采用一个64位的数组模拟规定化的直方图。
void CmyCImageView::OnHistMatch()
{
// lilizong【at】Gmail copyright:李立宗 2012-8-1
if(myImage2.IsNull()){
//myImage2.Destroy();
myImage2.Create(myImage.GetWidth(),myImage.GetHeight(),24,0);
//myImage2.~CImage();
// myImage2.m_hBitmap=0;
//这个函数的逻辑调整了很多次,开始是尝试去销毁已经存在的myImage2,后来发现并不行
//直接判断myImage2是否存在,然后决定是否creat比较合适。
}
/*
//读入目标要匹配的图像
CFileDialog fileDlg2(TRUE,NULL,NULL,OFN_ALLOWMULTISELECT,_T("Picture Files (*.bmp *.jpg)|*bmp;;*jpg||"),AfxGetMainWnd());
CString pathName2;
if(fileDlg2.DoModal () == IDOK)
{
POSITION mPos = fileDlg2.GetStartPosition();
if(mPos!=NULL)
{
pathName2 = (LPCTSTR)fileDlg2.GetPathName();
if(!myImage3.IsNull())//判断图象是否为空,如果不为空则先释放掉
myImage3.Destroy();
myImage3.Load(pathName2);
}
}
*/
//myImage2=myImage;
for(int x=0;x<256;x++)
myImageArray[x]=0;
//坑爹呀,数组居然没有初始化,导致总是黑图,完全一片黑,调试好久好久。
//错误一堆呀,终于完成。2012-8-1
COLORREF pixel;
int maxY = myImage.GetHeight();
int maxX=myImage.GetWidth();
int x,y;
int r,g,b,avg;
float temp=0.0f;
//开始将temp定义为int,致命错误。因为算出结果都是零呀。
int indexMap[256],indexpMap[64];
//for(int i=0;i<256;i++)
//{
// myImageArray[i]=0;
// myImage2Array[i]=0;
// myImage3Array[i]=0;
//}
//原始图像的计算
for (int x=0; x<maxX; x++) {
for (int y=0; y<maxY; y++) {
pixel = myImage.GetPixel(x,y);
r = GetRValue(pixel);
g = GetGValue(pixel);
b = GetBValue(pixel);
myImageArray[r]=myImageArray[r]+1;
}
}
//调试发现错误,myImageArray[i]始终为负数
for(int i=0;i<256;i++)
{
myImageArray[i]=myImageArray[i]/(maxX*maxY*1.0f);
}
for(int i=0;i<256;i++)
{
temp=temp+myImageArray[i];
myImageArray[i]=temp;
}
float a=1.0f/(32.0f*63.0f);
for(int i=0;i<64;i++)
{
indexpMap[i]=i*4;
myImage3Array[i]=a*i;
}
//目标图像的计算
temp=0;
for(int i=0;i<64;i++)
{
temp=temp+myImage3Array[i];
myImage3Array[i]=temp;
}
//确定映射关系
int i,j;
for(i=0;i<256;i++)
{
int m=0;
float min_value=1.0f;
for(j=0;j<64;j++)
{
float now_value=0.0f;
now_value=abs(myImageArray[i]-myImage3Array[j]);
if(now_value<min_value)
{
m=j;
min_value=now_value;
}
}
//m=rand()%63+1;
indexMap[i]=indexpMap[m];
}
//完成映射处理
for (int x=0; x<maxX; x++) {
for (int y=0; y<maxY; y++) {
pixel = myImage.GetPixel(x,y);
r = GetRValue(pixel);
g = GetGValue(pixel);
b = GetBValue(pixel);
avg=(int)indexMap[r];
/*CString str;
str.Format(_T("%d"),avg);
MessageBox(str);*/
//if(avg<0)
// avg=0;
//if(avg>255)
// avg=255;
myImage2.SetPixelRGB(x,y,avg,avg,avg);
}
}
Invalidate();
}
参考资料:Visual C++数字图像处理技术详解。