📄 zxdib.cpp
字号:
for(j=0; j<dwWidth; j++)
{
counter = (int)(pColorBitmap[(i*dwWidth+j)*3+1]) - (int)(pBKImage[(i*dwWidth+j)*3+1]);
if(counter<0) counter = 0-counter;
if(counter>255) counter = 255;
pResultImage[i*dwWidth+j] = (BYTE) counter;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 利用OTSU算法进行图像分割:
// 输入图像和输出图像都是pBitmap,输出为2值图像
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool CZXDib::SegmentByOTSU(BYTE *pBitmap, DWORD dwHeight, DWORD dwWidth)
{
int i,j,nResultColor,i_from,i_to;
DWORD dwSize = dwHeight*dwWidth;
float pHg[256];
float u,wk,uk,deltk;
float fMax;
for(i=0;i<256;i++)
pHg[i] = 0;
for(i=0;i<dwHeight; i++)
for(j=0;j<dwWidth; j++)
pHg[pBitmap[i*dwWidth+j]]++;
u = 0;
for(i=0;i<256; i++)
{
pHg[i] /= dwSize;
u += i*pHg[i];
}
//目的是避免分母为0的情况:
for(i=0;i<256 && !pHg[i];i++);
i_from = i;
for(i=255;i>=0 && !pHg[i];i--);
i_to = i;
i_from += 2;
i_to -= 2;
fMax = 0;wk=0; uk=0;
nResultColor = 0;
for(i=0;i<i_from;i++)
{
wk += pHg[i];
uk += (float)i * pHg[i];
}
//寻找门限;
for(i=i_from;i<i_to;i++)
{
wk += pHg[i];
uk += (float)i * pHg[i];
deltk = u*wk-uk;
deltk *= deltk;
deltk /= wk*(1-wk);
if(fMax<deltk)
{
fMax = deltk;
nResultColor = i;
}
}
//nResultColor -=40;
for(i=0;i<dwHeight;i++)
for(j=0;j<dwWidth;j++)
pBitmap[i*dwWidth+j] = pBitmap[i*dwWidth+j]>nResultColor?255:0;
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//利用下山法找谷点:
////////////////////////////////////////////////////////////////////////////////////////////////
int CZXDib::SegmentByDownHill(BYTE *pBitmap, DWORD dwHeight, DWORD dwWidth)
{
int i,j,dwSize;
dwSize = dwWidth*dwHeight;
DWORD pTemp[256];
for(i=0;i<256;i++)
pTemp[i] = 0;
for(i=0;i<dwHeight;i++)
for(j=0;j<dwWidth;j++)
pTemp[pBitmap[i*dwWidth+j]] ++;
// for(i=0;i<13;i++)
HistogramSmoothBy5Points(pTemp,256);
//找到最大峰点:
int max = 0;
int k = 0;
for(i=3;i<256;i++)
if(max<pTemp[i])
{
max = pTemp[i];
k = i;
}
for(i=0;i<256;i++)
{
pTemp[i] *= 255;
pTemp[i] /= max;
}
//找谷点:
int last,next;
last = pTemp[k-1]+pTemp[k];
next = pTemp[k+2]+pTemp[k+3];
bool bStop = false;
for(i=k;i<252 && !bStop;i++)
{
last += pTemp[i+1];
next += pTemp[i+4];
if(last - next <30)
{
bStop = true;
k=i;
}
last -= pTemp[i-1];
next -= pTemp[i+2];
}
//二值化:
for(i=0;i<dwHeight;i++)
for(j=0;j<dwWidth; j++)
pBitmap[i*dwWidth+j] = pBitmap[i*dwWidth+j]>k?255:0;
return k;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//利用给定的参数将图像进行归一化处理:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool CZXDib::UnifyByMeanAndVariance(BYTE *pBitmap, DWORD dwHeight, DWORD dwWidth, float fMeanOutput, float fVarianceOutput,float fMeanInput=-1,float fVarianceInput=-1)
{
DWORD i,dwSize;
float temp;
dwSize = dwHeight*dwWidth;
//求均值:
if(fMeanInput == -1)
{
fMeanInput = 0;
for(i=0;i<dwSize;i++)
fMeanInput += pBitmap[i];
fMeanInput /= dwSize;
}
//求方差:
if(fVarianceInput == -1)
{
fVarianceInput = 0;
for(i=0;i<dwSize;i++)
{
temp = pBitmap[i];
temp *= temp;
fVarianceInput += temp;
}
fVarianceInput = sqrt(fVarianceInput/dwSize-fMeanInput*fMeanInput);
}
//规整化
for(i=0;i<dwSize;i++)
{
temp = (pBitmap[i]-fMeanInput)*fVarianceOutput/fVarianceInput+fMeanOutput;
if(temp<0) pBitmap[i] = 0;
else
if(temp>255) pBitmap[i] = 255;
else
pBitmap[i] = (BYTE) temp;
}
return true;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//利用给定的参数将图像进行归一化处理:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool CZXDib::UnifyByMeanAndVariance(BYTE *pBitmap, DWORD dwHeight, DWORD dwWidth, float pMeanOutput[3], float pVarianceOutput[3],float pMeanInput[3],float pVarianceInput[3])
{
DWORD i,dwSize;
float temp;
bool bDeleteMean = false;
bool bDeleteVariance = false;
dwSize = dwHeight*dwWidth;
//求均值:
if(!pMeanInput)
{
bDeleteMean = true;
pMeanInput = new float[3];
pMeanInput[0] =
pMeanInput[1] =
pMeanInput[2] = 0;
for(i=0;i<dwSize;i++)
{
pMeanInput[0] += pBitmap[i*3];
pMeanInput[1] += pBitmap[i*3+1];
pMeanInput[2] += pBitmap[i*3+2];
}
pMeanInput[0] /= dwSize;
pMeanInput[1] /= dwSize;
pMeanInput[2] /= dwSize;
}
//求方差:
if(!pVarianceInput)
{
bDeleteVariance = true;
pVarianceInput = new float[3];
pVarianceInput[0] =
pVarianceInput[1] =
pVarianceInput[2] =0;
for(i=0;i<dwSize;i++)
{
temp = pBitmap[i*3];
temp *= temp;
pVarianceInput[0] += temp;
temp = pBitmap[i*3+1];
temp *= temp;
pVarianceInput[1] += temp;
temp = pBitmap[i*3+2];
temp *= temp;
pVarianceInput[2] += temp;
}
pVarianceInput[0] = sqrt(pVarianceInput[0]/dwSize-pMeanInput[0]);
pVarianceInput[1] = sqrt(pVarianceInput[1]/dwSize-pMeanInput[1]);
pVarianceInput[2] = sqrt(pVarianceInput[2]/dwSize-pMeanInput[2]);
}
//规整化
for(i=0;i<dwSize;i++)
{
temp = (pBitmap[i*3]-pMeanInput[0])*pVarianceOutput[0]/pVarianceInput[0]+pMeanOutput[0];
if(temp<0) pBitmap[i*3] = 0;
else
if(temp>255) pBitmap[i*3] = 255;
else
pBitmap[i*3] = (BYTE) temp;
temp = (pBitmap[i*3+1]-pMeanInput[1])*pVarianceOutput[1]/pVarianceInput[1]+pMeanOutput[1];
if(temp<0) pBitmap[i*3+1] = 0;
else
if(temp>255) pBitmap[i*3+1] = 255;
else
pBitmap[i*3+1] = (BYTE) temp;
temp = (pBitmap[i*3+2]-pMeanInput[2])*pVarianceOutput[2]/pVarianceInput[2]+pMeanOutput[2];
if(temp<0) pBitmap[i*3+2] = 0;
else
if(temp>255) pBitmap[i*3+2] = 255;
else
pBitmap[i*3+2] = (BYTE) temp;
}
if(bDeleteMean) delete pMeanInput;
if(bDeleteVariance) delete pVarianceInput;
return true;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//统计图像的均值和方差:
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool CZXDib::StatisticParametersAboutMeanAndVariance(BYTE *pBitmap, DWORD dwHeight, DWORD dwWidth, float &fMean, float &fVariance)
{
DWORD i,dwSize;
float temp;
dwSize = dwHeight*dwWidth;
//求均值:
fMean = 0;
for(i=0;i<dwSize;i++)
fMean += pBitmap[i];
fMean /= dwSize;
//求方差:
fVariance = 0;
for(i=0;i<dwSize;i++)
{
temp = pBitmap[i];
temp -= fMean;
temp *= temp;
fVariance += temp;
}
fVariance = sqrt(fVariance/dwSize);
return true;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//利用给定的参数将图像进行归一化处理:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool CZXDib::StatisticParametersAboutMeanAndVariance(BYTE *pBitmap, DWORD dwHeight, DWORD dwWidth, float fMean[3], float fVariance[3])
{
DWORD i,dwSize;
float temp;
dwSize = dwHeight*dwWidth;
//求均值:
fMean[0] =
fMean[1] =
fMean[2] = 0;
for(i=0;i<dwSize;i++)
{
fMean[0] += pBitmap[i*3];
fMean[1] += pBitmap[i*3+1];
fMean[2] += pBitmap[i*3+2];
}
fMean[0] /= dwSize;
fMean[1] /= dwSize;
fMean[2] /= dwSize;
//求方差:
fVariance[0] =
fVariance[1] =
fVariance[2] =0;
for(i=0;i<dwSize;i++)
{
temp = pBitmap[i*3];
temp -= fMean[0];
temp *= temp;
fVariance[0] += temp;
temp = pBitmap[i*3+1];
temp -= fMean[1];
temp *= temp;
fVariance[1] += temp;
temp = pBitmap[i*3+2];
temp -= fMean[2];
temp *= temp;
fVariance[2] += temp;
}
fVariance[0] = sqrt(fVariance[0]/dwSize);
fVariance[1] = sqrt(fVariance[1]/dwSize);
fVariance[2] = sqrt(fVariance[2]/dwSize);
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////
// 生成一个bmp文件头
////////////////////////////////////////////////////////////////////////////////////////////////
bool CZXDib::CreateBITMAPFILEHEADER(DWORD dwHeight, DWORD dwWidth, BITMAPFILEHEADER *&pBmi,WORD flag)
{
if(!pBmi)
pBmi =(BITMAPFILEHEADER*) new BYTE[sizeof(BITMAPFILEHEADER)];
if(flag == 24)
pBmi->bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFO)-4;
else
pBmi->bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFO)-4+256*sizeof(RGBQUAD);
pBmi->bfReserved1 = 0;
pBmi->bfReserved2 = 0;
pBmi->bfType = 0x4d42;//'BM'
DWORD dwWriteWidth = (dwWidth+3)/4*4;
pBmi->bfSize = dwHeight*dwWriteWidth + pBmi->bfOffBits;
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//求两个向量的互相关:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool CZXDib::CorrelationOfTwoVectors(BYTE *pBitmap1, BYTE *pBitmap2, DWORD dwHeight, DWORD dwWidth, float fFlag,float &fResult)
{
DWORD i,j;
DWORD dwSize = dwHeight*dwWidth;
float temp;
fResult = 0;
for(i=0;i<dwSize;i++)
{
temp = pBitmap1[i]-pBitmap2[i];
if(temp<0) temp = 0-temp;
if(temp>fFlag)
fResult++;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//求Nagel相似度量:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool CZXDib::NagelSimilarity(BYTE *pBitmap1, BYTE *pBitmap2, DWORD dwHeight, DWORD dwWidth, double *&pResult)
{
DWORD Height,Width,dwSize;
Height = dwHeight-1;
Width = dwWidth-1;
dwSize = dwHeight*dwWidth;
int k,l;
double variance1,variance2,mean1,mean2;
double temp;
if(pResult) delete pResult;
pResult = (double*) new double [dwSize];
DWORD i,j;
for(i=1;i<Height;i++)
for(j=1; j<Width;j++)
{
//3*3临域,均值和方差:
mean1=0;
for(k=-1;k<2;k++)
for(l=-1;l<2;l++)
mean1 += pBitmap1[(i+k)*dwWidth+j+l];
mean1 /= 9;
variance1=0;
for(k=-1;k<2;k++)
for(l=-1;l<2;l++)
variance1+=((double)(pBitmap1[(i+k)*dwWidth+j+l]))*((double)(pBitmap1[(i+k)*dwWidth+j+l]));
variance1=sqrt(variance1/9-mean1*mean1);
mean2=0;
for(k=-1;k<2;k++)
for(l=-1;l<2;l++)
mean2 += pBitmap2[(i+k)*dwWidth+j+l];
mean2 /= 9;
variance2=0;
for(k=-1;k<2;k++)
for(l=-1;l<2;l++)
variance2+=((double)(pBitmap2[(i+k)*dwWidth+j+l]))*((double)(pBitmap2[(i+k)*dwWidth+j+l]));
variance2=sqrt(variance2/9-mean2*mean2);
temp = (variance1+variance2)/2+(mean1-mean2)*(mean1-mean2)/4;
pResult[i*dwWidth+j] = (temp*temp/(variance1*variance2+1));
}
for(i=0;i<dwSize;i+=dwWidth)
{
pResult[i]=pResult[i+1];
pResult[i+dwWidth-1]=pResult[i+dwWidth-2];
}
for(j=0;j<dwWidth;j++)
{
pResult[j]=pResult[j+dwWidth];
pResult[dwSize-j-1]=pResult[dwSize-j-1-dwWidth];
}
return true;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// 写文件
///////////////////////////////////////////////////////////////////////////////////////////////////
bool CZXDib::WriteDoubleMatricToFile(CString strFileName, DWORD dwHeight, DWORD dwWidth,double* pMatric)
{
if(!pMatric)
return false;
//打开文件:
CFile File;
if(!File.Open(strFileName,CFile::modeCreate|CFile::modeWrite))
{
AfxMessageBox("打不开文件"+strFileName);
return false;
}
File.Write(&dwHeight,sizeof(DWORD));
File.Write(&dwWidth,sizeof(DWORD));
File.WriteHuge(pMatric,dwHeight*dwWidth*sizeof(double));
File.Close();
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
// 从文件中装入浮点型数据 //
////////////////////////////////////////////////////////////////////////////////////////////////////////
bool CZXDib::LoadDoubleDataFromFile(CString strFileName, DWORD &dwHeight, DW
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -