본문 목표
OpenCV 를 사용하다 보면, 웹캠으로 실시간 영상을 받아와서 영상처리를 해야할 때도 있지만, 저장되어 있는 동영상 파일에서도 영상처리를 필요로 할 때가 많다.
이번에는 동영상 파일에서 프레임을 추출해 연산처리를 할 수 있는 방법을 알아본다.
키워드 : VideoCapture
알아볼 함수 원형
- 동영상 캡쳐 또는 불러오기 ( VideoCapture )
#include <opencv2/opencv.hpp>
...
VideoCapture cap("test.mp4");
if (!cap.isOpened())
{
printf("Can't open the video");
return -1;
}
...
VideoCapture '변수 이름'( "동영상 이름" ) : '변수 이름'은 "동영상 이름"에 해당하는 동영상 화면(frame)을 읽어온다.
이 전에 웹캠으로부터 영상정보를 받아오는 방법과 매우 유사한 것을 알 수 있다.
사실 거의 같다고 보면 된다.
이 경우에는 카메라를 사용하는 것이 아니라, 컴퓨터에 저장되어 있는 동영상을 불러오는 것이 된다.
동영상 이름에는 확장자까지 포함이 되어야 정상적으로 불러올 수 있음에 주의한다.
동영상을 여러개 불러온다고 한다면 VideoCapture 변수를 여러개 사용하면 된다.
대신에 그만큼 연산처리 속도는 느려지게 될 것이다.
비디오 이름이 잘 못 되었거나, 없는 파일일 수 있다.
따라서 이에대한 안전장치를 해두는 것이 좋다.
코드에서도 나와있듯이 isOpened( ) 함수를 이용하여 동영상 파일이 제대로 읽혔는지 확인하는 습관을 가지자.
이왕 복붙 (복사 & 붙여넣기) 해서 사용할 꺼면 굳이 지우지 말고 그대로 사용하기를 권장한다.
코드 테스트 결과
- CODE
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main(int ac, char** av) {
VideoCapture cap("test.mp4");
//cap.set(CV_CAP_PROP_FRAME_WIDTH, 1920);
//cap.set(CV_CAP_PROP_FRAME_HEIGHT, 1080);
if (!cap.isOpened())
{
printf("Can't open the camera");
return -1;
}
Mat img;
while (1)
{
cap >> img;
if (img.empty())
{
printf("empty image");
return 0;
}
imshow("camera img", img);
if (waitKey(25) == 27)
break;
}
return 0;
}
- RESULT
동영상 파일이 정상적으로 OpenCV에서 읽혀서 출력이 되는 것을 확인할 수 있었다.
코드를 그대로 복사해서 사용할 경우 제대로 출력이 안 될 수 있다.
예를 들어, 속도가 너무 빠르거나 느리게 재생될 수 있다.
그 이유는 동영상의 해상도와, fps(초당 프레임), 컴퓨터 연산속도 이 모든것이 복합적으로 작용하기 때문이다.
그래서 이렇게 저장되어 있는 동영상을 실제 속도로 처리를 하려면 frame 을 받아오는 속도 조절이 필요하다.
가장 쉽게 하는 방법은
위와같이 waitKey( 'delay time' ) 함수를 적절히 사용하는 것이다.
waitKey 함수는 delay 기능을 하는데, 지연 시간을 잘 조정하면 실제 동영상 재생 속도와 근접하게 frame을 불러올 수 있다.
필자가 사용한 영상과 해상도, 컴퓨터 연산처리 속도에는 23~25 정도가 실제와 비슷하게 재생되었다.
하지만 완전 똑같을 수는 없었다...
여러가지 시도를 해봤지만, 제일 현실적인 방법은 waitKey() 를 통한 재생속도 조절이었다.
나중에는 연산처리를 하게되면 자연스럽게 느려지게 되어있으므로, 크게 신경 쓸 필요는 없다.
그리고 단순히 동영상만 재생한다면 상관없겠지만,
오류가 나지 않고 계속 실행되어야 하는 경우 동영상이 끝나면 불러오는 작업도 끝내야 오류가 나지 않는다.
영상은 다 끝났는데, 계속 무한반복문에서 없는 이미지 불러오라고 하면 당연히 오류가 나게 되고
코드 전체가 멈추게 된다.
그래서 필요한 장치가
img.empty( ) 함수를 사용한 동영상 정보의 유무 판단이다.
동영상 변수 cap 에서 img에 이미지 정보를 전달했을 때,
img 에 이미지 정보가 없으면 코드를 종료시킴으로써 오류가 발생하는 것을 방지해준다.
만약 위와 같은 장치 없이 imshow( ) 를 통해서 이미지를 출력하라고 하면
이미지가 없는데 어떻게 이미지를 출력하냐고 오류를 내뱉는다.
물론 코드가 전체적으로 중단된다...
따라서 나중에 사용자 정의함수를 만들어 사용한다면 꼭 이런 안전장치를 만들어놓고 사용하기를 바란다.
도움이 되었거나, 문제가 있는 경우 댓글로 알려주세요~!
감사의 댓글은 작성자에게 큰 힘이 됩니다 ^^
'코딩 > OpenCV' 카테고리의 다른 글
[C++ opencv] 효율적인 Histogram 이용한 이미지 밝기 조절 (4) | 2020.06.25 |
---|---|
[C++ opencv] 가장 쉽게 이미지 밝기 조절 하는 방법 (0) | 2020.06.25 |
[C++ opencv] 카메라, 웹캠 영상 입력받기 VideoCapture() (0) | 2020.06.24 |
[C++ opencv] Grayscale 변환에 대한 고찰 1 (4) | 2020.06.17 |
[C++ opencv] 컬러이미지 흑백으로 변환 , RGB to Grayscale (0) | 2020.06.17 |
댓글