opencv에서 재공하는 API를 이용해 영상의 관심영역을 생성하고, 밝기 보정 프로그램을 만들어 본다.
- 코드의 상세 내용을 설명하고 가장 마지막에 전체 코드를 공개한다.
비디오 캡쳐
- 이미지 저장은 Mat 클래스로 하지만, 영상을 불러올 때는 VideoCapture 클래스를 사용한다.
VideoCapture cap("./base_camera_dark.avi");
- 관심영역 생성을 위해 마스크를 만든다.
- 영상의 크기 정보를 얻어 w, h 변수에 저장한다.
- 마스크는 그레이 스케일로 만들고 0으로 초기화한다.(검은색)
- 벡터에 관심영역 정보를 담은 Point 클래스를 저장한다.
- fillpoly 를 호출하여 마스크에 관심영역 부분을 흰색으로 채운다.
int w = cvRound(cap.get(CAP_PROP_FRAME_WIDTH));
int h = cvRound(cap.get(CAP_PROP_FRAME_HEIGHT));
Mat mask = Mat::zeros(h, w, CV_8UC1);
vector<Point> pts = {
Point(240, 280),
Point(400, 280),
Point(620, 440),
Point(20, 440)
};
fillPoly(mask, { pts }, Scalar(255));
- 관심영역의 평균밝기를 구하고 보정하는 코드이다.
- 동영상에서 한 프레임을 가져와 Mat 클래스에 저장한다.
- cvtColor 를 호출하여 컬러 영상을 그레이 스케일로 변환한다.
- mean 을 호출하여 평균값을 구하는데 이전에 만들었던 마스크를 활용하여 관심영역 부분만 구한다.
- 구한 평균을 이용해 밝기를 보정한다.
cap >> frame;
cvtColor(frame, gray, COLOR_BGR2GRAY);
Scalar m = mean(gray, mask);
dst = gray + (Scalar(128) - m);
- 아래는 동영상에 관심영역부분을 그려주는 내용이다.
line(frame, Point(240, 280), Point(400, 280), Scalar(255, 0, 0), 2);
line(frame, Point(400, 280), Point(620, 440), Scalar(255, 0, 0), 2);
line(frame, Point(620, 440), Point(20, 440), Scalar(255, 0, 0), 2);
line(frame, Point(20, 440), Point(240, 280), Scalar(255, 0, 0), 2);
- 아래는 프래임 번호를 구해 화면에 그려주는 내용이다.
int pos = cvRound(cap.get(CAP_PROP_POS_FRAMES));
String text = format("frame number: %d", pos);
putText(frame, text, Point(20, 50), FONT_HERSHEY_SIMPLEX,
0.7, Scalar(0, 0, 255), 1, LINE_AA);
- 아래는 전체 코드.
#include <iostream>
#include "opencv2/opencv.hpp"
using namespace cv;
using namespace std;
int main()
{
VideoCapture cap("./base_camera_dark.avi");
if (!cap.isOpened()) {
cerr << "Video open failed!" << endl;
return -1;
}
int w = cvRound(cap.get(CAP_PROP_FRAME_WIDTH));
int h = cvRound(cap.get(CAP_PROP_FRAME_HEIGHT));
Mat mask = Mat::zeros(h, w, CV_8UC1);
vector<Point> pts = {
Point(240, 280),
Point(400, 280),
Point(620, 440),
Point(20, 440)
};
fillPoly(mask, { pts }, Scalar(255));
Mat frame;
Mat gray;
Mat dst;
while (true) {
cap >> frame;
if (frame.empty()) {
cerr << "Empty frame!" << endl;
break;
}
cvtColor(frame, gray, COLOR_BGR2GRAY);
imshow("gray", gray);
Scalar m = mean(gray, mask);
dst = gray + (Scalar(128) - m);
imshow("dst", dst);
line(frame, Point(240, 280), Point(400, 280), Scalar(255, 0, 0), 2);
line(frame, Point(400, 280), Point(620, 440), Scalar(255, 0, 0), 2);
line(frame, Point(620, 440), Point(20, 440), Scalar(255, 0, 0), 2);
line(frame, Point(20, 440), Point(240, 280), Scalar(255, 0, 0), 2);
int pos = cvRound(cap.get(CAP_PROP_POS_FRAMES));
String text = format("frame number: %d", pos);
putText(frame, text, Point(20, 50), FONT_HERSHEY_SIMPLEX,
0.7, Scalar(0, 0, 255), 1, LINE_AA);
imshow("frame", frame);
if (waitKey(10) == 27)
break;
}
cap.release();
destroyAllWindows();
}