2012년 12월 28일 금요일

OpenCV #2-2 Example (포인터로 영상 조회)

  • Example (Color reduce function - 분석 복잡도를 낮추기 위해 사용)

#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

void colorReduce(cv::Mat &image, int div=64){ // div = 64는 color Reduce 방법 중 하나

int nl = image.rows; // 행 개수 (높이)
int nc = image.cols*image.channels();
// 각 행에 있는 원소의 총 개수. cols는 너비
// image.channels()이 1이면 그레이레벨, 3이면 컬러레벨 영상

for(int j=0 ; j<nl ; j++){

uchar* data = image.ptr<uchar>(j); // j열의 주소를 가져오기

for(int i=0 ; i<nc ; i++){

// 각 화소 처리
data[i] = data[i]/div*div + div/2;
//*data++= *data/div*div + div/2;
// 각 화소 처리 끝
} // 행 끝
}
}

int main()

{
cv::Mat image = cv::imread("boldt.jpg");

colorReduce(image);


cv::namedWindow("Image");

cv::imshow("Image", image);
cv::waitKey(5000);

return 0;

}


  • Result



  • 예제 분석

 - 영상 데이터 버퍼의 첫 3 바이트는 상위 왼쪽 화소의 3 채널 값, 다음 3 바이트는 첫 번째 행의 두 번째 화소값
 - 영상의 너비가 W이고 높이가 H라면 WxHx3 uchar에 대한 메모리 블록이 필요
 - 데이터 속성인 cols는 영상의 너비 (열의 개수), rows는 영상의 높이
 - step 데이터 속성은 바이트 개수인 유효 너비 (uchar가 아닌 다른 타입이라도 너비당 바이트 개수를 갖는다.)

 - elemSize : 화소의 크기 (3채널 short 정수 행렬 CV_16SC3이라면 6을 반환)
 - nchannels : 영상의 채널 개수 (그레이레벨 영상은 1, 컬러 영상은 3)
 - total : 행렬 내 화소(행렬 원소)의 총 개수

 - 너비 당 화소 개수 값 : int nc = image.cols * image.channels();

 - ptr : 포인터 산술 연산을 이용한 계산에서 vc:Mat 클래스는 직접 영상의 열인 주소를 가져오는 ptr 메소드를 제공.
 - j열의 주소를 반환하는 템플릿 메소드 : uchar* data = image.ptr<uchar>(j);

 - 행에서 행으로 옮기기 위한 포인터 산술 연산 : *data++ = *data/div*div + div/2

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