?? restore.cpp
字號:
// ************************************************************************
// 文件名:restore.cpp
//
// 圖像復原API函數庫:
//
// BlurDIB() - 圖像模糊
// InverseDIB() - 圖像逆濾波
// NoiseBlurDIB() - 圖像模糊加噪
// WienerDIB() - 圖像維納濾波
// RandomNoiseDIB() - 圖像中加入隨機噪聲
// SaltNoiseDIB() - 圖像中加入椒鹽噪聲
// fourn() - n維FFT
//
// *************************************************************************
#include "stdafx.h"
#include "restore.h"
#include "DIBAPI.h"
#include <math.h>
#include <direct.h>
#define SWAP(a,b) tempr=(a);(a)=(b);(b)=tempr
/*************************************************************************
*
* 函數名稱:
* BlurDIB()
*
* 參數:
* LPSTR lpDIBBits - 指向源DIB圖像指針
* LONG lWidth - 源圖像寬度(象素數,必須是4的倍數)
* LONG lHeight - 源圖像高度(象素數)
*
* 返回值:
* BOOL - 平移成功返回TRUE,否則返回FALSE。
*
* 說明:
* 該函數用來對DIB圖像進行模糊操作。
*
************************************************************************/
BOOL WINAPI BlurDIB (LPSTR lpDIBBits, LONG lWidth, LONG lHeight)
{
// 指向源圖像的指針
LPSTR lpSrc;
//循環變量
long i;
long j;
//像素值
unsigned char pixel;
// 圖像每行的字節數
LONG lLineBytes;
//用于做FFT的數組
double *fftSrc,*fftKernel;
//二維FFT的長度和寬度
unsigned long nn[3];
//圖像歸一化因子
double MaxNum;
// 計算圖像每行的字節數
lLineBytes = WIDTHBYTES(lWidth * 8);
double dPower = log((double)lLineBytes)/log(2.0);
if(dPower != (int) dPower)
{
return false;
}
dPower = log((double)lHeight)/log(2.0);
if(dPower != (int) dPower)
{
return false;
}
fftSrc = new double [lHeight*lLineBytes*2+1];
fftKernel = new double [lHeight*lLineBytes*2+1];
nn[1] = lHeight;
nn[2] = lLineBytes;
for (j = 0;j < lHeight ;j++)
{
for(i = 0;i < lLineBytes ;i++)
{
// 指向源圖像倒數第j行,第i個象素的指針
lpSrc = (char *)lpDIBBits + lLineBytes * j + i;
pixel = (unsigned char)*lpSrc;
fftSrc[(2*lLineBytes)*j + 2*i + 1] = (double)pixel;
fftSrc[(2*lLineBytes)*j + 2*i + 2] = 0.0;
if(i < 5 && j < 5)
{
fftKernel[(2*lLineBytes)*j + 2*i + 1] = 1/25.0;
}
else
{
fftKernel[(2*lLineBytes)*j + 2*i + 1] = 0.0;
}
fftKernel[(2*lLineBytes)*j + 2*i + 2] = 0.0;
}
}
//對源圖像進行FFT
fourn(fftSrc,nn,2,1);
//對卷積核圖像進行FFT
fourn(fftKernel,nn,2,1);
//頻域相乘
for (i = 1;i <lHeight*lLineBytes*2;i+=2)
{
fftSrc[i] = fftSrc[i] * fftKernel[i] - fftSrc[i+1] * fftKernel[i+1];
fftSrc[i+1] = fftSrc[i] * fftKernel[i+1] + fftSrc[i+1] * fftKernel[i];
}
//對結果圖像進行反FFT
fourn(fftSrc,nn,2,-1);
//確定歸一化因子
MaxNum = 0.0;
for (j = 0;j < lHeight ;j++)
{
for(i = 0;i < lLineBytes ;i++)
{
fftSrc[(2*lLineBytes)*j + 2*i + 1] =
sqrt(fftSrc[(2*lLineBytes)*j + 2*i + 1] * fftSrc[(2*lLineBytes)*j + 2*i + 1]\
+fftSrc[(2*lLineBytes)*j + 2*i + 2] * fftSrc[(2*lLineBytes)*j + 2*i + 2]);
if( MaxNum < fftSrc[(2*lLineBytes)*j + 2*i + 1])
MaxNum = fftSrc[(2*lLineBytes)*j + 2*i + 1];
}
}
//轉換為圖像
for (j = 0;j < lHeight ;j++)
{
for(i = 0;i < lLineBytes ;i++)
{
// 指向源圖像倒數第j行,第i個象素的指針
lpSrc = (char *)lpDIBBits + lLineBytes * j + i;
*lpSrc = (unsigned char) (fftSrc[(2*lLineBytes)*j + 2*i + 1]*255.0/MaxNum);
}
}
delete fftSrc;
delete fftKernel;
// 返回
return true;
}
/*************************************************************************
*
* 函數名稱:
* RestoreDIB()
*
* 參數:
* LPSTR lpDIBBits - 指向源DIB圖像指針
* LONG lWidth - 源圖像寬度(象素數,必須是4的倍數)
* LONG lHeight - 源圖像高度(象素數)
*
* 返回值:
* BOOL - 平移成功返回TRUE,否則返回FALSE。
*
* 說明:
* 該函數用來對BlurDIB()生成的DIB圖像進行復原操作。
*
************************************************************************/
BOOL WINAPI RestoreDIB (LPSTR lpDIBBits, LONG lWidth, LONG lHeight)
{
// 指向源圖像的指針
LPSTR lpSrc;
//循環變量
long i;
long j;
//像素值
unsigned char pixel;
// 圖像每行的字節數
LONG lLineBytes;
//用于做FFT的數組
double *fftSrc,*fftKernel;
double a,b,c,d;
//二維FFT的長度和寬度
unsigned long nn[3];
//圖像歸一化因子
double MaxNum;
// 計算圖像每行的字節數
lLineBytes = WIDTHBYTES(lWidth * 8);
double dPower = log((double)lLineBytes)/log(2.0);
if(dPower != (int) dPower)
{
return false;
}
dPower = log((double)lHeight)/log(2.0);
if(dPower != (int) dPower)
{
return false;
}
fftSrc = new double [lHeight*lLineBytes*2+1];
fftKernel = new double [lHeight*lLineBytes*2+1];
nn[1] = lHeight;
nn[2] = lLineBytes;
for (j = 0;j < lHeight ;j++)
{
for(i = 0;i < lLineBytes ;i++)
{
// 指向源圖像倒數第j行,第i個象素的指針
lpSrc = (char *)lpDIBBits + lLineBytes * j + i;
pixel = (unsigned char)*lpSrc;
fftSrc[(2*lLineBytes)*j + 2*i + 1] = (double)pixel;
fftSrc[(2*lLineBytes)*j + 2*i + 2] = 0.0;
if(i < 5 && j == 0)
{
fftKernel[(2*lLineBytes)*j + 2*i + 1] = 1/5.0;
}
else
{
fftKernel[(2*lLineBytes)*j + 2*i + 1] = 0.0;
}
fftKernel[(2*lLineBytes)*j + 2*i + 2] = 0.0;
}
}
//對源圖像進行FFT
fourn(fftSrc,nn,2,1);
//對卷積核圖像進行FFT
fourn(fftKernel,nn,2,1);
for (j = 0;j < lHeight ;j++)
{
for(i = 0;i < lLineBytes ;i++)
{
a = fftSrc[(2*lLineBytes)*j + 2*i + 1];
b = fftSrc[(2*lLineBytes)*j + 2*i + 2];
c = fftKernel[(2*lLineBytes)*j + 2*i + 1];
d = fftKernel[(2*lLineBytes)*j + 2*i + 2];
if (c*c + d*d > 1e-3)
{
fftSrc[(2*lLineBytes)*j + 2*i + 1] = ( a*c + b*d ) / ( c*c + d*d );
fftSrc[(2*lLineBytes)*j + 2*i + 2] = ( b*c - a*d ) / ( c*c + d*d );
}
}
}
//對結果圖像進行反FFT
fourn(fftSrc,nn,2,-1);
//確定歸一化因子
MaxNum = 0.0;
for (j = 0;j < lHeight ;j++)
{
for(i = 0;i < lLineBytes ;i++)
{
fftSrc[(2*lLineBytes)*j + 2*i + 1] =
sqrt(fftSrc[(2*lLineBytes)*j + 2*i + 1] * fftSrc[(2*lLineBytes)*j + 2*i + 1]\
+fftSrc[(2*lLineBytes)*j + 2*i + 2] * fftSrc[(2*lLineBytes)*j + 2*i + 2]);
if( MaxNum < fftSrc[(2*lLineBytes)*j + 2*i + 1])
MaxNum = fftSrc[(2*lLineBytes)*j + 2*i + 1];
}
}
//轉換為圖像
for (j = 0;j < lHeight ;j++)
{
for(i = 0;i < lLineBytes ;i++)
{
// 指向源圖像倒數第j行,第i個象素的指針
lpSrc = (char *)lpDIBBits + lLineBytes * j + i;
*lpSrc = (unsigned char) (fftSrc[(2*lLineBytes)*j + 2*i + 1]*255.0/MaxNum);
}
}
delete fftSrc;
delete fftKernel;
// 返回
return true;
}
/*************************************************************************
*
* 函數名稱:
* NoiseBlurDIB()
*
* 參數:
* LPSTR lpDIBBits - 指向源DIB圖像指針
* LONG lWidth - 源圖像寬度(象素數)
* LONG lHeight - 源圖像高度(象素數)
*
* 返回值:
* BOOL - 模糊加噪操作成功返回TRUE,否則返回FALSE。
*
* 說明:
* 該函數用來對DIB圖像進行模糊加噪操作。
*
************************************************************************/
BOOL WINAPI NoiseBlurDIB (LPSTR lpDIBBits, LONG lWidth, LONG lHeight)
{
// 指向源圖像的指針
LPSTR lpSrc;
//循環變量
long i;
long j;
//像素值
unsigned char pixel;
// 圖像每行的字節數
LONG lLineBytes;
//用于做FFT的數組
double *fftSrc,*fftKernel;
//二維FFT的長度和寬度
unsigned long nn[3];
//圖像歸一化因子
double MaxNum;
// 計算圖像每行的字節數
lLineBytes = WIDTHBYTES(lWidth * 8);
double dPower = log((double)lLineBytes)/log(2.0);
if(dPower != (int) dPower)
{
return false;
}
dPower = log((double)lHeight)/log(2.0);
if(dPower != (int) dPower)
{
return false;
}
fftSrc = new double [lHeight*lLineBytes*2+1];
fftKernel = new double [lHeight*lLineBytes*2+1];
nn[1] = lHeight;
nn[2] = lLineBytes;
for (j = 0;j < lHeight ;j++)
{
for(i = 0;i < lLineBytes ;i++)
{
// 指向源圖像倒數第j行,第i個象素的指針
lpSrc = (char *)lpDIBBits + lLineBytes * j + i;
pixel = (unsigned char)*lpSrc;
fftSrc[(2*lLineBytes)*j + 2*i + 1] = (double)pixel;
fftSrc[(2*lLineBytes)*j + 2*i + 2] = 0.0;
if(i < 5 && j == 0)
{
fftKernel[(2*lLineBytes)*j + 2*i + 1] = 1/5.0;
}
else
{
fftKernel[(2*lLineBytes)*j + 2*i + 1] = 0.0;
}
fftKernel[(2*lLineBytes)*j + 2*i + 2] = 0.0;
}
}
//對源圖像進行FFT
fourn(fftSrc,nn,2,1);
//對卷積核圖像進行FFT
fourn(fftKernel,nn,2,1);
//頻域相乘
for (i = 1;i <lHeight*lLineBytes*2;i+=2)
{
fftSrc[i] = fftSrc[i] * fftKernel[i] - fftSrc[i+1] * fftKernel[i+1];
fftSrc[i+1] = fftSrc[i] * fftKernel[i+1] + fftSrc[i+1] * fftKernel[i];
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -