2018-01-29 12:37:23

로버트 라가니에의 <OpenCV를 활용한 컴퓨터 비전 프로그래밍, 3판>을 참고서로 하루에 2시간 정도씩 opencv를 활용해서 영상처리를 공부하려고 한다. 그동안 매트랩을 주로 써왔는데, MATLAB만으로 영상처리 관련 프로젝트를 다 구현해내기에는 한계를 많이 느껴왔기 때문이다. 물론 이전에도 C++과 opencv를 간간히 활용했지만 자유자재로 구현할 수 있는 수준은 아니기에, 연습이 필요하다. 


opencv를 활용하기 위해서 설치하고 빌드하는 과정이 복잡하지만 이 과정만 잘 거치면 영상처리를 위한 강력한 오픈소스 라이브러리를 활용할 수 있다. 



▶ 영상 읽고, 띄우고, 축소하고, 좌우반전하고, 저장하기


오늘은 가장 기본적인 영상을 읽고, 띄우고, 축소하고, 좌우반전하고, 저장하기를 실행해보겠다. 아래와 같은 절차를 밟을 것이다. 


1. 영상 읽기

2. 영상 띄우기

3. 영상 사이즈 변경- cv::resize

4. 영상 좌우 반전- cv::flip

5. 영상 저장


전체 코드를 우선 보자. 코드에 주석을 달아놓았으니 참고하자. 


#include <opencv2/core.hpp>

#include <opencv2/highgui.hpp>

#include <opencv2/opencv.hpp> // resize 함수 사용을 위해

#include <iostream>


int main()

{

cv::Mat image; // 빈 영상 생성


image = cv::imread("image1.JPG"); //이미지 읽기

if (image.empty()) //이미지를 제대로 읽을 수 없으면 에러 메시지 출력

{

std::cout << "error when reading image!" << std::endl;

return 0;

}


std::cout << "Origianl image is " << image.rows << " x " << image.cols << std::endl; //원본 이미지 사이즈 출력


cv::namedWindow("Original image"); // 원본 이미지를 전시할 창 만들기 

cv::imshow("Original image", image); // 원본 이미지 보여주기


cv::Mat resized_image; 

cv::resize(image, resized_image, cv::Size(), 0.25, 0.25, CV_INTER_AREA);  //원본 이미지 크기 조정하기. 가로 세로 모두 1/4로 축소. 


std::cout << "Resized image is " << resized_image.rows << " x " << resized_image.cols << std::endl; // 축소된 이미지 사이즈 출력


cv::namedWindow("Resized image"); 

cv::imshow("Resized image", resized_image); // 축소된 이미지 보여주기


cv::Mat result; 

cv::flip(resized_image, result, 1); //영상 좌우 반전하기


cv::namedWindow("Fliped image"); 

cv::imshow("Fliped image", result); //좌우 반전된 이미지 보여주기


cv::imwrite("Fliped_image.bmp", result); //좌우 반전된 이미지 저장


cv::waitKey(0); 


return 0;

}


이 코드를 실행한 결과 아래와 같은 세 개의 이미지가 전시되었다. 



가장 큰 이미지가 원본 이미지, 아래에서 왼쪽에 있는 것이 축소된 이미지, 오른쪽에 있는 것이 좌우반전된 이미지다. 참고로 이 사진은 고척돔에서 찍은 것이다. 또한 원본 이미지의 사이즈와 크기를 조정한 이미지의 사이즈가 출력되었다. 



가로, 세로 모두 1/4로 축소된 것을 알 수 있다. 



▶ 좀 더 알고 넘어갈 것들


1) cv::resize(입력 이미지, 출력 이미지, 출력 이미지 사이즈, 가로 축척 비율, 세로 축척 비율, 보간법)


입력 매개변수들 중에서 마지막은 보간법(interpolation)과 관련된 것이다. 영상을 축소하는 경우에는 CV_INTER_AREA, 영상을 확대하는 경우에는 CV_INTER_CUBIC(다소 느림) 또는 CV_INTER_LINEAR(빠름)가 추천된다. 


그리고 예제에서 영상을 가로, 세로 모두 1/4로 축소시킨 것과 달리 특정한 사이즈, 예를 들어 256x256으로 변경하고자 한다면, 


cv::resize(image, resized_image, cv::Size(256, 256), 0, 0, CV_INTER_AREA) 


과 같이 코드를 변경해주면 된다. 



2) cv::flip(입력 이미지, 출력 이미지, 반전 방향)


세번째 매개변수는 어느 방향으로 반전시켜줄지를 결정한다. 예제와 같이 양수면 좌우반전, 0이면 상하반전, 음수면 좌우반전과 상하반전을 모두 시켜준다. 


3) 영상 저장 관련


영상을 저장할 때는 cv::imwrite()가 활용되는데, 지원하는 영상 포맷은 JPG, PNG, TIFF이다. 


4) 영상 읽기 관련


예제에서는 컬러영상을 컬러로 읽었는데, 만약 그레이스케일로 읽으려면, 


image = cv::imread("image1.JPG", CV_LOAD_IMAGE_GRAYSCALE);


와 같이 코드를 변경해주면 된다. 아니면 컬러로 읽은 다음에 cv::cvtColor 함수를 활용해서 그레이영상으로 변환해줄 수도 있다. 


영상의 채널 개수를 확인하고 싶을 때는 channels 메소드를 사용하면 된다. 컬러 영상이라면 3이, 그레이 영상이라면 1이 출력될 것이다. 




<참고자료>

[1] 로버트 라가니에 지음, 이문호 옮김, "OpenCV를 활용한 컴퓨터 비전 프로그래밍 3/e", 에이콘