首页 > 代码库 > 图像直方图均衡化增强opencv与C语言版

图像直方图均衡化增强opencv与C语言版

本文实现彩色图像的全局直方图均衡。分别对R/G/B三通道均衡,读写图片采用OpenCV。代码如下:

#include <opencv2/opencv.hpp>
//#include <cv.h>
//#include <cxcore.h>
//#include <highgui.h>
#include <time.h>  
#include <stdio.h>
#include <math.h>
#include "EqualizeHist.h" 
//typedef unsigned char uchar;

IplImage* EqualizeHistColorImage(IplImage *pImage)  
{  
    IplImage *pEquaImage = cvCreateImage(cvGetSize(pImage), pImage->depth, 3);  
      
    // 原图像分成各通道后再均衡化,最后合并即彩色图像的直方图均衡化  
    const int MAX_CHANNEL = 4;  
    IplImage *pImageChannel[MAX_CHANNEL] = {NULL};  
  
    int i;  
    for (i = 0; i < pImage->nChannels; i++)  
        pImageChannel[i] = cvCreateImage(cvGetSize(pImage), pImage->depth, 1);  
  
    cvSplit(pImage, pImageChannel[0], pImageChannel[1], pImageChannel[2], pImageChannel[3]);  
      
    for (i = 0; i < pImage->nChannels; i++)  
     // cvEqualizeHist(pImageChannel[i], pImageChannel[i]);
  	EqualizeHist( (uchar*)(pImageChannel[i]->imageData), (uchar*)(pImageChannel[i]->imageData),pImage->width,pImage->height );
    cvMerge(pImageChannel[0], pImageChannel[1], pImageChannel[2], pImageChannel[3], pEquaImage);  
  
    for (i = 0; i < pImage->nChannels; i++)  
        cvReleaseImage(&pImageChannel[i]);  
  
    return pEquaImage;  
} 

      
int main( int argc, char** argv )  
{  
      IplImage* pImg; //声明IplImage指针  
	IplImage* pEquaImage; 
	clock_t start, finish;
      	double time;
      //载入图像,强制转化为Gray   
	   
	pImg = cvLoadImage( "nupt.jpg", CV_LOAD_IMAGE_UNCHANGED); 
	if(pImg==NULL)
		return -1;
	printf("Load img success\n"); 

	start = clock();
	pEquaImage = EqualizeHistColorImage(pImg);
	finish = clock();
	time = (double)(finish - start) / CLOCKS_PER_SEC;
    	printf( "finish operation for %dchannels in %lf seconds\n",pImg->nChannels,time);

	cvNamedWindow("src",CV_WINDOW_AUTOSIZE);
	cvNamedWindow("dst",CV_WINDOW_AUTOSIZE);
	cvShowImage("src",pImg);
	cvShowImage("dst",pEquaImage);
	cvWaitKey(0);
	cvSaveImage("ret.jpg", pEquaImage);//把图像写入文件   
	cvReleaseImage(&pImg); //释放图像 
	cvReleaseImage(&pEquaImage);
          return 0;  

} 

//#include <math.h>
#include <assert.h>
typedef unsigned char uchar;
void EqualizeHist( const unsigned char* src,unsigned char* dst,int width,int height )
{
    int x,y;
    const int hist_sz = 256;
    int hist[hist_sz];
    memset(hist, 0, sizeof(hist));
    int size = width*height;
//统计每个灰度值出现的次数
	for(x=0;x<size;x++){
			assert(*(src+x)<257 && *(src+x)>=0);
            hist[*(src+x)]++;
	}
    
    float scale = 255.f/(width*height);
    int sum = 0;
    uchar lut[hist_sz+1];


    for(x = 0; x < hist_sz; x++ )
    {
        sum += hist[x];
        //int val = round(sum*scale);
		int val =(sum*scale+0.5);
        lut[x] = val;
    }


    lut[0] = 0;
    for( y = 0; y < size; y++ )
    {


            *(dst+y) = lut[*(src+y)];
					if(y%100==0)
		printf("%d\n",*(dst+y));
    }
}


原图:

效果图