본문 바로가기
코딩/OpenCV

[C++ opencv] 카메라, 웹캠 영상 입력받기 VideoCapture()

by DIYver 2020. 6. 24.

본문 목표

OpenCV를 사용하는 목적은 여러가지가 있을 수 있다. 정지되어 있는 사진, 움직이는 물체를 담은 동영상, 실시간 카메라 영상 등 다양하게 사용할 수 있는데, 이번에는 실시간 카메라 영상을 OpenCV에서 사용하는 방법에 대해서 알아본다.

 

 

키워드 :  VideoCapture 

 

 

 

 

 

알아볼 함수 원형

- 동영상 캡쳐 또는 불러오기 ( VideoCapture )

#include <opencv2/opencv.hpp>

...
VideoCapture cap(0);
	
if (!cap.isOpened())
{
	printf("Can't open the camera");
	return -1;
}

...

 

VideoCapture '변수 이름'( '카메라 번호' ) : '변수 이름'은 '카메라 번호'에 해당하는 카메라 화면을 읽어온다.

 

 

노트북의 경우 내장 웹캠이 있고, 활성화가 되어있는 경우 내장 웹캠의 카메라 번호는 '0' 이 된다.

 

데스크탑처럼 웹캠을 추가적으로 usb를 통해서 연결한 경우 해당 웹캠의 카메라 번호는 '0' 이 된다.

 

노트북의 경우 내장 웹캠이 활성화 되어있으면, 웹캠을 추가할 경우 카메라 번호는 '1' 이 된다.

 

위와 같은 규칙으로 카메라 번호가 설정된다.

 

 

'변수 이름'은 웹캠으로부터 이미지를 읽어오는 역할을 한다.

 

보통 capture 를 줄여서 cap 이라고 많이 사용한다.

 

카메라가 정상적으로 연결이 안 되었을 수 있으니 코딩 시작부에서 카메라가 정상 작동하는지 확인하는 명령을 넣어줄 필요가 있다.

 

OpenCV가 정말 많이 개발되었고 오래사용하면서 이런것들은 다 준비가 되어있다고 보면 된다.

 

'변수 이름'.isOpened()  함수가 카메라 정보가 있는지 없는지를 판단해주는 역할을 한다.

 

카메라 정보가 있으면 1, 없으면 0을 반환한다.

 

앞에 ! 를 붙였으므로 카메라 정보가 없으면 '1' 로 반환되게 하고 조건문을 실행되게 한다.

 

return -1 로 하여 오류가 있음을 사용자에게 알려주는 센스가 필요하다.

(굳이 안 해도 전혀 문제 될 건 없지만, 습관을 기르는게 실력향상에 도움이 된다.)

 

 

 

 

 

 

 

코드 테스트 결과

- CODE

#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main(int ac, char** av) {

	VideoCapture cap(0);
	
	if (!cap.isOpened())
	{
		printf("Can't open the camera");
		return -1;
	}

	Mat img;

	while (1)
	{
		cap >> img;

		imshow("camera img", img);

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


	return 0;
}

 

- RESULT

 

웹캠을 이용해서 사무실 내부가 정상적으로 나오고 있음을 확인할 수 있었다.

 

OpenCV 코딩을 통해서 해상도, 자동초점 설정, 밝기, 채도 등 다양한 옵션을 손볼 수 있다.

 

하지만 그냥 실행한 결과 640,480 해상도로 카메라 정보를 받아왔고,

 

밝기와 초점 등 모두 웹캠의 세팅값인 자동으로 처리되는 것을 확인할 수 있었다.

 

 

 

코딩 내용 중에서 cap 은 카메라를 준비시키는 변수이지, 픽셀 정보를 담고 있는 변수가 아님에 주의해야한다.

 

카메라를 계속 사용하려면 무한 반복문에서 코딩을 해야 하며,

cap >> img  라는 명령을 써야, 카메라 정보를 img 라는 행렬에 저장할 수 있게된다.

 

그리고 웹캠 이미지를 출력하는 것에서 종료할 수 있는 방법을 만들어 놓지 않으면 강제로 끄는 수 밖에 없기 때문에

 

waitKey() == 27 을 사용하여 'esc'를 눌러 종료할 수 있게 해야한다.

 

 

 

 

 

 

이번에는 해상도를 변경해 보도록 한다.

...
	VideoCapture cap(0);
	cap.set(CV_CAP_PROP_FRAME_WIDTH, 1920);
	cap.set(CV_CAP_PROP_FRAME_HEIGHT, 1080);
...

 

기존 그대로에서 

 

cap.set(CV_CAP_PROP_FRAME_WIDTH, 1920);

cap.set(CV_CAP_PROP_FRAME_HEIGHT, 1080);

을 추가하면 된다.

 

실행 결과는 아래와 같다.

해상도는 양옆 검은화면까지 포함해서 1920 x 1080 해상도로 나온다.

 

하지만 정상적인 FHD 화면은 아니라고 할 수 있다.

 

해외 포럼을 뒤져본 결과 로지텍 웹캠 C920 에서 이런 문제가 발생하는 듯 하다.

 

뭔가 드라이버가 제대로 작동 안 하는것 같다. 정확히 모르겠다.

 

해결방법은 간단했다.

 

설정을 하나만 더 추가해줬으면 되었는데

 

VideoCapture cap(0, CAP_DSHOW);

위와 같이 CAP_DSHOW 를 옵션에 추가만 해주면 되었다.

 

즉, 코드를 보면

이런식으로 하면 FHD 영상을 받아올 수 있게된다.

 

결과 이미지는 위와같고

 

그전 양옆에 검은색으로 뜨던 부위로 더 넓게 이미지가 정상 출력되는 것을 확인할 수 있었다.

 

 

 

 

 

도움이 되었거나, 문제가 있는 경우 댓글로 알려주세요~!

감사의 댓글은 작성자에게 큰 힘이 됩니다 ^^

댓글