📄 图像增强技术doc.cpp
字号:
TD1[i + h * j] = FD1[j + w * i];
TD2[i + h * j] = FD2[j + w * i];
}
}
for(i = 0; i < w; i++)
{
// 对x方向进行快速付立叶变换
FFT(&TD1[i * h],&TD2[i * h],&FD1[i * h], &FD2[i * h], hp);
}
for(i = 0; i < h; i++)
{
for(j = 0; j < w; j++)
{
// 计算频谱
dTemp = sqrt(FD1[j * h + i] * FD1[j * h + i] +
FD2[j * h + i] * FD2[j * h + i]) / 100;
// 判断是否超过255
if (dTemp > 255)
{
// 对于超过的,直接设置为255
dTemp = 255;
}
// 指向DIB第(i<h/2 ? i+h/2 : i-h/2)行,第(j<w/2 ? j+w/2 : j-w/2)个象素的指针
// 此处不直接取i和j,是为了将变换后的原点移到中心
// 更新源图像
lpBits[(i<h/2 ? i+h/2 : i-h/2)/*)*/*lLineBytes
+ (j<w/2 ? j+w/2 : j-w/2)] = (BYTE)(dTemp);
}
}
FFD1=FD1;
FFD2=FD2;
// 删除临时变量
delete TD1;
delete TD2;
// delete FD1;
// delete FD2;
UpdateAllViews(NULL);
SetModifiedFlag();
}
//22.对图像进行高通傅立叶变换函数代码完毕
//DEL void CMyDoc::OnNormalHightFilter()
//DEL {
//DEL // TODO: Add your command handler code here
//DEL //该函数用于对图像进行理想高通滤波
//DEL
//DEL float fFreq;
//DEL long i,j;
//DEL long lLineBytes=(8*m_size.cx+31)/32*4;
//DEL
//DEL CNormalFrequentDlg dlg;
//DEL dlg.m_fNormalFrequent=100;
//DEL dlg.m_iSize=100;
//DEL
//DEL if(dlg.DoModal()==IDOK)
//DEL {
//DEL fFreq=dlg.m_fNormalFrequent;
//DEL //调用高通傅立叶变换
//DEL HightFilterFFT();
//DEL
//DEL for(j=m_size.cy/2-dlg.m_iSize/2;j<m_size.cy/2+dlg.m_iSize/2;j++)
//DEL {
//DEL for(i=lLineBytes/2-dlg.m_iSize/2;i<lLineBytes/2+dlg.m_iSize/2;i++)
//DEL {
//DEL if(lpBits[j*lLineBytes+i]>=fFreq)
//DEL {
//DEL FFD1[j*lLineBytes+i]=0;
//DEL FFD2[j*lLineBytes+i]=0;
//DEL // lpBits[j*lLineBytes+i]=(int)(0.5+FFD1[j*lLineBytes+i]);
//DEL }
//DEL }
//DEL }
//DEL //调用高通傅立叶反变换
//DEL HightFilterIFFT();
//DEL }
//DEL
//DEL }
//23.对图像进行理想高通滤波函数代码完毕
void CMyDoc::HightFilterIFFT()
{
//该函数对图像进行高通反傅立叶变换
// 中间变量
double dTemp;
// 循环变量
LONG i,j;
// 进行付立叶变换的宽度和高度(2的整数次方)
LONG w,h;
int wp,hp;
// 图像每行的字节数
LONG lLineBytes=(8*m_size.cx+31)/32*4;
// 赋初值
w = 1;
h = 1;
wp = 0;
hp = 0;
// 计算进行付立叶变换的宽度和高度(2的整数次方)
while(w * 2 <= m_size.cx)
{
w *= 2;
wp++;
}
while(h * 2 <= m_size.cy)
{
h *= 2;
hp++;
}
// 分配内存
double *TD1 = new double[w * h];
double *TD2 = new double[w * h];
double *FD1 = new double[w * h];
double *FD2 = new double[w * h];
for(i = 0; i < h; i++)
{
for(j = 0; j < w; j++)
{
// 给频域赋值
FD1[j + w * i] = FFD1[j+w*i];
FD2[j + w * i] = FFD2[j+w*i];
}
}
for(i = 0; i < w; i++)
{
// 对x方向进行快速付立叶反变换
IFFT(&FD1[h * i], &FD2[h * i],&TD1[h * i],&TD2[h * i], hp);
}
// 保存变换结果
for(i = 0; i < h; i++)
{
for(j = 0; j < w; j++)
{
FD1[i + h * j] = TD1[j + w * i];
FD2[i + h * j] = TD2[j + w * i];
}
}
for(i = 0; i < h; i++)
{
// 对y方向进行快速付立叶反变换
IFFT(&FD1[i * w],&FD2[i * w],&TD1[i * w], &TD2[i * w], wp);
}
for(i = 0; i < h; i++)
{
for(j = 0; j < w; j++)
{
//计算灰度值
dTemp = sqrt(TD1[j * h + i] * TD1[j * h + i] +
TD2[j * h + i] * TD2[j * h + i]);
// 判断是否超过255
if (dTemp > 255)
{
// 对于超过的,直接设置为255
dTemp = 255;
}
// 更新源图像
lpBits[j*lLineBytes+i/*i*lLineBytes + j*/] = (BYTE)(dTemp);
}
}
delete TD1;
delete TD2;
delete FD1;
delete FD2;
UpdateAllViews(NULL);
SetModifiedFlag();
}
//24.对图像进行高通反傅立叶变换函数代码完毕
void CMyDoc::OnRecursivemidfilter()
{
// TODO: Add your command handler code here
//该函数用递归中值滤波的方法对图像进行平滑
//定义递归中值滤波参数设置对话框
CRecursiveMidFilterDlg dlg;
//循环变量
LONG i,j,x,y;
//模板的高度,宽度,系数及中心元素的X坐标,Y坐标
int iTempH,iTempW,iTempMX,iTempMY;
//图像每行的字节数
long lLineBytes=(8*m_size.cx+31)/32*4;
//中间变量
BYTE bTemp;
//复制原始图像
LPBYTE lpNewDIB;
HLOCAL hNew;
hNew=LocalAlloc(LHND,lLineBytes*m_size.cy);
if(hNew==NULL)
{
MessageBox(NULL,"分配内存失败!","flase",MB_OK);
}
lpNewDIB=(BYTE*)LocalLock(hNew);
memcpy(lpNewDIB,lpBits,lLineBytes*m_size.cy);
//模板数组
unsigned char* bValue;
//初始化对话框
dlg.m_MidFH=3;
dlg.m_MidFW=3;
dlg.m_MidFMX=1;
dlg.m_MidFMY=1;
if(dlg.DoModal()==IDOK)
{
//接受用户设置
iTempH=dlg.m_MidFH;
iTempW=dlg.m_MidFW;
iTempMX=dlg.m_MidFMX;
iTempMY=dlg.m_MidFMY;
//递归中值滤波模板长度
int iFilterLen=iTempH*iTempW;
bValue=(unsigned char*)malloc(iFilterLen);
//开始递归中值滤波
//由于模板的原因,除去边缘几行
for(j=iTempMY;j<m_size.cy-iTempH+iTempMY+1;j++)
{
//由于模板的原因,除去边缘几列
for(i=iTempMX;i<lLineBytes-iTempW+iTempMX+1;i++)
{
//读取滤波器数组
for(y=0;y<iTempH;y++)
{
for(x=0;x<iTempW;x++)
{
if(y<iTempMY)
{
bValue[y*iTempW+x]=lpBits[(j-iTempMY+y)*lLineBytes+x+i-iTempMX];
}
else if(y>iTempMY)
{
bValue[y*iTempW+x]=lpNewDIB[(j-iTempMY+y)*lLineBytes+x+i-iTempMX];
}
else if(x<iTempMX)
{
bValue[y*iTempW+x]=lpBits[(j-iTempMY+y)*lLineBytes+x+i-iTempMX];
}
else
{
bValue[y*iTempW+x]=lpNewDIB[(j-iTempMY+y)*lLineBytes+x+i-iTempMX];
}
}
}
//对模板内的灰度值进行排序
for(y=0;y<iFilterLen-1;y++)
{
for(x=0;x<iFilterLen-y-1;x++)
{
if(bValue[x]>bValue[x+1])
{
//互换
bTemp=bValue[x];
bValue[x]=bValue[x+1];
bValue[x+1]=bTemp;
}
}
}
//找出该模板内灰度的中间值
if(iFilterLen%2==0)
{
//偶数个元素,返回中间两个元素中间值
bTemp=(bValue[iFilterLen/2]+bValue[iFilterLen/2-1])/2;
}
else
{
//奇数个元素,返回中间一个元素值
bTemp=bValue[(iFilterLen-1)/2];
}
lpBits[j*lLineBytes+i]=bTemp;
}
}
}
/****************************用于计算峰值信噪比*********************************/
FPSNRTemp=0.0;
for(j=0;j<m_size.cy;j++)
{
for(i=0;i<lLineBytes;i++)
{
FPSNRTemp+=pow((double)(lpBits[j*lLineBytes+i]-lpTemp1DIB[j*lLineBytes+i]),2)/(m_size.cy*lLineBytes);
}
}
FPSNR=10*log10(255*255/FPSNRTemp);
PSNR=1;
/******************************************************************************/
/******************************************************************************/
FNMSETemp1=0.0;
FNMSETemp2=0.0;
for(j=0;j<m_size.cy;j++)
{
for(i=0;i<lLineBytes;i++)
{
FNMSETemp1+=pow((lpBits[j*lLineBytes+i]-lpTempDIB[j*lLineBytes+i]),2);
FNMSETemp2+=pow(lpTempDIB[j*lLineBytes+i],2);
}
}
FNMSE=FNMSETemp1/FNMSETemp2;
PSNR=1;
Caption.Format("*****您所用的滤波方法为%dx%d递归中值滤波*****",iTempH,iTempW);
/******************************************************************************/
/*************************************************************/
FSIF=0.0;
FNMSETemp3=0;
for(j=0;j<m_size.cy;j++)
{
for(i=0;i<lLineBytes;i++)
{
FNMSETemp3+=pow((double)(lpTempDIB[j*lLineBytes+i]-lpTemp1DIB[j*lLineBytes+i]),2);
}
}
FSIF=-20*log10(FNMSETemp1/FNMSETemp3);
/*************************************************************/
UpdateAllViews(NULL);
SetModifiedFlag();
LocalUnlock(lpNewDIB);
LocalFree(lpNewDIB);
free(bValue);
}
//25.用递归中值滤波的方法对图像进行平滑函数代码完毕
void CMyDoc::OnSmallwave()
{
// TODO: Add your command handler code here
//该函数用小波去噪的方法对图像进行平滑
}
//26.用小波去噪的方法对图像进行平滑函数代码完毕
void CMyDoc::OnNormallowfilter()
{
// TODO: Add your command handler code here
//该函数用理想低通滤波的方法对图像进行平滑
}
//27.用理想低通滤波的方法对图像进行平滑函数代码完毕
void CMyDoc::OnBaterwofulowfilter()
{
// TODO: Add your command handler code here
//该函数用巴特沃夫低通滤波的方法对图像进行平滑
}
//28.用巴特沃夫低通滤波的方法对图像进行平滑函数代码完毕
void CMyDoc::OnZhishulowfilter()
{
// TODO: Add your command handler code here
//该函数用指数低通低通滤波的方法对图像进行平滑
}
//29.用指数低通滤波的方法对图像进行平滑函数代码完毕
void CMyDoc::OnTixinglowfilter()
{
// TODO: Add your command handler code here
//该函数用梯形低通低通滤波的方法对图像进行平滑
}
//30.用梯形低通滤波的方法对图像进行平滑函数代码完毕
void CMyDoc::OnBaterwofuhightfilter()
{
// TODO: Add your command handler code here
//该函数用巴特沃夫高通滤波的方法对图像进行锐化
}
//31.用巴特沃夫高通滤波的方法对图像进行锐化函数代码完毕
void CMyDoc::OnZhishuhightfilter()
{
// TODO: Add your command handler code here
//该函数用指数高通低通滤波的方法对图像进行锐化
}
//32.用指数高通滤波的方法对图像进行锐化函数代码完毕
void CMyDoc::OnTixinghightfilter()
{
// TODO: Add your command handler code here
//该函数用梯形高通低通滤波的方法对图像进行锐化
}
//33.用梯形高通滤波的方法对图像进行锐化函数代码完毕
void CMyDoc::OnCopysaltnoiseimage()
{
// TODO: Add your command handler code here
//该函数用于复制噪声图像
//循环变量
long i,j;
lpTemp1DIB=new unsigned char[m_size.cx*(8*m_size.cx+31)/32*4];
for(j=0;j<m_size.cy;j++)
{
for(i=0;i<(8*m_size.cx+31)/32*4;i++)
{
lpTemp1DIB[j*(8*m_size.cx+31)/32*4+i]=lpBits[j*(8*m_size.cx+31)/32*4+i];
}
}
}
//34.复制噪声图像函数代码完毕
void CMyDoc::OnBlurredaddedmeanfilter()
{
// TODO: Add your command handler code here
//该函数用模糊加权均值滤波的方法对图像进行平滑滤波
CBlurredAddedMeanFilterDlg dlg;
//循环变量
long i,j,x,y;
//每行的字节数
long lLineBytes=(8*m_size.cx+31)/32*4;
//中间变量
float iTemp;
float fTempBorderValue,fTemp1,fTemp2;
int iTempDimensionValue;
float* fTemp=new float[9];
float fTemp3,y0,y1;
//复制原始图像
LPBYTE lpNewDIB;
HLOCAL hNew;
hNew=LocalAlloc(LHND,lLineBytes*m_size.cy);
if(hNew==NULL)
{
MessageBox(NULL,"分配内存失败!","flase",MB_OK);
}
lpNewDIB=(BYTE*)LocalLock(hNew);
memcpy(lpNewDIB,lpBits,lLineBytes*m_size.cy);
//初始化对话框
dlg.m_fBorderValue=(float)0.01;
dlg.m_iDimensionValue=5000;
if(dlg.DoModal()==IDOK)
{
//接受用户设置
fTempBorderValue=dlg.m_fBorderValue;
iTempDimensionValue=dlg.m_iDimensionValue;
//开始模糊加权均值滤波
//由于模板的原因,除去边缘几行
for(j=1;j<m_size.cy-1;j++)
{
//由于模板的原因,除去边缘几列
for(i=1;i<lLineBytes-1;i++)
{
iTemp=0;
fTemp1=0;
fTemp2=0;
fTemp3=1;
//中心点及周围灰度的总值
iTemp=(float)(lpNewDIB[(j-1)*lLineBytes+i-1]+2*lpNewDIB[(j-1)*lLineBytes+i]+lpNewDIB[(j-1)*lLineBytes+i+1]+
2*lpNewDIB[(j)*lLineBytes+i-1]+4*lpNewDIB[(j)*lLineBytes+i]+2*lpNewDIB[(j)*lLineBytes+i+1]+
lpNewDIB[(j+1)*lLineBytes+i-1]+2*lpNewDIB[(j+1)*lLineBytes+i]+lpNewDIB[(j+1)*lLineBytes+i+1]);
y0=(float)iTemp/16;
while(fTemp3>fTempBorderValue)
{
//计算模糊隶属度
for(y=0;y<3;y++)
{
for(x=0;x<3;x++)
{
fTemp[y*3+x]=(float)exp(-pow(lpBits[(j-1+y)*lLineBytes+i-1+x]-y0,2)/iTempDimensionValue);
fTemp2+=fTemp[y*3+x];
}
}
for(y=0;y<3;y++)
{
for(x=0;x<3;x++)
{
fTemp1+=fTemp[y*3+x]*lpBits[(j-1+y)*lLineBytes+i-1+x];
}
}
y1=fTemp1/fTemp2;
fTemp3=y1-y0;
if(fTemp3<0)
fTemp3=-fTemp3;
y0=fTemp1/fTemp2;
}
lpBits[j*lLineBytes+i]=(int)(0.5+fTemp1/fTemp2);
}
}
}
/****************************用于计算峰值信噪比*********************************/
FPSNRTemp=0.0;
for(j=0;j<m_size.cy;j++)
{
for(i=0;i<lLineBytes;i++)
{
FPSNRTemp+=pow((double)(lpBits[j*lLineBytes+i]-lpTemp1DIB[j*lLineBytes+i]),2)/(m_size.cy*lLineBytes);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -