본문 바로가기
머신비전/OpenCV

[OpenCV] 도형 그리기 그림판

by 기딩 2024. 1. 11.
728x90

개발 툴 : Visual Studio 2019

언어 : C++

진행 기간 : 1일

 

 

설명

 

1. 두 점을 찍고 키보드 'c' -> 원

2. 두 점을 찍고 키보드 'r' -> 직사각형

3. 여러 점을 찍고 키보드 'p' -> 다각형

4. 키보드 'ctrl' + 마우스 좌클릭 -> 지우개

5. 키보드 'q' -> 모두 지우기

6. 키보드 ESC -> 종료

 

 

추가설명

- 1, 2번에서 여러 점을 찍더라도 마지막 두 점만 고려

- 직사각형을 위해 찍는 두 점은 top-left, 가로, 세로 길이만 반영

 

 

 

 

소스코드

#include "opencv2/opencv.hpp"
#include <iostream>
#include <math.h>

using namespace cv;
using namespace std;

Mat img(1500, 1500, CV_8UC3, Scalar(255, 255, 255));
Point ptOld;
void on_mouse(int event, int x, int y, int flags, void*);
vector<Point> pts;
bool eraseFlag = false;

//기능 구현 사항

// 두 점 c 원
// 두 점 r 직사각형
// 3~ 여러 점 p 다각형
// e 지우개
// r 전체 지우개

int main() {

	namedWindow("img");
	setMouseCallback("img", on_mouse);
	imshow("img", img);

	while (true) {

		int keycode = waitKey();
		int cnt = pts.size();

		if (cnt >= 2 && (keycode == 'c' || keycode == 'C')) {

			double x_d = pts[cnt - 2].x - pts[cnt - 1].x;
			double y_d = pts[cnt - 2].y - pts[cnt - 1].y;
			double r = sqrt(pow(x_d, 2) + pow(y_d, 2));

			circle(img, pts[cnt - 2], r, Scalar(255, 0, 0), 3, LINE_AA);
			pts.clear();
		}
		else if (cnt >= 2 && (keycode == 'r' || keycode == 'R')) {
			
			int width = abs(pts[cnt - 2].x - pts[cnt - 1].x);
			int height = abs(pts[cnt - 2].y - pts[cnt - 1].y);
			
			rectangle(img, Rect( pts[cnt-2].x , pts[cnt-2].y, width, height), Scalar(0, 255, 0), 2);
			pts.clear();
		}
		else if (cnt >= 3 && (keycode == 'p' || keycode == 'P')) {
			fillPoly(img, pts, Scalar(255, 204, 153));
			pts.clear();
		}
		else if (keycode == 'q' || keycode == 'Q') {
			img = Scalar(255, 255, 255);
			pts.clear();
		}

		imshow("img", img);

		if (keycode == 27) {
			destroyAllWindows();
			break;
		}
			
	}

	return 0;
}

void erase(Point pt) {
	
		double r = 10;
		circle(img, pt, r, Scalar(255, 255, 255), -1, LINE_AA);
}

void on_mouse(int event, int x, int y, int flags, void*) {

	switch (event) {

	case EVENT_LBUTTONDOWN :
		ptOld = Point(x, y);
		pts.push_back(ptOld);
		cout << "좌클릭 좌표 : " << x << ", " << y << endl;
		break;

	case EVENT_MOUSEMOVE:
		if (flags == EVENT_FLAG_CTRLKEY ) {
			erase(Point(x, y));
			imshow("img", img);
		}
		break;

	default:
		break;
	}

}
728x90

'머신비전 > OpenCV' 카테고리의 다른 글

[OpenCV] 오픈 CV 공부  (0) 2024.02.15
[OpenCV] 카드 사진 투시변환  (0) 2024.01.11
[OpenCV] 웹 캠 차영상  (0) 2024.01.11