?? restore.cpp
字號:
}
}
//釋放存儲空間
delete pCTSrc;
delete pCTH;
delete pCFSrc;
delete pCFH;
// 返回
return true;
}
/*************************************************************************
*
* 函數名稱:
* DIBWinnerFilter()
*
* 參數:
* CDib *pDib - 指向CDib類的指針
*
* 返回值:
* BOOL - 維納濾波復原操作成功返回TRUE,否則返回FALSE。
*
* 說明:
* 該函數用來對DIB圖像進行維納濾波復原操作。
*
************************************************************************/
BOOL WINAPI DIBWinnerFilter (CDib *pDib)
{
// 指向源圖像的指針
BYTE * lpSrc;
//圖象的寬度和高度
LONG lWidth;
LONG lHeight;
// 圖像每行的字節數
LONG lLineBytes;
//得到圖象的寬度和高度
CSize SizeDim;
SizeDim = pDib->GetDimensions();
lWidth = SizeDim.cx;
lHeight = SizeDim.cy;
//得到實際的Dib圖象存儲大小
CSize SizeRealDim;
SizeRealDim = pDib->GetDibSaveDim();
// 計算圖像每行的字節數
lLineBytes = SizeRealDim.cx;
//圖像數據的指針
LPBYTE lpDIBBits = pDib->m_lpImage;
//循環變量
long i;
long j;
//臨時變量
double temp, tempre, tempim,
a, b, c, d, norm2;
// 實際進行付立葉變換的寬度和高度
LONG lW = 1;
LONG lH = 1;
int wp = 0;
int hp = 0;
// 保證離散傅立葉變換的寬度和高度為2的整數次方
while(lW * 2 <= lLineBytes)
{
lW = lW * 2;
wp++;
}
while(lH * 2 <= lHeight)
{
lH = lH * 2;
hp++;
}
//用來存儲源圖象和變換核的時域數據
complex<double> *pCTSrc,*pCTH;
//用來存儲源圖象和變換核的頻域數據
complex<double> *pCFSrc,*pCFH;
//輸入退化圖象的長和寬必須為2的整數倍
if(lW != (int) lLineBytes)
{
return false;
}
if(lH != (int) lHeight)
{
return false;
}
// 為時域和頻域的數組分配空間
pCTSrc = new complex<double> [lHeight*lLineBytes];
pCTH = new complex<double> [lHeight*lLineBytes];
pCFSrc = new complex<double> [lHeight*lLineBytes];
pCFH = new complex<double> [lHeight*lLineBytes];
// 濾波器加權系數
double *pCFFilter = new double [lHeight*lLineBytes];
for (j = 0;j < lHeight ;j++)
{
for(i = 0;i < lLineBytes ;i++)
{
// 指向退化圖像倒數第j行,第i個象素的指針
lpSrc = (unsigned char *)lpDIBBits + lLineBytes * j + i;
// 將象素值存儲到時域數組中
pCTSrc[ lLineBytes*j + i ] = complex<double>((double)*lpSrc , 0);
// 頻域賦零值
pCFSrc[ lLineBytes*j + i ] = complex<double>(0.0 , 0.0);
// 退化系統時域及維納濾波加權系數賦值
if(i < 5 && j <5)
{
pCTH[ lLineBytes*j + i ] = complex<double>(0.04 , 0.0);
pCFFilter[ lLineBytes*j + i ] = 0.5;
}
else
{
pCTH[ lLineBytes*j + i ] = complex<double>(0.0 , 0.0);
pCFFilter[ lLineBytes*j + i ] = 0.05;
}
// 頻域賦零值
pCFH[ lLineBytes*j + i ] = complex<double>(0.0 , 0.0);
}
}
//對退化圖像進行FFT
::DIBFFT_2D(pCTSrc, lLineBytes, lHeight, pCFSrc);
//對變換核圖像進行FFT
::DIBFFT_2D(pCTH, lLineBytes, lHeight, pCFH);
// 計算M
for (i = 0; i < lHeight * lLineBytes; i++)
{
// 賦值
a = pCFSrc[i].real();
b = pCFSrc[i].imag();
c = pCFH[i].real();
d = pCFH[i].imag();
// |H(u,v)|*|H(u,v)|
norm2 = c * c + d * d;
// |H(u,v)|*|H(u,v)|/(|H(u,v)|*|H(u,v)|+a)
temp = (norm2 ) / (norm2 + pCFFilter[i]);
{
tempre = ( a*c + b*d ) / ( c*c + d*d );
tempim = ( b*c - a*d ) / ( c*c + d*d );
// 求得f(u,v)
pCFSrc[i]= complex<double>(temp*tempre , temp*tempim);
}
}
//對復原圖像進行反FFT
IFFT_2D(pCFSrc, pCTSrc, lLineBytes, lHeight);
//轉換為復原圖像
for (j = 0;j < lHeight ;j++)
{
for(i = 0;i < lLineBytes ;i++)
{
// 指向復原圖像倒數第j行,第i個象素的指針
lpSrc = (unsigned char *)lpDIBBits + lLineBytes * j + i;
a = pCTSrc[(lLineBytes)*j + i].real();
b = pCTSrc[(lLineBytes)*j + i].imag();
norm2 = a*a + b*b;
norm2 = sqrt(norm2) + 40;
if(norm2 > 255)
norm2 = 255.0;
if(norm2 < 0)
norm2 = 0;
*lpSrc = (unsigned char) (norm2);
}
}
//釋放存儲空間
delete pCTSrc;
delete pCTH;
delete pCFSrc;
delete pCFH;
delete pCFFilter;
// 返回
return true;
}
/*************************************************************************
*
* 函數名稱:
* DIBMotionDegeneration()
*
* 參數:
* CDib *pDib - 指向CDib類的指針
*
* 返回值:
* BOOL - 成功返回TRUE,否則返回FALSE。
*
* 說明:
* 該函數用來對DIB圖像模擬由勻速直線運動造成的模糊
*
***********************************************************************
*/
BOOL WINAPI DIBMotionDegeneration(CDib *pDib)
{
// 指向源圖像的指針
BYTE * lpSrc;
//圖象的寬度和高度
LONG lWidth;
LONG lHeight;
// 圖像每行的字節數
LONG lLineBytes;
//得到圖象的寬度和高度
CSize SizeDim;
SizeDim = pDib->GetDimensions();
lWidth = SizeDim.cx;
lHeight = SizeDim.cy;
//得到實際的Dib圖象存儲大小
CSize SizeRealDim;
SizeRealDim = pDib->GetDibSaveDim();
// 計算圖像每行的字節數
lLineBytes = SizeRealDim.cx;
//圖像數據的指針
LPBYTE lpDIBBits = pDib->m_lpImage;
//循環變量
long iColumn;
long jRow;
//臨時變量
int temp,m;
// 臨時變量
double p,q;
int nTotTime, nTotLen, nTime;
//總的運動時間10s
nTotTime = 10;
// 總的運動距離10個象素點
nTotLen = 10;
// 攝像機的暴光系數
double B;
B = 0.1;
//用來存儲源圖象和變換核的時域數據
int *nImageDegener;
// 為時域和頻域的數組分配空間
nImageDegener = new int [lHeight*lLineBytes];
// 將數據存入時域數組
for (jRow = 0; jRow < lHeight; jRow++)
{
for(iColumn = 0; iColumn < lLineBytes; iColumn++)
{
temp=0;
// 指向源圖像倒數第jRow行,第iColumn個象素的指針
lpSrc = (unsigned char *)lpDIBBits + lLineBytes * jRow + iColumn;
// 象素點的象素值積累
for ( nTime = 0; nTime < nTotTime; nTime++ )
{
p = (float)iColumn - (float)(nTotLen)*nTime/nTotTime;
if (p > 0)
{
q = p - floor((double)p);
if(q >= 0.5)
m = (int)ceil((double)p);
else
m = (int)floor((double)p);
// 累加
lpSrc = (unsigned char *)lpDIBBits + lLineBytes * jRow + m;
temp = temp + *lpSrc;
}
}
// 乘以攝像機的暴光系數
temp = B * temp;
temp=(int)ceil((double)temp);
// 使得temp的取值符合取值范圍
if(temp<0)
temp=0;
if(temp>255)
temp=255;
nImageDegener[lLineBytes*jRow + iColumn] = temp;
}
}
//轉換為圖像
for (jRow = 0;jRow < lHeight ;jRow++)
{
for(iColumn = 0;iColumn < lLineBytes ;iColumn++)
{
// 指向源圖像倒數第jRow行,第iColumn個象素的指針
lpSrc = (unsigned char *)lpDIBBits + lLineBytes * jRow + iColumn;
*lpSrc = nImageDegener[lLineBytes*jRow + iColumn];
}
}
//釋放存儲空間
delete nImageDegener;
// 返回
return true;
}
/*************************************************************************
*
* 函數名稱:
* DIBMotionRestore()
*
* 參數:
* CDib *pDib - 指向CDib類的指針
*
* 返回值:
* BOOL - 成功返回TRUE,否則返回FALSE。
*
* 說明:
* 該函數用來對擬由勻速直線運動造成的模糊圖象進行復原
*
***********************************************************************
*/
BOOL WINAPI DIBMotionRestore(CDib *pDib)
{
// 指向源圖像的指針
BYTE * lpSrc;
//圖象的寬度和高度
LONG lWidth;
LONG lHeight;
// 圖像每行的字節數
LONG lLineBytes;
//得到圖象的寬度和高度
CSize SizeDim;
SizeDim = pDib->GetDimensions();
lWidth = SizeDim.cx;
lHeight = SizeDim.cy;
//得到實際的Dib圖象存儲大小
CSize SizeRealDim;
SizeRealDim = pDib->GetDibSaveDim();
// 計算圖像每行的字節數
lLineBytes = SizeRealDim.cx;
//圖像數據的指針
LPBYTE lpDIBBits = pDib->m_lpImage;
//循環變量
long iColumn;
long jRow;
int i,n,m;
//臨時變量
int temp1,temp2,
totalq,q1,q2,z;
double p,q;
// 常量A賦值
int A = 80;
//常量B賦值
int B = 10;
//總的移動距離
int nTotLen=10;
// 圖象寬度包含多少個ntotlen
int K=lLineBytes/nTotLen;
int error[10];
//用來存儲源圖象時域數據
int *nImageDegener;
// 為時域數組分配空間
nImageDegener = new int [lHeight*lLineBytes];
// 將象素存入數組中
for (jRow = 0; jRow < lHeight; jRow++)
{
for(iColumn = 0; iColumn < lLineBytes; iColumn++)
{
lpSrc = (unsigned char *)lpDIBBits + lLineBytes * jRow + iColumn;
nImageDegener[lLineBytes*jRow + iColumn] = (*lpSrc);
}
}
for (jRow = 0; jRow < lHeight; jRow++)
{
// 計算error[i]
for(i = 0; i < 10; i++)
{
error[i] = 0;
for(n = 0; n < K; n++)
for(m = 0; m <= n; m++)
{
// 象素是否為一行的開始處
if(i == 0 && m == 0)
{
temp1=temp2=0;
}
// 進行差分運算
else
{
lpSrc = (unsigned char *)lpDIBBits + lLineBytes * jRow + m*10+i;
temp1=*lpSrc;
lpSrc = (unsigned char *)lpDIBBits + lLineBytes * jRow + m*10+i-1;
temp2 = *lpSrc;
}
error[i] = error[i] + temp1 - temp2;
}
error[i] = B * error[i] / K;
}
for(iColumn = 0; iColumn < lLineBytes; iColumn++)
{
// 計算m,以及z
m = iColumn / nTotLen;
z = iColumn - m*nTotLen;
// 初始化
totalq = 0;
q = 0;
for(n = 0; n <= m; n++)
{
q1 = iColumn - nTotLen*n;
if(q1 == 0)
q = 0;
// 進行差分運算
else
{
q2 = q1 - 1;
lpSrc = (unsigned char *)lpDIBBits + lLineBytes * jRow + q1;
temp1 = *lpSrc;
lpSrc = (unsigned char *)lpDIBBits + lLineBytes * jRow + q2;
temp2 = *lpSrc;
q = (temp1 - temp2) * B;
}
totalq = totalq + q;
}
p = error[z];
// 得到f(x,y)的值
temp1 = totalq + A - p;
// 使得象素的取值符合取值范圍
if(temp1 < 0)
temp1 = 0;
if(temp1 > 255)
temp1 = 255;
nImageDegener[lLineBytes*jRow + iColumn] = temp1;
}
}
//轉換為圖像
for (jRow = 0;jRow < lHeight ;jRow++)
{
for(iColumn = 0;iColumn < lLineBytes ;iColumn++)
{
// 指向源圖像倒數第jRow行,第iColumn個象素的指針
lpSrc = (unsigned char *)lpDIBBits + lLineBytes * jRow + iColumn;
// 存儲象素值
*lpSrc = nImageDegener[lLineBytes*jRow + iColumn];
}
}
//釋放存儲空間
delete nImageDegener;
// 返回
return true;
}
#undef SWAP
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -