본문 바로가기
AI_Student/Video Processing&Computer Vision

[OpenCV,C++] 이미지 영상 처리 코드 분석(In/Out)

by AndrewL 2020. 9. 5.

OpenCV를 이용해서 간단한 이미지, 영상의 In/Out 처리를 해보며 사용되는 코드 분석을 해보겠습니다.(Image Processing/Video Processing)

 

먼저, 개념들에 대해서 간단하게 설명한 후 시작하도록 하겠습니다.


OpenCV(Open Source Computer Vision Library)

-Intel사에서 1999년에 처음 발표된 영상처리 및 컴퓨터 비전 라이브러리이며, 현재는 OpenCV Foundation에서 프로젝트 관리가 이루어지고 있습니다

-현재까지는 4.4.0버전까지 배포되었습니다.

-영상의 파일 및 화면 입출력, 다양한 변환과정, 공간 변환, 영상 분할, 히스토그램 분석 및 처리 등 다양한 기능을 가지고 있습니다.

 

(이 글에서는 OpenCV-3.1.0으로 학습을 진행해보겠습니다.)

설치과정은 아래 링크를 참고하시기 바랍니다.

https://docs.opencv.org/3.1.0/d5/de5/tutorial_py_setup_in_windows.html

 

OpenCV: Install OpenCV-Python in Windows

Goals In this tutorial We will learn to setup OpenCV-Python in your Windows system. Below steps are tested in a Windows 7-64 bit machine with Visual Studio 2010 and Visual Studio 2012. The screenshots shows VS2012. Installing OpenCV from prebuilt binaries

docs.opencv.org

윈도우일 경우, 시스템 환경변수를 추가해야하고, visual studio에서 라이브러리를 찾을 수 있도록 몇가지 수정해야 한다는 점 유의하시기 바랍니다. 

 


설치가 완료되었다면, 예제를 통해 통해 살펴본 후, 코드 분석을 통해 자세한 설명을 진행하겠습니다.

#include <opencv2/opencv.hpp>

using namespace cv;

void main()
{
//Mat객체 변수인 Image에 lena.jpg파일을 읽어서 저장.
	Mat Image = imread("lena.jpg", IMREAD_COLOR);
    
//간단한 위도우 이름설정하고 사이즈는 자동할당으로 지정.
	namedWindow("display", WINDOW_AUTOSIZE);
//윈도우 이름과 윈도우에 보여주고자하는 변수명을 imshow를 통해 입력.
	imshow("display", Image);
//저장하고자 하는 이미지 파일이음.파일확장자와 저장하고싶은 이미지
	imwrite("lena_new.jpg", Image);

		waitKey(0);
}

-> 간단히 프로젝트 폴더에 있는 이미지를 읽어와서 새로운 파일명으로 저장해보는 예제입니다.

-> 여기서 Mat 클래스는 여러 채널의 실수나 행렬, 영상 등의 수치 데이터를 표현하는 N차원 행렬 클래스입니다.

간단히 말하자면 "비정형 데이터에서 수치를 표현해주는 행렬바구니"로 이해하면 될 것 같습니다.

 

또한 Data Type& Channel Pattern을 살펴보면 

CV_8UC1 : 8 비트 픽셀/부호가 없는 정수/1채널

CV_16SC3 : 16 비트 픽셀/부호가 있는 정수/3채널

CV_32FC4 : 32 비트 픽셀/부동 소수점 방식/4채널

이와 같은 표현합니다. (U: unsigned, S: signed, F: float이고 앞의 숫자는 비트, 뒤의 숫자는 채널을 의미합니다.)

 

추가적으로 헤더파일 다음에 namespace cv를 사용했는데, cv::의 주요 메소드는

-imread, imwrite, imshow, waitkey등이 있습니다.(waitkey(0)은 키보드 입력이 들어올 때 까지 무한 대기한다는 의미입니다)

 


다음은 영상 처리 예제를 살펴보겠습니다.

#include <opencv2/opencv.hpp>

using namespace cv;

void main()
{
	VideoCapture capture("video.mp4");

	Mat Frame; //Frame변수에 프레임을 저장할 것이다.
	if (!capture.isOpened()) // 비디오캡쳐가 되지 않았을 때(불러오지 못했을 때)
	{
		printf("Video file can not open \n");
		return;
	}

	namedWindow("video");

	while (1) {
		capture >> Frame;//캡처한 비디오 프레임을 Mat변수 Frame에 저장.

		if (Frame.empty())//프레임이 끝났을 때 즉, 일 다했으면 나가라.
			break;

		imshow("video", Frame); //출력 창에 캡쳐된 프레임을 출력해라
		if (waitKey(10) > 0)
			break;
	}
}

-> 간단한 영상을 읽어와서 프레임단위로 출력해보는 예제입니다.

전에 진행했던 Image클래스에서는 Mat클래스를 사용하여 불러오고 저장하였지만 영상을 가져올 때는 먼저! VideoCapture클래스로 가져오고 >>연산자로 Mat객체에 넘겨주는 과정이 보이 실겁니다.

 

+영상 처리 활용

그러면 실제 영상을 만들어서 프레임 단위로 읽어 프레임을 제일 끝부분 부터 출력해보겠습니다(영상 역순 출력)

#include <opencv2\opencv.hpp>
#include <vector>
#include <iostream>

using namespace cv;
using namespace std;

void main()
{
	VideoCapture capture("Test321count.mp4");

	Mat frame;

	if (!capture.isOpened())
	{
		printf("video file cannot open\n");
		return;
	}

	VideoWriter writer;

	vector<Mat> video;

	writer.open("Reverse321count.avi", CV_FOURCC('D', 'I', 'V', 'X'), 30, Size(1920, 1080), true);

	while (1)
	{
		Mat frame;
		capture >> frame;
		if (frame.empty())
			break;

		video.push_back(frame);
	}
	for (int i = 0;i < video.size();i++)
		writer.write(video[video.size() - (i + 1)]);
}

-> 'Test321count'라는 을 videocapture클래스로 가져와서 역순으로 출력할 것이기 때문에 플레임 순서를 가리키고 작업을 진행해야 하므로 Vector를 사용하였습니다. 

-또한 비디오를 작성하기 위한 클래스인 VideoWriter를 써서 writer.open으로 어떤 유형의 파일을 만들것인지 설정해준 다음 video벡터에 Push_back(프레임)으로 프레임 하나씩 넣어준다음, video끝부분 부터 iterating하여 writer.write로 적어주었습니다.

 

쉽게 말하면, 프레임을 담기 위해서는 Mat라는 바구니가 필요하고 그 바구니의 처음과 끝을 가리키기 위해 vector<Mat>를 선언했고, whlie반복문을 사용하여 하나씩 push_back을 하였습니다.

 

//CV_FOURCC부분은 프레임을 압축하는데 사용되는 4자리의 코덱이며

코덱목록은 아래 링크를 참고하시기 바랍니다.

http://www.fourcc.org/codecs.php

 

Video Codecs by FOURCC - fourcc.org

 

www.fourcc.org

 

 

댓글