카메라와 동영상처리

강형우·2022년 11월 29일
0

OpenCV

목록 보기
12/17

카메라와 동영상 처리하기

VideoCaputure 클래스

  • OpenCV에서는 카메라와 동영상으로부터 프레임(frame)을 받아오는 작업을 VideoCapture 클래스 하나로 처리함
  • 일단 카메라와 동영상을 여는 작업이 수행되면, 이후에는 매 프레임을 받아오는 공통의 작업을 수행
class VideoCapture
{
public:
	VideoCapture(); // 아무런 인자를 받지 않는 기본적인 생성자
    // 여러개의 인자를 받는 생성자
    VideoCapture(const String& filename, int apiPreference = CAP_ANY); // 문자열 받는 형태
    VideoCapture(int index, int apiPreference = CAP_ANY); // 정수값 받는 형태
    virtual ~VideoCapture(); // 소멸자
    
    virtual bool open(const String& filename, int apiPreference = CAP_ANY); // 문자열을 받는 형태
    virtual bool open(int index, int apiPreference = CAP_ANY); // 정수값을 받는 형태
    vitrual void release();
    
    // 문자열은 받는 형태의 함수들은 동영상 파일들을 오픈할때 사용하는 함수
    // 정수값을 받는 형태는 카메라 장치를 열때 사용하는 함수
    
    //프레임 받아오기
    virtual VideoCapture& operator >> (Mat& image);
    virtual bool VideoCapture::read(OutputArray image);
	// 속성 설정과 참조
	virtual bool set(int propId, double value);
    virtual double get(int propId) const;
	
}

카메라 열기

	VideoCapture::VideoCapture(int index, int apiPreference = CAP_ANY);
	bool VideoCapture::open(int index, int apiPreference = CAP_ANY);
  • index: 사용할 캡쳐 장치의 ID.(camera_id + domain_offset_id) 시스템 기본 카메라를 기본 방법으로 열려면 0을 지정.
    컴퓨터에 여러 대의 카메라가 연결됭 있으면, 0,1...순서로 지정
  • apiPreference: 선호하는 카메라 처리 방법을 지정.
    e.g) cv::CAP_DSHOW, cv::CAP_MSMF, cv::CAP_V4L, etc.
    2번째 인자는 디폴트로 CAP_ANY인데 이 경우 OpenCV library가 적정한 방법을 알아서 선택하기 때문에 2번째 인자는 기본적으로 주지 않는 형태로 코드 작성하는것이 좋다.
  • 반환값: VideoCapture 생성자는 VideoCapture 객체를 반환.
    VideoCapture::open() 함수는 작업이 성공하면 true를, 실패하면 false를 반환.

동영상 파일 열기

	VideoCapture::VideoCapture(const String& filename, int apiPreference = CAP_ANY);
	bool VideoCapture::open(const String& filename, int apiPreference = CAP_ANY);
  • filename: 동영상 파일 이름, 정지 영상 시퀀스, 비디오 스트림URL 등
  • apiPreference: 선호하는 동영상 처리 방법을 지정
  • 반환값: VideoCapture 생성자는 VideoCapture 객체를 반환.
    VideoCapture::open() 함수는 작업이 성공하면 true를, 실패하면 false를 반환.

현재 프레임 받아오기

	bool VideoCapture::read(OutputArray image);
    VideoCapture& VideoCapture::operator >> (Mat& image);
  • image: 현재 프레임. 만약 현재 프레임을 받아오지 못하면 비어있는 영상으로 설정됨.
  • 반환값: VideoCapture::read() 함수는 작업이 성공하면 true를, 실패하면 false를 반환.
  • 참고사항: >>연산자 오버로딩은 내부에서 read()하무를 재호출 하는 래퍼(wrapper)함수임.
	VideoCapture& VideoCapture::operator >> (Mat& image)
    {
    	read(image);
        return *this;
    }

카메라 프레임 처리하기

