Histogram 그리기
이미지에서 픽셀들이 가지는 값들의 출현빈도를 히스토그램 (histogram)이라고 한다.
예를 들어, gray 이미지에서 각 픽셀은 0부터 255까지의 값을 갖는다.
이미지의 크기를 300 x 300 이라고 한다면, 총 90,000개의 픽셀들을 0~255 값에 따라 분류하여
각 개별값을 갖는 픽셀들이 몇 개씩인지 알아낸 것이 히스토그램이다.
히스토그램은 contranst enhancement (안 보이는 부분을 잘 보이게) 등에 사용되는데,
이 때 사용되는 기술이 histogram equalization이다. 이것의 원리는 이 <<블로그>>를 참조한다.
OpenCV에서는 이미지의 히스토그램 계산이 쉽도록 함수 calcHist( )를 제공한다.
void cv::calcHist | ( | const Mat * | images, |
int | nimages, | ||
const int * | channels, | ||
InputArray | mask, | ||
OutputArray | hist, | ||
int | dims, | ||
const int * | histSize, | ||
const float ** | ranges, | ||
bool | uniform = true , | ||
bool | accumulate = false | ||
) |
images: Histogram을 계산할 이미지들에 대한 배열이다.
nimages: images 배열에 포함된 이미지의 개수 이다.
channels: Histogram을 계산할 채널 번호들의 배열이다. 예를 들어, 아래 그림과 같이 BGR 이미지 2장에 대해, 첫 번째 이미지는 B 채널, 두 번째 이미지는 G 채널에 대해서 histogram을 구하고자 한다면 {0, 4}를 배열에 넣어서 전달해야 한다.
mask: Histogram을 계산할 영역을 지정할 수 있다. 옵션사항이고, emptry mask (즉, Mat( ))를 전달하면 아무런 동작도 하지 않는다.
hist: Histogram 계산결과를 저장한다.
dims: Histogram 계산결과를 저장한 hist의 차원을 가리킨다.
histSize: 각 차원의 bin 개수, 즉 빈도수를 분류할 칸의 개수를 의미한다.
ranges: 각 차원의 분류 bin의 최소값과 최대값을 의미한다.
아래는 gray 이미지에 대해 픽셀값 0 ~ 255에 대해 histogram을 계산하여 그래프로 표시한 결과이다.
<그림 1> Histogram을 계산할 대상 이미지 (gray)
<그림 2> 그림 1에 대한 Histogram 계산결과를 시각화한 결과
위의 결과를 만들어 내기 위한 프로그램의 소스코드이다.
<소스코드 1> 히스토그램을 계산하고 그래프로 시각화하는 프로그램
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace std; #define SCALE 0.2 int main(int argc, char** argv) { if (argc != 2) { cout << " Provide image name to read" << endl; return -1; } Mat inputImg; Mat greyImg; inputImg = imread(argv[1], CV_LOAD_IMAGE_COLOR); resize(inputImg, inputImg, Size(), SCALE, SCALE, CV_INTER_AREA); // inputImg를 gray영상(greyImg)으로 변환한다. cvtColor(inputImg, greyImg, CV_BGR2GRAY); MatND histogram; const int* channel_numbers = { 0 }; float channel_range[] = { 0.0, 255.0 }; const float* channel_ranges = channel_range; int number_bins = 255; calcHist(&greyImg, 1, channel_numbers, Mat(), histogram, 1, &number_bins, &channel_ranges); // Plot the histogram int hist_w = 512; int hist_h = 400; int bin_w = cvRound((double)hist_w / number_bins); Mat histImage(hist_h, hist_w, CV_8UC1, Scalar(0, 0, 0)); normalize(histogram, histogram, 0, histImage.rows, NORM_MINMAX, -1, Mat()); for (int i = 1; i < number_bins; i++) { line(histImage, Point(bin_w*(i - 1), hist_h - cvRound(histogram.at<float>(i - 1))), Point(bin_w*(i), hist_h - cvRound(histogram.at<float>(i))), Scalar(255, 0, 0), 2, 8, 0); } namedWindow("Original", CV_WINDOW_AUTOSIZE); namedWindow("Histogram", CV_WINDOW_AUTOSIZE); moveWindow("Original", 100, 100); moveWindow("Histogram", 120, 120); imshow("Original", greyImg); imshow("Histogram", histImage); waitKey(0); return 0; } |
'Computer Vision by OpenCV' 카테고리의 다른 글
OpenCV: HLS영상 히스토그램(histogram)의 장점 (2) | 2016.03.27 |
---|---|
OpenCV : calcHist함수를 이용한 histogram 구하기 - 컬러이미지에 대해 (1) | 2016.03.26 |
OpenCV Noise제거하기, Median filtering (1) | 2016.03.26 |
OpenCV 잡음(noise) 제거하기 - Local Averaging, Gaussian smoothing (0) | 2016.03.25 |
OpenCV 잡음, Salt & Pepper Noise 추가하기 (1) | 2016.03.25 |