2013년 1월 7일 월요일

OpenCV #4-2 Example (영상 모습을 수정하기 위한 룩업 테이블 적용)

 - 영상 히스토그램 : 활용 가능한 화소의 명암도 값을 사용해 묘사된 장면을 잡는 방법.
 - 영상 전체의 화소값 분포를 분석하면 수정하기 위한 정보를 사용할 수 있고, 영상도 개선할 수 있다.
 - 영상의 화소값을 수정하기 위해 룩업 테이블로 표현하는 간단한 사상 함수 사용.

 - 룩업 테이블 : 일대일(다대일) 함수, 화소값을 새로운 화소값으로 변환하는 방법을 정의.
 - 1차원 배열로 그레이레벨 영상 수준인 경우 256개 항목이 있음.
 - 테이블의 i 항목은 대응하는 그레이레벨 영상의 새로운 명암도 값.
 - netIntensity = lookup[oldIntensity];


  • Example
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

// 멤버 변수 정의
class Histogram1D {
private:
int histSize[1]; // 빈도수
float hranges[2]; // 최소/최대 화소값
const float* ranges[1];
int channels[1]; // 여기서 1채널만 사용
public :
Histogram1D() { // 1차원 히스토그램을 위한 인자 준비
histSize[0]= 256;
hranges[0]= 0.0;
hranges[1]= 255.0;
ranges[0]= hranges; 
channels[0]= 0; // 기본적으로 채널을 0으로 보기
 }
cv::Mat applyLookUp (const cv::Mat& image, const cv::Mat& lookup)
// const cv::Mat& image는 입력 영상
// const cv::Mat& lookup는 1x256 uchar 행렬
{
cv::Mat result; // 결과 영상
cv::LUT(image, lookup, result); 
// 새로운 영상을 만들기 위해 룩업 테이블을 영상에 적용
// 새로운 영상에는 룩업 테이블에 의해 처리된 그대로 화소의 명암도 값을 수정한 결과가 들어감
return result;
}
};

int main()
{
cv::Mat image = cv::imread("batgirl.jpg", 0);
// 입력 영상 읽기
// 이진 영상으로 간주해 열기
if(!image.data)
return 0;

cv::namedWindow("Image");
cv::imshow("Image", image);

Histogram1D h; // 히스토그램 객체

// 간단한 변환
int dim(256); // 영상 역전 테이블 생성
cv::Mat lut(1, &dim, CV_8U);
// 1은 1차원, &dim은 256 항목, CV_8U는 uchar
for(int i=0 ; i<256 ; i++) {
lut.at<uchar>(i) = 255-i;
}

cv::namedWindow("Negative image");
cv::imshow("Negative image",h.applyLookUp(image,lut));
// 화소의 명암도를 뒤집는다.
// 명암도 0을 255로, 1을 254로 계속 바꿈
// 영상에 룩업 테이블을 적용하면 원 영상의 네거티브 영상을 만듬

cv::waitKey(0);

return 0;
}

  • Result

  • 참고문헌 : OpenCV 2 Computer Vision Application Programming Cookbook