본문 바로가기

Computer Vision by OpenCV

OpenCV : calcHist함수를 이용한 histogram 구하기 - 컬러이미지에 대해

반응형

컬러이미지를 B, G, R채널별로 히스토그램 구하기


각 채널별로 히스토그램을 별도로 계산해야 한다. Gray이미지의 채널 1개에 대해 하던 방법대로 하되, 다만 B, G, R 채널별로 동일한 작업을 반복해야 한다.


<그림 1> 컬러이미지

<그림 2> Blue 채널의 히스토그램: 하늘이 진한 파랑과 중간 파랑이 많아서 해당 부분의 빈도수가 높은 것을 볼 수 있다.

<그림 3> Green채널의 히스토그램

<그림 4> Red 채널의 히스토그램: 원본이미지의 바위색깔이 전반적으로 불그스레한 계통이므로 진한 빨간 계통의 색이 많이 분포하는 것을 볼 수 있다.


<소스코드 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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#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;

	inputImg = imread(argv[1], CV_LOAD_IMAGE_COLOR);
	resize(inputImg, inputImg, Size(), SCALE, SCALE, CV_INTER_AREA);

	MatND histogramB, histogramG, histogramR;
	const int channel_numbersB[] = { 0 };  // Blue
	const int channel_numbersG[] = { 1 };  // Green
	const int channel_numbersR[] = { 2 };  // Red
	float channel_range[] = { 0.0, 255.0 };
	const float* channel_ranges = channel_range;
	int number_bins = 255;

	// R, G, B별로 각각 히스토그램을 계산한다.
	calcHist(&inputImg, 1, channel_numbersB, Mat(), histogramB, 1, &number_bins, &channel_ranges);
	calcHist(&inputImg, 1, channel_numbersG, Mat(), histogramG, 1, &number_bins, &channel_ranges);
	calcHist(&inputImg, 1, channel_numbersR, Mat(), histogramR, 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 histImageB(hist_h, hist_w, CV_8UC3, Scalar(0, 0, 0));
	normalize(histogramB, histogramB, 0, histImageB.rows, NORM_MINMAX, -1, Mat());

	Mat histImageG(hist_h, hist_w, CV_8UC3, Scalar(0, 0, 0));
	normalize(histogramG, histogramG, 0, histImageG.rows, NORM_MINMAX, -1, Mat());

	Mat histImageR(hist_h, hist_w, CV_8UC3, Scalar(0, 0, 0));
	normalize(histogramR, histogramR, 0, histImageR.rows, NORM_MINMAX, -1, Mat());

	for (int i = 1; i < number_bins; i++)
	{
		
		line(histImageB, Point(bin_w*(i - 1), hist_h - cvRound(histogramB.at<float>(i - 1))),
			Point(bin_w*(i), hist_h - cvRound(histogramB.at<float>(i))),
			Scalar(255, 0, 0), 2, 8, 0);
		line(histImageG, Point(bin_w*(i - 1), hist_h - cvRound(histogramG.at<float>(i - 1))),
			Point(bin_w*(i), hist_h - cvRound(histogramG.at<float>(i))),
			Scalar(0, 255, 0), 2, 8, 0);

		line(histImageR, Point(bin_w*(i - 1), hist_h - cvRound(histogramR.at<float>(i - 1))),
			Point(bin_w*(i), hist_h - cvRound(histogramR.at<float>(i))),
			Scalar(0, 0, 255), 2, 8, 0);
	
	}


	namedWindow("Original", CV_WINDOW_AUTOSIZE);
	namedWindow("HistogramB", CV_WINDOW_AUTOSIZE);
	namedWindow("HistogramG", CV_WINDOW_AUTOSIZE);
	namedWindow("HistogramR", CV_WINDOW_AUTOSIZE);

	moveWindow("Original", 100, 100);
	moveWindow("HistogramB", 110, 110);
	moveWindow("HistogramG", 120, 120);
	moveWindow("HistogramR", 130, 130);

	imshow("Original", inputImg);
	imshow("HistogramB", histImageB);
	imshow("HistogramG", histImageG);
	imshow("HistogramR", histImageR);

	waitKey(0);
	return 0;
}



반응형