测试图片:
code:
方案1:
#include "cv.h" #include "highgui.h" #define HDIM 256 // bin of HIST, default = 256 int main( int argc, char** argv ) { IplImage *src = 0, *dst = 0; CvHistogram *hist = 0; int n = HDIM; double nn[HDIM]; uchar T[HDIM]; CvMat *T_mat; int x; int sum = 0; // sum of pixels of the source image 图像中象素点的总和 double val = 0; src=cvLoadImage("1.jpg", 0); cvNamedWindow( "source", 1 ); cvNamedWindow( "result", 1 ); // calculate histgram 计算直方图 hist = cvCreateHist( 1, &n, CV_HIST_ARRAY, 0, 1 ); cvCalcHist( &src, hist, 0, 0 ); // Create Accumulative Distribute Function of histgram val = 0; for ( x = 0; x < n; x++) { val = val + cvGetReal1D (hist->bins, x); nn[x] = val; } // Compute intensity transformation 计算变换函数的离散形式 sum = src->height * src->width; for( x = 0; x < n; x++ ) { T[x] = (uchar) (255 * nn[x] / sum); // range is [0,255] } // Do intensity transform for source image dst = cvCloneImage( src ); T_mat = cvCreateMatHeader( 1, 256, CV_8UC1 ); cvSetData( T_mat, T, 0 ); // directly use look-up-table function 直接调用内部函数完成 look-up-table 的过程 cvLUT( src, dst, T_mat ); int y; for(y=0;y<dst->height;y++) { for(x=0;x<dst->width;x++) { int dstV,srcV; dstV = cvGetReal2D(dst,y,x); srcV = cvGetReal2D(src,y,x); int newV ; newV = (srcV*0.7+dstV*0.4); newV = newV > 255 ? 255 : newV; cvSetReal2D(dst,y,x,newV); } } cvShowImage( "source", src ); cvShowImage( "result", dst ); cvWaitKey(0); cvDestroyWindow("source"); cvDestroyWindow("result"); cvReleaseImage( &src ); cvReleaseImage( &dst ); cvReleaseHist ( &hist ); return 0; }
效果:
方案2:
#include "stdafx.h" #include "cv.h" #include "cxcore.h" #include "highgui.h" int main(int argc, char* argv[]) { IplImage* src; src = cvLoadImage("1.jpg"); IplImage* srcSmooth; srcSmooth= cvCreateImage(cvGetSize(src),8,3); cvSmooth(src,srcSmooth,CV_GAUSSIAN,35,35,0,0); IplImage* srcGray=cvCreateImage(cvGetSize(src),8,1); cvCvtColor(srcSmooth,srcGray,CV_BGR2GRAY); CvMat* points = cvCreateMat(srcGray->height*srcGray->width , 1 , CV_32FC1); CvMat* clusters= cvCreateMat(srcGray->height*srcGray->width , 1 , CV_32SC1); uchar* image_data = (uchar*)srcGray->imageData; int width_step = srcGray->widthStep; int x,y; for(y=0;y<src->height;y++) { for(x=0;x<src->width;x++) { points->data.fl[y*srcGray->width+x] = (float)(*(image_data + y*width_step + x)); } } cvKMeans2(points,3,clusters ,cvTermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER,10,1.0)); float cluster_0_count=0,cluster_1_count=0; float sum_cluster_0 =0 , sum_cluster_1 = 0; for(y=0;y<srcGray->height;y++) { for(x=0;x<srcGray->width;x++) { int cluster_id = clusters->data.i[y*srcGray->width+x]; if(cluster_id == 0 || cluster_id==2) { sum_cluster_0 = sum_cluster_0 + (float)(*(image_data + y*width_step + x)); cluster_0_count = cluster_0_count + 1; *(image_data + y*width_step + x) = 255; } else if(cluster_id == 1 ) { sum_cluster_1 = sum_cluster_1 + (float)(*(image_data + y*width_step + x)); *(image_data + y*width_step + x) = (int)cvGetReal2D(srcGray,y,x); } else { } } } cvNamedWindow("src"); cvShowImage("src",src); cvNamedWindow("s"); cvShowImage("s",srcSmooth); cvNamedWindow("g"); cvShowImage("g",srcGray); cvWaitKey(0); return 0; }
效果: