동영상과 WebCAM 재생 및 녹화 - OpenCV(C++)

Updated:

OpenCV를 이용해 동영상를 읽은 후 재생 및 녹화 + WebCAM 연결 및 녹화해서 저장하기

Visual Studio 2017을 사용하였습니다.

#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>

using namespace std;
using namespace cv;

int main()
{
	int num;

	cout << "사용할 옵션(번호)을 선택하시오.\n" << "1. Webcam으로 입력/imshow/출력/녹화 버튼\n" << "2. video file 입력/imshow/출력/녹화 버튼\n";
	cin >> num;

	if (num == 1)// webcam으로 입력/imshow/출력/녹화 버튼
	{
		Mat frame;

		VideoCapture cap(1); // camera 연결
		if (!cap.isOpened())
		{
			cerr << "카메라 열 수 없음." << endl;
			return -1;
		}

		double fps = 30.0;

		int width = cap.get(CAP_PROP_FRAME_WIDTH); // 웹캠의 width 받기
		int height = cap.get(CAP_PROP_FRAME_HEIGHT); // 웹캠의 height 받기
		int fourcc = VideoWriter::fourcc('X', 'V', 'I', 'D'); // 동영상 사용시 저장할 코덱을 지정
		cout << fps << " " << width << " " << height << " " << fourcc << endl;
		VideoWriter outputVideo; // Videowirter  객체 생성
		outputVideo.open("output.avi", fourcc, fps, Size(width, height), true);


		cout << "Webcam을 선택하였습니다. R 또는 r 버튼을 누르시면 녹화가 진행됩니다. (녹화 및 프로그램 종료 : esc key)\n";

		while (true) // 종료 시까지 영상 출력
		{
			cap.read(frame); // video 캡쳐 객체 받는 것(비디오의 한 프레임씩 읽음)
			if (frame.empty())
			{
				cerr << "캡쳐 실패." << endl;
				break;
			}
			cout << outputVideo.isOpened() << "\n";
			imshow("Live", frame);
			int wait = int(1.0 / fps * 1000); // 이미지를 가져오는 사이 대기시간을 계산(즉 delay를 계산할 수 있음)

			int key = waitKey(1);
			if (key == 27) // esc key 누르면 종료
				break;
			else if ((key == 82) || (key == 114)) // 녹화 버튼을 눌렀을 때
			{
				cout << "녹화가 시작됩니다.\n\n";

				while (true)
				{
					cout << outputVideo.isOpened() << "\n";
					cap.read(frame);
					if (frame.empty())
					{
						cerr << "캡쳐 실패." << endl;
						break;
					}

					imshow("Live", frame);

					outputVideo.write(frame);// 이미지를 계속 저장되기 때문에 동영상으로 저장되게 하는 것

					if (waitKey(1) == 27) // esc key 누르면 종료
						break;
				}
				outputVideo.release();
				break;
			}

		}
	}

	else if (num == 2)// video file로 입력/imshow/출력/녹화 버튼
	{
		Mat frame;

		VideoCapture cap("Sea.avi");

		double fps = cap.get(CAP_PROP_FPS);

		int width = cap.get(CAP_PROP_FRAME_WIDTH); // 웹캠의 width 받기
		int height = cap.get(CAP_PROP_FRAME_HEIGHT); // 웹캠의 height 받기
		int fourcc = VideoWriter::fourcc('X', 'V', 'I', 'D'); // 동영상 사용시 저장할 코덱을 지정

		VideoWriter outputVideo; // Videowirter  객체 생성
		outputVideo.open("sea_cap.avi", fourcc, fps, Size(width, height), true);

		if (!cap.isOpened())
		{
			cerr << "파일을 열 수 없습니다." << endl;
			return -1;
		}
		cout << "Video file을 선택하였습니다. Esc 버튼을 누르시면 동영상이 종료됩니다.\n";

		bool is_record = false;
		while (cap.isOpened())
		{
			cap.read(frame);
			if (frame.empty())
			{
				cerr << "\n\n파일 읽기 실패 or 동영상 재생 완료" << endl;
				return -1;
			}

			imshow("sea", frame);
			int key = cv::waitKey(10);
			//int wait = int(1.0 / fps * 1000);
			if (key == 27) // esc key 누르면 종료로 설정
				// cout << "\n프로그램을 종료합니다!" << endl; <- 이 줄이 있으면 동영상 재생이 되지않고 바로 종료되는 에러 발생
				break;
			else if ((key == 82) || (key == 114)) // 녹화 버튼을 눌렀을 때
			{
				cout << "녹화가 시작됩니다.\n\n";
				is_record = !is_record;
			}

			if (is_record)
			{

				if (!outputVideo.isOpened())
				{

					cerr << "동영상 저장을 위한 초기화중 에러 발생." << endl;
					return -1;
				}
				else
				{
					outputVideo.write(frame);// 이미지를 계속 저장되기 때문에 동영상으로 저장되게 하는 것
				}
			}
		}
		outputVideo.release();
	}
	else
	{
		cout << "제대로 읽고 다시 입력하세요. 프로그램이 종료됩니다.\n";
		return -1;
	}

	return 0;
}

Leave a comment