영상 처리 과정 중에 각 단계별 프레임을 동시에 놓고 봐야 하는 경우가 굉장히 많다. 출력을 바로 띄워 주는 경우에는 각 윈도우의 위치를 잘 조정해주면 되지만, 아무래도 분석을 위해서는 영상을 합쳐서 하나로 저장하는 것이 보기 더 편할 때가 있다.
다행히 프레임을 가로, 세로로 이어 붙이는 함수가 다 있으므로 편하게 사용하면 된다.
// 두 프레임을 가로로 붙여 result에 저장
cv::hconcat(src1, src2, result); // horizental-concatenation
// 두 프레임을 세로로 붙여 result에 저장
cv::vconcat(src1, src2, result); // vertical-concatenate
src1, src2의 채널 수는 같아야 한다.
또한 hconcat()의 경우에는 두 프레임의 row의 수가 일치해야 하고, vconcat()의 경우 col의 수가 일치해야 한다.
4개의 영상을 2x2로 이어 붙이는 코드이다.
frame1 | frame2 |
---|---|
frame3 | frame4 |
추후 이 코드를 발전시켜 다양한 레이아웃을 지원하도록 바꿔볼 예정이다.
#include "opencv2/opencv.hpp"
using namespace cv;
int main(){
VideoCapture input_video("input_path");
if (!input_video.isOpened()) {
cout << "Can't open video\n";
return;
}
int fourcc = VideoWriter::fourcc('a', 'v', 'c', '1');
double fps = input_video.get(CAP_PROP_FPS);
Size size = Size(input_video.get(CAP_PROP_FRAME_WIDTH), input_video.get(CAP_PROP_FRAME_HEIGHT));
VideoWriter output_video;
output_video.open("output_path", fourcc, fps, size, true);
Mat original, frame[4], temp[2], result;
while (true) {
video >> original;
if (original.empty()) {
break;
}
// 4단계 가공을 거친다고 가정했을 때...
frame[0] = proc1(original);
frame[1] = proc2(frame[0]);
frame[2] = proc3(frame[1]);
frame[3] = proc4(frame[2]);
// 가로로 이어 붙이기
for (int i=0; i<2; i++) {
hconcat(frame[2*i], frame[2*i+1], temp[i]);
}
// 세로로 이어 붙이기
vconcat(temp[0], temp[1], result);
output_video << result;
}
input_video.release();
output_video.release();
}