int main()
{
	// VideoCapture 객체 생성 후 0번 카메라 열기.
	VideoCapture cap;
	cap.open(0); // VideoCapture cap(0); 과 같음

	if (!cap.isOpened()) {
		cerr << "Camera open failed!" << endl;
		return -1;
	}
    
	Mat frame, edge;
	while (true) {
    	// VideoCapture 객체로부터 한 프레임을 받아 frame 변수에 저장
		cap >> frame;

		if (frame.empty()) {
			break;
		}
		// 받아온 프레임 처리 및 화면 출력
		Canny(frame, edge, 50, 150);
		imshow("frame", frame);
		imshow("edge", edge);
		
        // 일정 시간(10ms) 기다린 후 다음 프레임을 처리.
        // 만약 키 입력이 있으면 프로그램을 종료
		if (waitKey(10) == 0)
			break;
	}
}

동영상 프레임 처리하기

int main()
{
	// VideoCapture 객체 생성 후 test_video.mp4 파일 열기
	VideoCapture cap;
	cap.open("test_video.mp4"); // VideoCapture cap("test_video.mp4");와 같음

	if (!cap.isOpened()) {
		cerr << "Camera open failed!" << endl;
		return -1;
	}
    
	Mat frame, edge;
	while (true) {
    	// VideoCapture 객체로부터 한 프레임을 받아 frame 변수에 저장
		cap >> frame;

		if (frame.empty()) {
			break;
		}
		// 받아온 프레임 처리 및 화면 출력
		Canny(frame, edge, 50, 150);
		imshow("frame", frame);
		imshow("edge", edge);
		
        // 일정 시간(10ms) 기다린 후 다음 프레임을 처리.
        // 만약 키 입력이 있으면 프로그램을 종료
		if (waitKey(10) == 0)
			break;
	}
}

카메라와 동영상 속성 참조

카메라와 동영상 속성 값 참조와 설정

double VideoCapture::get(int propId) const;
bool VideoCapture::set(int propId, double value);
  • propId: 속성 플래그. cv::VideoCaptureProperties 또는 Additional flags for video I/O API backends 상수 중 선택

  • value: 속성 값. 필요한 경우 정수형으로 형변환하여 사용

  • 1280 x 720 프레임으로 받아오고 싶을 경우
    cap.set(CAP_PROP_FRAME_WIDTH,1280);
    cap.set(CAP_PROP_FRAME_HEIGHT,720);

  • fps 값 받아와서 출력하기
    double fps = cap.get(CAP_PROP_FPS)

동영상 저장하기

VideoWriter 클래스

  • OpenCV는 일련의 정지 영상을 동영상 파일로 저장할 수 있는 VideoWriter 클래스를 제공
  • VideoWriter 클래스 정의
class VideoWriter
{
public:
	VideoWriter();
    // 저장할 동영상 파일 열기
    VideoWriter(const String& filename, int fourcc, double fps, Size frameSize, bool isColor = true);
    virtual ~VideoCapture();
    
    // 저장할 동영상 파일 열기
    virtual bool open(const String& filename, int fourcc, double fps, Size frameSize, bool isColor = true);
    virtual void release();
    
    // 프레임 저장
    virtual VideoCapture& operator << (const Mat& image);
    
    // 정보 설정하기 & 가져오기
    virtual bool set(int propId, double value);
    virtual double get(int propId) const;
}

VideoWriter 클래스 생성자와 VideoWriter::open() 함수

	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개의 문자. VideoWriter::fourcc() 함수로 생성.
  • fps: 초당 프레임 수
  • frameSize: 비디오 프레임 크기
  • isColor: 컬러 동영상 플래그. false로 지정하면 그레이스케일 동영상

카메라 입력을 동영상 파일로 저장하는 예제 코드

int main()
{
	VideoCapture cap(0);

	int  fourcc = VideoWriter::fourcc('X', 'V', 'I', 'D');
	double fps = 15;
	Size sz((int)cap.get(CAP_PROP_FRAME_WIDTH), (int)cap.get(CAP_PROP_FRAME_HEIGHT));

	VideoWriter output("output.avi", fourcc, fps, sz);

	int delay = cvRound(1000 / fps);
	Mat frame;
	while (true) {
		cap >> frame;

		outputVideo << frame;
		imshow("frame", frame);

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

0개의 댓글