컬러이미지를 채널별로 분리하여 히스토그램 그리기

히스토그램 : 영상의 픽셀값들에 대한 분포를 나타내는 그래프

가로축은 픽셀값(0~255)이고 세로축은 픽셀값에 대한 빈도수이다



c++)

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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include <opencv/cv.h>
#include <opencv/highgui.h>
 
 
void main() {
    IplImage *srcImage = cvLoadImage("D:/study/testimage2.jpg"-1);
 
    IplImage *rImage = cvCreateImage(cvGetSize(srcImage), IPL_DEPTH_8U, 1);
    IplImage *gImage = cvCreateImage(cvGetSize(srcImage), IPL_DEPTH_8U, 1);
    IplImage *bImage = cvCreateImage(cvGetSize(srcImage), IPL_DEPTH_8U, 1);
 
    IplImage *rHistogramImage = cvCreateImage(cvGetSize(srcImage), IPL_DEPTH_8U, 1);
    IplImage *gHistogramImage = cvCreateImage(cvGetSize(srcImage), IPL_DEPTH_8U, 1);
    IplImage *bHistogramImage = cvCreateImage(cvGetSize(srcImage), IPL_DEPTH_8U, 1);
 
 
 
    //cvSplit() : 원본이미지를 B,G,R 채널별로 분리
    cvSplit(srcImage, bImage, gImage, rImage, NULL);
 
 
    //cvCreateHist(차원, 차원의 크기배열, 표현형식, x축 범위, 막대간격) : 히스토그램 생성
    //차원 : 1 - 1차원 or 3 - 3차원
    //차원의 크기배열 : {256} - 1차원 , {256,256,256} - 3차원
    //표현형식 : CV_HIST_ARRAY - 다채널 밀집배열(0인 원소가 거의 없음) , CV_HIST_SPARSE - 다채널 희소배열(0인 원소가 많음)
    //x축 범위
    //막대간격 : 0이면 막대간격을 다르게 , 0이 아니면 막대간격을 일정하게
    int bins = 256;    //0~255
    int sizes[3= {256,256,256};
    float range[] = {0255};
    float *ranges[] = {range};
    CvHistogram *rHistogram = cvCreateHist(1&bins, CV_HIST_ARRAY, ranges, 1);
    CvHistogram *gHistogram = cvCreateHist(1&bins, CV_HIST_ARRAY, ranges, 1);
    CvHistogram *bHistogram = cvCreateHist(1&bins, CV_HIST_ARRAY, ranges, 1);
 
 
    //cvCalcHist(원본이미지, 히스토그램 포인터) : 이미지로부터 히스토그램을 계산
    cvCalcHist(&rImage, rHistogram, 0NULL);
    cvCalcHist(&gImage, gHistogram, 0NULL);
    cvCalcHist(&bImage, bHistogram, 0NULL);
 
 
    //cvGetMinMaxHistValue(히스토그램, 최소빈도수, 최대빈도수) : 히스토그램에서 막대에 대한 최대빈도수, 최소빈도수를 구하는 함수
    float rMinValue, gMinValue, bMinValue;
    float rMaxValue, gMaxValue, bMaxValue;
    cvGetMinMaxHistValue(rHistogram, &rMinValue, &rMaxValue);
    cvGetMinMaxHistValue(rHistogram, &gMinValue, &gMaxValue);
    cvGetMinMaxHistValue(rHistogram, &bMinValue, &bMaxValue);
 
 
    //cvScale(원본배열, 결과배열, scale, shift) : 하나의 배열을 다른 배열로 변환하는 함수
    //dst = src * scale + shift
    cvScale(rHistogram->bins, rHistogram->bins, ((double)rImage->height)/rMaxValue, 0); //scale the histogram bar heights to fit into the histogram image window
    cvScale(gHistogram->bins, gHistogram->bins, ((double)gImage->height) / gMaxValue, 0);
    cvScale(bHistogram->bins, bHistogram->bins, ((double)bImage->height) / bMaxValue, 0);
 
 
    //cvSet(이미지, 채울값, 마스크) : 이미지를 주어진 값으로 설정
    cvSet(rHistogramImage, cvScalarAll(255), 0);    //background of histogram window is set to white(255)
    cvSet(gHistogramImage, cvScalarAll(255), 0);
    cvSet(bHistogramImage, cvScalarAll(255), 0);
 
 
    //cvRound(값) : 반올림 함수
    int binW = cvRound((double)rHistogramImage->width / bins);
 
 
    //히스토그램 막대 그리기
    for (int i = 0; i < bins; i++) {
        //cvRectangle(이미지, 모서리좌표1, 모서리좌표2, 선색, 선두께) : 직사각형그리는 함수
        //cvGetReal1D(히스토그램의 1차원배열, index) : 1차원 히스토그램에서 index번째 막대의 빈도수를 얻는 함수
        cvRectangle(rHistogramImage, cvPoint(i*binW, rHistogramImage->height), cvPoint((i+1)*binW, rHistogramImage->height - cvRound(cvGetReal1D(rHistogram->bins, i))), cvScalarAll(0), 1);
        cvRectangle(gHistogramImage, cvPoint(i*binW, gHistogramImage->height), cvPoint((i+1)*binW, gHistogramImage->height - cvRound(cvGetReal1D(gHistogram->bins, i))), cvScalarAll(0), 1);
        cvRectangle(bHistogramImage, cvPoint(i*binW, bHistogramImage->height), cvPoint((i+1)*binW, bHistogramImage->height - cvRound(cvGetReal1D(bHistogram->bins, i))), cvScalarAll(0), 1);
    }
 
 
 
    cvNamedWindow("source", CV_WINDOW_AUTOSIZE);
    cvNamedWindow("red", CV_WINDOW_AUTOSIZE);
    cvNamedWindow("green", CV_WINDOW_AUTOSIZE);
    cvNamedWindow("blue", CV_WINDOW_AUTOSIZE);
 
    cvShowImage("source", srcImage);
    cvShowImage("red", rHistogramImage);
    cvShowImage("green", gHistogramImage);
    cvShowImage("blue", bHistogramImage);
 
    cvWaitKey(0);
 
    cvReleaseImage(&srcImage);
    cvReleaseImage(&rImage);
    cvReleaseImage(&gImage);
    cvReleaseImage(&bImage);
    cvReleaseImage(&rHistogramImage);
    cvReleaseImage(&gHistogramImage);
    cvReleaseImage(&bHistogramImage);
}
 
cs



결과

이미지에 대한 R,G,B 별로 픽셀값에 대한 빈도수를 그래프로 보여준다



+ Recent posts