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();
}