본문 바로가기
런닝머신 (ML)

[컴퓨터 비전 & 머신러닝] 카메라와 동영상 파일 다루기

728x90

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

 

VideoCapture(const String& filename, int apiPreference = CAP_ANY);
open(const String& filename, int apiPreference = CAP_ANY);
//filename -> 동영상 파일 이름
//파일 이름 종류 : .avi, .mpg, .mp4
//apiPreference -> 사용할 비디오 캡쳐 API 백엔드

동영상 파일 말고로 다른 정지 영상 파일과 비디오 스트림 URL도 VideoCapture 클래스를 통해 불러올 수 있다

 

CAP_ANY 자동 선택
CAP_V4L, CAP_V4L2 V4L/V4L2 (리눅스)
CAP_FIREWIRE, CAP_FIREWARE, CAP_IEEE1394  IEEE 1394 드라이버
CAP_DSHOW 다이렉트쇼
CAP_PVAPI PvAPI, Proslilca GigE SDK
CAP_OPENNI OpenNI
CAP_MSMF 마이크로소프트 미디어 파운데이션
CAP_GSTREAMER Gstreamer
CAP_FFMPEG FFMPEG 라이브러리
CAP_IMAGES OpenCV에서 지원하는 일련의 영상 파일
CAP_OPENCV_MJPEG OpenCV에 내장된 MotionJPEG 코덱

 

VideoCapture(int index, int apiPreference = CAP_ANY);
open(int index, int apiPreference = CAP_ANY);
//index -> 카메라와 장치 사용 방식 지정 번호

index = camera_id + domain_offset_id

camera_id -> 컴퓨터에 연결되어 있는 카메라, 한대의 카메라 연결되어 있으면 0, 두대 이상이면 0보다 같거나 큰 정수

domain_offset_id -> 카메라 장치를 사용하는 방식을 표현하는 정수 값, 자동선택은 0이기에 대부분 index 값은 camera_id와 같은 값이 된다

 

isOpened() 함수 : 열기 작업이 성공적으로 수행되었는지 확인하는 함수

isOpened() const;

 

release() 함수 : 카메라 장치 또는 동영상 파일의 사용이 끝나면 사용하는 함수, 소멸자

release();

 

카메라 또는 동영상 파일로부터 한 프레임의 정지 영상을 받아오는 함수

VideoCapture::operator >> (Mat& image);
VideoCapture::read(OutputArray image);
//image -> 다음 비디오 프레임
VidioCapture cap(0);

Mat frame1, frame2;
cap >> frame1; //VideoCapture::operator >>() 함수 사용
cap.read(frame2); //VideoCapture::read() 함수 사용

 

get() 함수 : 현재 열려 있는 카메라 장치 또는 동영상 파일로부터 여러가지 정보를 받아오는 함수

get(int propId) const;
//propId -> 속성 ID, vidioCaptureProperties 열거형 중 하나 지정
VidioCapture cap(0);

//카메라의 기본 프레임 크기 출력
cout << "Frame width: " << cvRound(cap.get(CAP_PROP_FRAME_WIDTH)) << endl;
cout << "Frame height: " << cvRound(cap.get(CAP_PROP_FRAME_HEIGHT)) << endl;

 

set() 함수 : 현재 열려 있는 카메라 또는 비디오 파일 재생과 관련한 속성 값을 설정하는 함수

set(int propId, double value);
//video.mp4 파일을 열어서 100번째 프레임으로 이동
VideoCapture cap("video.mp4");
cap.set(CAP_PROP_POS_FRAMES, 100);

카메라 입력 처리하기

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;
/*
Frame width: 640
Frame height: 480
*/

	Mat frame, inversed;
	while (true) {
		cap >> frame; //카메라 장치로 부터 프레임 받아와 저장
		if (frame.empty())
			break;

		inversed = ~frame; //반전된 프레임 저장

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

		if (waitKey(10) == 27) // ESC key 누르면 종료
			break;
	}

	destroyAllWindows();
}


동영상 파일 처리하기

void video_in()
{
//특정 파일을 불러와서 객체에 저장
	VideoCapture cap("stopwatch.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;

//초당 프레임 수(FPS)값을 출력
	double fps = cap.get(CAP_PROP_FPS);
	cout << "FPS: " << fps << endl;

//밀리초 간위 delay 계산
	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();
}


동영상 파일 저장하기

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

//DivX MPEG-4 코덱에 해당하는 forcecc 코드를 생성
	int fourcc = VideoWriter::fourcc('D', 'I', 'V', 'X');
	int delay = cvRound(1000 / fps);

//저장할 동영상 파일 생성, 이름은 output.avi
	VideoWriter outputVideo("output.avi", fourcc, fps, Size(w, h));

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

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

		inversed = ~frame; //반전된 프레임을 저장
		outputVideo << inversed; //반전된 카메라 프레임 영상 inversed를 출력 동영상에 추가

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

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

	destroyAllWindows();
}

 

728x90