상세 컨텐츠

본문 제목

#OpenCV 4로 배우는 컴퓨터 비전과 머신 러닝 - 5

Programing/OpenCV

by CouqueD'asse 2022. 5. 25. 16:25

본문

4장 OpenCV 주요 기능

 

4.1 카메라와 동영상 파일 다루기

 

4.1.1 VideoCapture 클래스

카메라 또는 동영상 파일로부터 정지 영상 프레임을 받아올 수 있는 클래스

동영상 : 일련의 정지 영상(프레임 frame)을 압축하여 파일로 저장한 형태

동영상을 처리하는 작업은 동영상에서 프레임을 추출한 후, 각각의 프레임에 영상 처리 기법을 적용하는 형태

 

4.1.2 카메라 입력 처리하기

void camera_in()
{
	VideoCapture cap(0);

	if (!cap.isOpened())
	{
		cerr << "Camera open failed!" << endl;
		return;
	}

	cout << "Frame Width : " << cvRound(cap.get(CAP_PROP_FRAME_WIDTH)) << endl;
	cout << "Frame Height : " << cvRound(cap.get(CAP_PROP_FRAME_HEIGHT)) << endl;

	Mat frame, inversed;
	while (true)
	{
		cap >> frame;
		if (frame.empty())
			break;
		inversed = ~frame;

		imshow("frame", frame);
		imshow("inversed", inversed);

		if (waitKey(10) == 27)
			break;
	}

	destroyAllWindows();
}

 

4.1.3 동영상 파일 처리하기

void video_in()
{
	VideoCapture cap("dog.avi");
	
	if (!cap.isOpened())
	{
		cerr << "Video open failed!" << endl;
		return;
	}

	cout << "Frame Width : " << cvRound(cap.get(CAP_PROP_FRAME_WIDTH)) << endl;
	cout << "Frame Height : " << cvRound(cap.get(CAP_PROP_FRAME_HEIGHT)) << endl;
	cout << "Frame Count : " << cvRound(cap.get(CAP_PROP_FRAME_COUNT)) << endl;

	double fps = cap.get(CAP_PROP_FPS);
	cout << "FPS : " << fps << endl;

	int delay = cvRound(1000 / fps);

	Mat frame, inversed;
	while (true)
	{
		cap >> frame;
		if (frame.empty())
			break;
		inversed = ~frame;

		imshow("frame", frame);
		imshow("inversed", inversed);

		if (waitKey(10) == 27)
			break;
	}

	destroyAllWindows();
}

 

4.1.4 동영상 파일 저장하기

void camera_in_video_out()
{
	VideoCapture cap(0);
	if (!cap.isOpened())
	{
		cerr << "Camera open failed!" << endl;
		return;
	}

	int w = cvRound(cap.get(CAP_PROP_FRAME_WIDTH));
	int h = cvRound(cap.get(CAP_PROP_FRAME_HEIGHT));
	double fps = cap.get(CAP_PROP_FPS);

	int fourcc = VideoWriter::fourcc('D', 'I', 'V', 'X');
	int delay = cvRound(1000 / fps);

	VideoWriter outputVideo("output.avi", fourcc, fps, Size(w, h));

	if (!outputVideo.isOpened())
	{
		cerr << "File open failed!" << endl;
		return;
	}

	Mat frame, inversed;
	while (true)
	{
		cap >> frame;
		if (frame.empty())
			break;
		inversed = ~frame;
		outputVideo << inversed;

		imshow("frame", frame);
		imshow("inversed", inversed);

		if (waitKey(delay) == 27)
			break;
	}

	destroyAllWindows();
}

 

4.2 다양한 그리기 함수

 

4.2.1 직선 그리기

// 직선
void line(InputOutputArray img, Point pt1, Pint pt2, const Scalar& color, 
		int thickness = 1, int lineType = LINE_8, int shift = 0);
// 화살표 직선
void arrowedLine(InputOutputArray img, Point pt1, Point pt2, const Scalar& color,
		int thickness = 1, int line_type = 8, int shift = 0, double tipLength = 0.1);
// tipLength : 전체 직선 길이에 대한 화살표 길이 비율
void drawMarker(InputOutputArray img, Point position, const Scalar& color, 
		int markerType = MARKER_CROSS, int markerSize = 20, int thickness = 1, int line_type = 8);

 

4.2.2 도형 그리기

// 사각형
void ractangle(InputOutputArray img, Point p1, Point p2, const Scalar& color,
		int thickness = 1, int lineType = LINE_8, int shift = 0);
void ractangle(InputOutputArray img, Rect rec, const Scalar& color,
		int thickness = 1, int lineType = LINE_8, int shift = 0);
// 원
void circle(InputOutputArray img, Point centerm int radius, const Scalar& color,
		int thickness = 1, int lineType = LINE_8, int shift = 0);
// 타원형 원
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);
// 다각형
void polylines(InputOutputArray img, InputArrayOfArrays pts, bool isClosed, const Scalar& color,
		int thickness = 1, int lineType = LINE_8, int shift = 0);

 

4.2.3 문자열 출력하기

void putText(InputOutputArray img, const String& text, Point org, int fontFace, Scalar color,
		int thickness = 1, int lineType = LINE_8, bool bottomLeftOrigin = false);
// bottomLeftOrigin : true이면 영상의 좌측 하단이 원점, false이면 좌측 상단이 원점
Size getTextSize(const String& text, int fontFace, double dontScale, int thickness, int* baseLine);
// 문자열을 출력할 때 차지할 사각형 영역 크기 정보를 반환
// 이 정보를 이용하여 출력 위치를 적절하게 조절가능
// 영상 중앙에 문자열 출력하기
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;

	Size sizeText = getTextSize(text, fontFace, fontScale, thickness, 0);
	Size sizeImg = img.size();

	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();

	destroyAllWindows();
}

관련글 더보기