본문 바로가기
OpenCV

OpenCV , C++ ] 도형 그리기 + 문자열 출력

by eteo 2022. 8. 16.

 

1. 직선 그리기

 

void drawLines() {
	
	Mat im = imread("lenna.bmp", IMREAD_GRAYSCALE);
	Mat img;
	cvtColor(im, img, COLOR_GRAY2BGR);
	//흑백영상 위에 그리면 원래 도형도 흑백으로 그려짐. 위 코드는 흑백 영상위에 컬러 도형을 그리는 방법 중 하나

	//Mat img(400, 400, CV_8UC3, Scalar(255, 255, 255));

	//직선 그리기
	//void line(InputOutputArray img, Point pt1, Point pt2, const Scalar &color, int thickness = 1, int lineType = 8, int shift = 0)
	//입출력 영상 InputOutputArray라서 원본 위에 그려짐, 시작점과 끝점, 선 색상, 선 두께, 선 타입, 그리기 좌표값의 축소비율(>>연산)
	line(img, Point(50, 50), Point(200, 50), Scalar(0, 0, 255));
	line(img, Point(50, 100), Point(200, 100), Scalar(255, 0, 255), 3);
	line(img, Point(50, 150), Point(200, 150), Scalar(255, 0, 0), 10);

	//선 타입 : -1 내부를 채움(폐곡선만 가능), LINE_4 4방향연결, LINE_8 8방향 연결, LINE_AA Anti-aliasing
	//이미지나 텍스트의 가장자리 계단 현상을 없애고 부드럽게 해주는 기능
	line(img, Point(250, 50), Point(350, 100), Scalar(0, 0, 255), 1, LINE_4);
	line(img, Point(250, 70), Point(350, 120), Scalar(255, 0, 255), 1, LINE_8);
	line(img, Point(250, 90), Point(350, 140), Scalar(255, 0, 0), 1, LINE_AA);

	//화살표 그리기. 마지막 매개변수 tipLength = 0.1 은 전체 직선 길이에 대한 화살표 길이의 비율
	arrowedLine(img, Point(50, 200), Point(150, 200), Scalar(0, 0, 255), 1);
	arrowedLine(img, Point(50, 250), Point(350, 250), Scalar(255, 0, 255), 1);
	arrowedLine(img, Point(50, 300), Point(350, 300), Scalar(255, 0, 0), 1, LINE_8, 0, 0.05);

	imshow("img", img);
	waitKey();

	//다양한 모양의 마커 그리기. 2번째 매개변수가 마커 출력 위치, 4번째 매개변수가 마커 종류
	drawMarker(img, Point(50, 350), Scalar(0, 0, 255), MARKER_CROSS);
	drawMarker(img, Point(100, 350), Scalar(0, 0, 255), MARKER_TILTED_CROSS);
	drawMarker(img, Point(150, 350), Scalar(0, 0, 255), MARKER_STAR);
	drawMarker(img, Point(200, 350), Scalar(0, 0, 255), MARKER_DIAMOND);
	drawMarker(img, Point(250, 350), Scalar(0, 0, 255), MARKER_SQUARE);
	drawMarker(img, Point(300, 350), Scalar(0, 0, 255), MARKER_TRIANGLE_UP);
	drawMarker(img, Point(350, 350), Scalar(0, 0, 255), MARKER_TRIANGLE_DOWN);

	imshow("img", img);

	waitKey();

	destroyAllWindows();

}

 

 

 

 

 

 

 

 

 

 

 

 

2. 도형 그리기

 

void drawPolys() {

	Mat img(400, 400, CV_8UC3, Scalar(255, 255, 255));

	//사각형 그리기. 2가지 형식이 있음
	//void rectangle(InputOutputArray img, Rect rec, Scalar &color, int thickness = 1, int lineType = 8, int shift = 0)
	//void rectangle(InputOutputArray img, Point pt1, Point pt2, Scalar &color, int thickness = 1, int lineType = 8, int shift = 0)
	//사각형의 위치정보를 나타내는 Rect 객체 또는 서로 대각 방향에 있는 사각형 꼭지점 좌표인 Point 객체 2개
	rectangle(img, Rect(50, 50, 100, 50), Scalar(0, 0, 255), 2);
	rectangle(img, Rect(50, 150, 100, 50), Scalar(0, 0, 128), -1);

	//원 그리기
	//void circle(InputOutputArray img, Point center, int radius, const Scalar& color, int thickness = 1, int lineType = LINE_8, int shift = 0)
	//center : 원의 중심 Point, radius : 원의 반지름
	circle(img, Point(300, 120), 30, Scalar(255, 255, 0), -1, LINE_AA);
	circle(img, Point(300, 120), 60, Scalar(255, 0, 0), 3, LINE_AA);

	//타원그리기
	//void ellipse(InputOutputArray img, Point center, Size axes, double angle, double startAngle, double endAngle,	const Scalar& color, int thickness = 1,	int lineType = LINE_8, int shift = 0);
	//center : 타원의 중심, axes : 타원의 반지름 Size(x축 반지름, z축 반지름), angle : 타원의 회전 각도
	//starAngle : 타원 호의 시작 각도, endAngle 타원 호의 끝 각도. angle은 전부 x축 기준, CW방향
	ellipse(img, Point(120, 300), Size(60, 30), 20, 0, 270, Scalar(255, 255, 0), -1, LINE_AA);
	ellipse(img, Point(120, 300), Size(100, 50), 20, 0, 360, Scalar(0, 255, 0), 2, LINE_AA);

	//임의의 다각형 그리기. 보통 다각형의 꼭지점 좌표를 vector<Point> 자료형에 저장하여 그리기 함수에 전달함
	vector<Point> pts;
	pts.push_back(Point(250, 250));
	pts.push_back(Point(300, 250));
	pts.push_back(Point(300, 300));
	pts.push_back(Point(350, 300));
	pts.push_back(Point(350, 350));
	pts.push_back(Point(250, 350));

	//void polylines(InputOutputArray img, InputArrayOfArrays pts, bool isClosed, const Scalar& color, int thickness = 1, int lineType = LINE_8, int shift = 0 );
	//InputArrayOfArrays pts : 다각형 외곽 점들의 좌표 배열 또는 벡터, isClose : 다각형이 닫혀있는지 나타내는 플래그로 true면 마지막 꼭지점과 첫 꼭지점을 이음
	polylines(img, pts, true, Scalar(255, 0, 255), 2);
	
	//내부가 채워진 임의의 다각형 그리기
	fillPoly(img, pts, Scalar(0, 255, 255));


	imshow("img", img);
	waitKey(0);
	destroyAllWindows();

}

 

 

 

 

 

 

 

 

 

 

 

