본문 바로가기
Computer Vision

OpenCV 주요 기능 - 1. 카메라와 동영상 파일 다루기(2)

by ksb0511 2020. 2. 13.

2. 카메라 입력 처리하기

// 카메라 장치 열기
VideoCapture cap;		// VideoCapture 기본 생성자를 이용하여 변수 선언
cap.open(0);			// 컴퓨터에 연결되어 있는 기본 카메라 사용하기 위해 open() 함수 인자에 0을 지정

VideoCapture(0);		// 위의 두 줄 코드를 한 줄로 줄일 수 있음.

 

  • 카메라 장치가 열리도록 한 뒤, 정상적으로 열렸는지 isOpened() 멤버 함수를 이용하여 확인하는 것이 좋음.
    • isOpened() 멤버 함수가 false를 반환하면 카메라 장치를 사용할 수 없는 상태일 경우 예외 처리 코드 추가 필요
    • 예외 처리 코드 추가시...
if (!cap.isOpened()) {
	cerr << "failed" << endl;
        return -1;
}

 

  •  카메라 장치를 사용할 수 있는 상태가 되었을 경우 카메라 장치로부터 프레임을 받아옴. 이것을 Mat 클래스 객체에 저장 가능.
  • Mat 객체에 저장된 영상은 imshow() 함수를 사용하여 화면에 출력 가능.
  • 카메라로부터 일정 시간 간격마다 프레임을 받아와 화면에 출력하는 예제 코드
Mat frame;
while (true) {					// 무한반복
	cap >> frame;				// Mat 클래스 객체인 frame 변수에 하나의 프레임 저장.
    
    if ( frame.empty())		// 카메라로부터 받아 온 프레임 영상이 비어있을 시 반복문 빠져 나감.
    	break;
    
    imshow("frame", frame);		// Mat 객체에 저장된 영상 화면에 출력
    
    // waitKey(10) : 10ms 까지 기다린 뒤 다음 프레임을 받아 옴.
    // if waitKey(0)이라면 사용자의 키 입력을 무한히 기다리게 됨. 그러므로 0보다 큰 정수를 입력해야 함.
    if ( waitKey(10) == 27 )			// ESC key
    	break;
}

camera_in() 함수가 정의된 소스 파일

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;		// 현재 프레임을 반전하여 inversed 변수에 저장.

		// frame 과 inversed에 저장된 정지 영상을 화면에 출력
		imshow("frame", frame);
		imshow("inversed", inversed);

		if (waitKey(10) == 27) // ESC key
			break;
	}

	destroyAllWindows();		// 모든 창을 닫음.
}

 


3. 동영상 파일 처리하기

  • FPS (초당 프레임 수)

 double fps = cap.get ( CAP_PROP_FPS ) ; 

  • 매 프레임 사이의 시간 간격

 int delay = cvRound ( 1000 / fps ) ;

video_in() 함수가 정의된 소스 파일

void video_in()
{
	VideoCapture cap("stopwatch.avi");		// stopwatch.avi 파일을 불러와 cap 객체 생성

	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;

	// 비디오 파일의 fps 값을 받아와 출력
	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(delay) == 27) // ESC key
			break;
	}

	destroyAllWindows();
}

 


4. 동영상 파일 저장하기

// VideoWriter 객체 생성 후 동영상 파일을 쓰기 모드로 열기
VideoWriter::VideoWriter(const String& filename, int fourcc, double fps, Size frameSize, bool isColor = true);
bool VideoWriter::open(const String& filename, int fourcc, double fps, Size frameSize, bool isColor = true);

 

  • filename : 저장할 동영상 파일 이름
  • fourcc : 동영상 압축 코덱을 표현하는 4-문자 코드 ( 동영상파일의 코덱, 압축 방식, 색상 혹은 픽셀 포맷 등을 정의하는 정수 값 )
  • fps : 저장할 동영상의 초당 프레임 수
  • frameSize : 동영상 프레임의 가로 및 세로 크기
  • isColor : 이 값이 true면 컬러 동영상으로 저장, 아니면 그레이스케일 동영상으로 저장.
  • 열기 성공시 true가 반환, 실패 시 false가 반환됨.

// fourcc에 해당하는 정수값 생성
static int VideoWriter::fourcc(char c1, char c2, char c3, char c4);

 

  • 코덱을 표현하는 1byte 문자 네 개를 입력하여 정수형 4-문자코드 값을 반환.
fourcc 코드 생성 방법 코덱 설명
VideoWriter::fourcc('D', 'I', 'V', 'X') DivX MPEG-4 코덱
VideoWriter::fourcc('X', 'V', 'I', 'D') XVID MPEG-4 코덱
VideoWriter::fourcc('F', 'M', 'P', '4') FFMPEG MPEG4 코덱
VideoWriter::fourcc('W', 'M', 'V', '2') Windows Media Video 8 코덱
VideoWriter::fourcc('M', 'J', 'P', 'G') 모션 JPEG 코덱
VideoWriter::fourcc('Y', 'V', '1', '2') YUV 4:2:0 Planner(비압축)
VideoWriter::fourcc('X', '2', '6', '4') H.264/AVC 코덱
VideoWriter::fourcc('A', 'V', 'C', '1') Advanced Video 코덱

// 열려 있는 동영상 파일에 새로운 프레임을 추가하기 위해서는 << 연산자 재정의 또는 VideoWriter::write() 함수를 사용.
VideoWriter& VideoWriter::operator << (const Mat& image);
void VideoWriter::write(InputArray image);

 

  • 프레임을 추가할 시, 새로 추가하는 이미지 프레임 크기는 동영상 파일 생성 때 지정했던 크기와 같아야 함.
  • 컬러 동영상 파일에 그레이스케일 영상 추가하면 정상적으로 저장 x, 주의 필요!

// 파일을 닫는 함수
virtual void VideoWriter::release();

 

  • 프레임 저장이 완료되었으면 열려 있던 파일을 닫아야 함.
  • VideoWriter 클래스의 소멸자에서 release() 함수를 호출하기 때문에 VideoWriter 객체가 소멸되면 자동으로 파일이 닫힘.

댓글