灰度或者彩色图像的直方图均衡化+Opencv(可以选择其中的某一个区域进行均衡)
支持单通道或者多通道的处理。可以对直方图选择其中的一段区域进行均衡,也可以对整个直方图进行均衡(只要改变均衡的起始和结束的直方图级别即可)。可以对背景或者黑白的部分进行排除而不对其进行处理,减少这些对均衡化的影响。
#include <highgui.h>
#include <cv.h>
int main()
{
int i = 0;
int j = 0;
int k = 0;
IplImage* src = cvLoadImage("33.jpg", CV_LOAD_IMAGE_GRAYSCALE );//CV_LOAD_IMAGE_GRAYSCALE
cvNamedWindow( "src", 1 );
cvShowImage( "src", src );
//cvWaitKey(0);
IplImage* dst = cvCreateImage( cvGetSize( src ), IPL_DEPTH_8U, src->nChannels );
//直方图均衡化,灰度或者彩色图均可
if( src )
{
for( k = 0; k < src -> nChannels; k++ )
{
//直方图均衡化,原始图像和目标图像必须是单通道
//cvEqualizeHist( imgChannel[i], imgChannel[i] );
int Hist[256] = {0};
int pixelsnum = 0;
int nStartGrayLevel = 8;
int nEndGrayLevel = 256 - nStartGrayLevel;
int nGrayLevel = 256 - nStartGrayLevel * 2;//需要均衡化的灰度级
unsigned char gray = 0;
//直方图
for(i = 0; i < src->height; i++)
{
char *p = src->imageData + i * src->widthStep + k;//+k是选择需要均衡化的通道
for(j = 0; j < src->width; j++)
{
gray = (unsigned char)(*(p));
Hist[gray]++;
if(gray > nStartGrayLevel && gray < nEndGrayLevel)
pixelsnum++;
p += 3;
}
}
//均衡化索引
for(i = 0; i < nStartGrayLevel;i++)
{
Hist[i] = i;
}
int temp = 0;
for(i = nStartGrayLevel; i < nEndGrayLevel;i++)
{
temp += Hist[i];
int value = 0;
value = (int)(temp * nGrayLevel / (float)pixelsnum + 0.5 +nStartGrayLevel);
if(value > 255)
value = 255;
if(value < 0)
value = 0;
Hist[i] = value;
}
for(i = nEndGrayLevel; i < 256;i++)
{
Hist[i] = i;
}
//根据均衡化索引进行处理
for(i = 0; i < src->height; i++)
{
char *ps = src->imageData + i * src->widthStep + k;//+k是选择需要均衡化的通道
char *p = dst->imageData + i * dst->widthStep + k;//+k是保存均衡化的通道
for(j = 0; j < src->width; j++)
{
gray = (unsigned char)(*(ps));
*(p) = (unsigned char)(Hist[gray]);
ps += 3;
p += 3;
}
}
}
cvNamedWindow( "src", 1 );
cvShowImage( "src", src );
cvNamedWindow( "Equalize", 1 );
cvShowImage( "Equalize", dst );
cvWaitKey(0);
//释放资源
cvReleaseImage( &dst );
}
return 0;
}