3. 문자열 출력

 

void drawText1() {

	Mat img(500, 800, CV_8UC3, Scalar(255, 255, 255));
	
	//void putText(InputOutputArray img, const String & text, Point org, int fontFace, double fontScale, Scalar color, int thickness = 1, int lineType = LINE_8, bool bottomLeftOrigin = false);
	//text : 출력할 문자열, org : 문자열을 출력할 위치의 좌측 하단 좌표, fontFace : 폰트 종류, fontScale : 폰트 크기 확대/축소 비율
	//마지막 매개변수 bottomLeftOrigin : 디폴트는 false고 이 값이 true면 영상의 좌측 하단을 원점으로 간주. false일 땐 당연히 좌측 상단이 원점
	putText(img, "FONT_HERSHEY_SIMPLEX", Point(20, 50), FONT_HERSHEY_SIMPLEX, 1, Scalar(0, 0, 255));
	putText(img, "FONT_HERSHEY_PLAIN", Point(20, 100), FONT_HERSHEY_PLAIN, 1, Scalar(0, 0, 255));
	putText(img, "FONT_HERSHEY_DUPLEX", Point(20, 150), FONT_HERSHEY_DUPLEX, 1, Scalar(0, 0, 255));
	putText(img, "FONT_HERSHEY_COMPLEX", Point(20, 200), FONT_HERSHEY_COMPLEX, 1, Scalar(255, 0, 0));
	putText(img, "FONT_HERSHEY_TRIPLEX", Point(20, 250), FONT_HERSHEY_TRIPLEX, 1, Scalar(255, 0, 0));
	putText(img, "FONT_HERSHEY_COMPLEX_SMALL", Point(20, 300), FONT_HERSHEY_COMPLEX_SMALL, 1, Scalar(255, 0, 0));
	putText(img, "FONT_HERSHEY_SCRIPT_SIMPLEX", Point(20, 350), FONT_HERSHEY_SCRIPT_SIMPLEX, 1, Scalar(255, 0, 255));
	putText(img, "FONT_HERSHEY_SCRIPT_COMPLEX", Point(20, 400), FONT_HERSHEY_SCRIPT_COMPLEX, 1, Scalar(255, 0, 255));
	putText(img, "FONT_HERSHEY_COMPLEX | FONT_ITALIC", Point(20, 450), FONT_HERSHEY_COMPLEX | FONT_ITALIC, 1, Scalar(255, 0, 0));

	imshow("img", img);
	waitKey(0);

}

 

 

 

 

 

 

 

 

 

4. 문자열을 영상의 특정위치에 출력

640×200 크기의 흰색 영상 정중앙에Hello, OpenCV문자열을 출력하기

 

void drawText2() {

	Mat img(200, 640, CV_8UC3, Scalar(255, 255, 255));

	const String text = "Hello, OpenCV";
	int fontFace = FONT_HERSHEY_TRIPLEX;
	double fontScale = 2.0;
	int thickness = 1;

	//getTextSize()함수는 문자열 출력을 위해 필요한 사각형 영역 크기를 가늠할 수 있는 함수
	//Size getTextSize(const String& text, int fontFace, double fontScale, int thickness, CV_OUT int* baseLine);
	//리턴값은 Size 타입으로 지정한 문자열 출력시 차지하는 사각형 크기.
	//마지막 매개변수 baseLine : 가장 하단의 텍스트 위치를 기준으로 하는 기준선의 y좌표로 필요 없으면 0지정
	Size sizeText = getTextSize(text, fontFace, fontScale, thickness, 0);
	Size sizeImg = img.size();

	// 영상의 가로/세로크기를 확인하고, 출력할 문자열이 차지할 영역의 크기를 getTextSize()함수를 통해 확인해서
	// 아래와 같이 문자열이 영상 정중앙에 출력될 수 있도록 하는 사각 영역의 좌측 하단 좌표를 알아냄
	Point org((sizeImg.width - sizeText.width) / 2, (sizeImg.height + sizeText.height) / 2);

	// 화면 정중앙에 문자열 출력
	putText(img, text, org, fontFace, fontScale, Scalar(255, 0, 0), thickness);

	// 문자열을 감싸는 사각형 출력
	rectangle(img, org, org + Point(sizeText.width, -sizeText.height), Scalar(255, 0, 0), 1);
	

	imshow("img", img);
	waitKey(0);
}