컬러이미지를 채널별로 분리하여 히스토그램 그리기
히스토그램 : 영상의 픽셀값들에 대한 분포를 나타내는 그래프
가로축은 픽셀값(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[] = {0, 255}; 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, 0, NULL); cvCalcHist(&gImage, gHistogram, 0, NULL); cvCalcHist(&bImage, bHistogram, 0, NULL); //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 별로 픽셀값에 대한 빈도수를 그래프로 보여준다
'IT > - 프로그래밍' 카테고리의 다른 글
OpenCV 이미지 확대하기 (0) | 2017.04.29 |
---|---|
OpenCV 이미지 히스토그램 평활화하기 (0) | 2017.04.28 |
OpenCV 에지검출하기2 (0) | 2017.04.26 |
OpenCV 에지검출하기1 (0) | 2017.04.25 |
OpenCV 임펄스 잡음 제거하기 (중앙값 필터링 사용) (0) | 2017.04.24 |