?? restore.cpp
字號(hào):
// ************************************************************************
// 文件名:restore.cpp
//
// 圖像復(fù)原API函數(shù)庫(kù):
//
// DIBNoRestriction() - 圖像模糊
// DIBInverseFilter() - 圖像逆濾波復(fù)原
// DIBNoiseDegeneration() - 圖像模糊加噪
// DIBWinnerFilter() - 圖像維納濾波
// DIBMotionDegeneration() - 圖像運(yùn)動(dòng)模糊
// DIBMotionRestore() - 圖像運(yùn)動(dòng)模糊復(fù)原
//
// *************************************************************************
#include "stdafx.h"
#include "GlobalApi.h"
#include "Cdib.h"
#include <math.h>
#include <direct.h>
#include <complex>
using namespace std;
#define SWAP(a,b) tempr=(a);(a)=(b);(b)=tempr
/*************************************************************************
*
* 函數(shù)名稱:
* DIBNoRestriction()
*
* 參數(shù):
* CDib *pDib - 指向CDib類的指針
*
* 返回值:
* BOOL - 成功返回TRUE,否則返回FALSE。
*
* 說明:
* 該函數(shù)用來對(duì)DIB圖像進(jìn)行模糊操作。
*
************************************************************************/
BOOL WINAPI DIBNoRestriction(CDib *pDib)
{
// 指向源圖像的指針
BYTE * lpSrc;
//圖象的寬度和高度
LONG lWidth;
LONG lHeight;
// 圖像每行的字節(jié)數(shù)
LONG lLineBytes;
//得到圖象的寬度和高度
CSize SizeDim;
SizeDim = pDib->GetDimensions();
lWidth = SizeDim.cx;
lHeight = SizeDim.cy;
//得到實(shí)際的Dib圖象存儲(chǔ)大小
CSize SizeRealDim;
SizeRealDim = pDib->GetDibSaveDim();
// 計(jì)算圖像每行的字節(jié)數(shù)
lLineBytes = SizeRealDim.cx;
//圖像數(shù)據(jù)的指針
LPBYTE lpDIBBits = pDib->m_lpImage;
//循環(huán)變量
long i;
long j;
//臨時(shí)變量
double temp;
// 實(shí)際進(jìn)行付立葉變換的寬度和高度
LONG lW = 1;
LONG lH = 1;
int wp = 0;
int hp = 0;
// 保證離散傅立葉變換的寬度和高度為2的整數(shù)次方
while(lW * 2 <= lLineBytes)
{
lW = lW * 2;
wp++;
}
while(lH * 2 <= lHeight)
{
lH = lH * 2;
hp++;
}
//用來存儲(chǔ)源圖象和變換核的時(shí)域數(shù)據(jù)
complex<double> *pCTSrc,*pCTH;
//用來存儲(chǔ)源圖象和變換核的頻域數(shù)據(jù)
complex<double> *pCFSrc,*pCFH;
//圖像歸一化因子
double MaxNum;
//輸入圖象的長(zhǎng)和寬必須為2的整數(shù)倍
if(lW != (int) lLineBytes)
{
return false;
}
if(lH != (int) lHeight)
{
return false;
}
// 為時(shí)域和頻域的數(shù)組分配空間
pCTSrc = new complex<double> [lHeight*lLineBytes];
pCTH = new complex<double> [lHeight*lLineBytes];
pCFSrc = new complex<double> [lHeight*lLineBytes];
pCFH = new complex<double> [lHeight*lLineBytes];
// 將數(shù)據(jù)存入時(shí)域數(shù)組
for (j = 0; j < lHeight; j++)
{
for(i = 0; i < lLineBytes; i++)
{
// 指向源圖像倒數(shù)第j行,第i個(gè)象素的指針
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);
}
else
{
pCTH[ lLineBytes*j + i ] = complex<double>(0.0 , 0.0);
}
pCFH[ lLineBytes*j + i ] = complex<double>(0.0 , 0.0);
}
}
//對(duì)源圖像進(jìn)行FFT
::DIBFFT_2D(pCTSrc, lLineBytes, lHeight, pCFSrc);
//對(duì)變換核圖像進(jìn)行FFT
::DIBFFT_2D(pCTH, lLineBytes, lHeight, pCFH);
//頻域相乘
for (i = 0;i <lHeight*lLineBytes;i++)
{
pCFSrc[i] = pCFSrc[i]*pCFH[i];
}
//對(duì)結(jié)果圖像進(jìn)行反FFT
IFFT_2D(pCFSrc, pCTSrc, lLineBytes, lHeight);
//確定歸一化因子
MaxNum = 0.0;
for (j = 0;j < lHeight ;j++)
{
for(i = 0;i < lLineBytes ;i++)
{
temp = sqrt(pCTSrc[ lLineBytes*j + i ].real() * pCTSrc[ lLineBytes*j + i ].real()
+pCTSrc[lLineBytes*j + i ].imag() * pCTSrc[ lLineBytes*j +i].imag());
//選擇歸一化因子
if( MaxNum < temp)
MaxNum = temp;
}
}
//轉(zhuǎn)換為圖像
for (j = 0;j < lHeight ;j++)
{
for(i = 0;i < lLineBytes ;i++)
{
// 指向源圖像倒數(shù)第j行,第i個(gè)象素的指針
lpSrc = (unsigned char *)lpDIBBits + lLineBytes * j + i;
*lpSrc = (unsigned char) (pCTSrc[(lLineBytes)*j + i].real()*255.0/MaxNum);
}
}
//釋放存儲(chǔ)空間
delete pCTSrc;
delete pCTH;
delete pCFSrc;
delete pCFH;
// 返回
return true;
}
/*************************************************************************
*
* 函數(shù)名稱:
* DIBInverseFilter()
*
* 參數(shù):
* CDib *pDib - 指向CDib類的指針
*
* 返回值:
* BOOL - 成功返回TRUE,否則返回FALSE
*
* 說明:
* 該函數(shù)用來對(duì)DIBNoRestriction()生成的DIB圖像進(jìn)行復(fù)原操作。
*
************************************************************************/
BOOL WINAPI DIBInverseFilter (CDib *pDib)
{
// 指向源圖像的指針
BYTE * lpSrc;
//圖象的寬度和高度
LONG lWidth;
LONG lHeight;
// 圖像每行的字節(jié)數(shù)
LONG lLineBytes;
//得到圖象的寬度和高度
CSize SizeDim;
SizeDim = pDib->GetDimensions();
lWidth = SizeDim.cx;
lHeight = SizeDim.cy;
//得到實(shí)際的Dib圖象存儲(chǔ)大小
CSize SizeRealDim;
SizeRealDim = pDib->GetDibSaveDim();
// 計(jì)算圖像每行的字節(jié)數(shù)
lLineBytes = SizeRealDim.cx;
//圖像數(shù)據(jù)的指針
LPBYTE lpDIBBits = pDib->m_lpImage;
//循環(huán)變量
long i;
long j;
//臨時(shí)變量
double tempre, tempim, a, b, c, d;
// 實(shí)際進(jìn)行付立葉變換的寬度和高度
LONG lW = 1;
LONG lH = 1;
int wp = 0;
int hp = 0;
// 保證離散傅立葉變換的寬度和高度為2的整數(shù)次方
while(lW * 2 <= lLineBytes)
{
lW = lW * 2;
wp++;
}
while(lH * 2 <= lHeight)
{
lH = lH * 2;
hp++;
}
//用來存儲(chǔ)源圖象和變換核的時(shí)域數(shù)據(jù)
complex<double> *pCTSrc,*pCTH;
//用來存儲(chǔ)源圖象和變換核的頻域數(shù)據(jù)
complex<double> *pCFSrc,*pCFH;
//圖像歸一化因子
double MaxNum;
//輸入退化圖象的長(zhǎng)和寬必須為2的整數(shù)倍
if(lW != (int) lLineBytes)
{
return false;
}
if(lH != (int) lHeight)
{
return false;
}
// 為時(shí)域和頻域的數(shù)組分配空間
pCTSrc = new complex<double> [lHeight*lLineBytes];
pCTH = new complex<double> [lHeight*lLineBytes];
pCFSrc = new complex<double> [lHeight*lLineBytes];
pCFH = new complex<double> [lHeight*lLineBytes];
// 將退化圖象數(shù)據(jù)存入時(shí)域數(shù)組
for (j = 0; j < lHeight; j++)
{
for(i = 0; i < lLineBytes; i++)
{
// 指向退化圖像倒數(shù)第j行,第i個(gè)象素的指針
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);
}
else
{
pCTH[ lLineBytes*j + i ] = complex<double>(0.0 , 0.0);
}
pCFH[ lLineBytes*j + i ] = complex<double>(0.0 , 0.0);
}
}
//對(duì)退化圖像進(jìn)行FFT
::DIBFFT_2D(pCTSrc, lLineBytes, lHeight, pCFSrc);
//對(duì)變換核圖像進(jìn)行FFT
::DIBFFT_2D(pCTH, lLineBytes, lHeight, pCFH);
//頻域相除
for (i = 0;i <lHeight*lLineBytes;i++)
{
a = pCFSrc[i].real();
b = pCFSrc[i].imag();
c = pCFH[i].real();
d = pCFH[i].imag();
//如果頻域值太小,不予考慮
if (c*c + d*d > 1e-3)
{
tempre = ( a*c + b*d ) / ( c*c + d*d );
tempim = ( b*c - a*d ) / ( c*c + d*d );
}
pCFSrc[i]= complex<double>(tempre , tempim);
}
//對(duì)復(fù)原圖像進(jìn)行反FFT
IFFT_2D(pCFSrc, pCTSrc, lLineBytes, lHeight);
//確定歸一化因子
MaxNum=300;
//轉(zhuǎn)換為復(fù)原圖像
for (j = 0;j < lHeight ;j++)
{
for(i = 0;i < lLineBytes ;i++)
{
// 指向復(fù)原圖像倒數(shù)第j行,第i個(gè)象素的指針
lpSrc = (unsigned char *)lpDIBBits + lLineBytes * j + i;
*lpSrc = (unsigned char) (pCTSrc[(lLineBytes)*j + i].real()*255.0/MaxNum);
}
}
//釋放存儲(chǔ)空間
delete pCTSrc;
delete pCTH;
delete pCFSrc;
delete pCFH;
// 返回
return true;
}
/*************************************************************************
*
* 函數(shù)名稱:
* DIBNoiseDegeneration()
*
* 參數(shù):
* CDib *pDib - 指向CDib類的指針
*
* 返回值:
* BOOL - 模糊加噪操作成功返回TRUE,否則返回FALSE。
*
* 說明:
* 該函數(shù)用來對(duì)DIB圖像進(jìn)行模糊加噪操作。
*
************************************************************************/
BOOL WINAPI DIBNoiseDegeneration (CDib *pDib)
{
// 指向源圖像的指針
BYTE * lpSrc;
//圖象的寬度和高度
LONG lWidth;
LONG lHeight;
// 圖像每行的字節(jié)數(shù)
LONG lLineBytes;
//得到圖象的寬度和高度
CSize SizeDim;
SizeDim = pDib->GetDimensions();
lWidth = SizeDim.cx;
lHeight = SizeDim.cy;
//得到實(shí)際的Dib圖象存儲(chǔ)大小
CSize SizeRealDim;
SizeRealDim = pDib->GetDibSaveDim();
// 計(jì)算圖像每行的字節(jié)數(shù)
lLineBytes = SizeRealDim.cx;
//圖像數(shù)據(jù)的指針
LPBYTE lpDIBBits = pDib->m_lpImage;
//循環(huán)變量
long i;
long j;
//轉(zhuǎn)換為圖像,加噪
unsigned char NoisePoint;
//臨時(shí)變量
double temp;
//圖像歸一化因子
double MaxNum;
// 實(shí)際進(jìn)行付立葉變換的寬度和高度
LONG lW = 1;
LONG lH = 1;
int wp = 0;
int hp = 0;
// 保證離散傅立葉變換的寬度和高度為2的整數(shù)次方
while(lW * 2 <= lLineBytes)
{
lW = lW * 2;
wp++;
}
while(lH * 2 <= lHeight)
{
lH = lH * 2;
hp++;
}
//用來存儲(chǔ)源圖象和變換核的時(shí)域數(shù)據(jù)
complex<double> *pCTSrc,*pCTH;
//用來存儲(chǔ)源圖象和變換核的頻域數(shù)據(jù)
complex<double> *pCFSrc,*pCFH;
// 為時(shí)域和頻域的數(shù)組分配空間
pCTSrc = new complex<double> [lHeight*lLineBytes];
pCTH = new complex<double> [lHeight*lLineBytes];
pCFSrc = new complex<double> [lHeight*lLineBytes];
pCFH = new complex<double> [lHeight*lLineBytes];
for (j = 0;j < lHeight ;j++)
{
for(i = 0;i < lLineBytes ;i++)
{
// 指向源圖像倒數(shù)第j行,第i個(gè)象素的指針
lpSrc = (unsigned char *)lpDIBBits + lLineBytes * j + i;
// 將象素值存儲(chǔ)到時(shí)域數(shù)組中
pCTSrc[ lLineBytes*j + i ] = complex<double>((double)*lpSrc , 0);
// 頻域賦零值
pCFSrc[ lLineBytes*j + i ] = complex<double>(0.0 , 0.0);
// 用來對(duì)圖象做退化的系統(tǒng)
if(i < 5 && j <5 )
{
pCTH[ lLineBytes*j + i ] = complex<double>(0.04 , 0.0);
}
else
{
pCTH[ lLineBytes*j + i ] = complex<double>(0.0 , 0.0);
}
// 頻域賦零值
pCFH[ lLineBytes*j + i ] = complex<double>(0.0 , 0.0);
}
}
//對(duì)源圖像進(jìn)行FFT
::DIBFFT_2D(pCTSrc, lLineBytes, lHeight, pCFSrc);
//對(duì)變換核圖像進(jìn)行FFT
::DIBFFT_2D(pCTH, lLineBytes, lHeight, pCFH);
//頻域相乘
for (i = 0;i <lHeight*lLineBytes;i++)
{
pCFSrc[i] = pCFSrc[i]*pCFH[i];
}
//對(duì)結(jié)果圖像進(jìn)行反FFT
IFFT_2D(pCFSrc, pCTSrc, lLineBytes, lHeight);
//確定歸一化因子
MaxNum = 0.0;
for (j = 0;j < lHeight ;j++)
{
for(i = 0;i < lLineBytes ;i++)
{
temp = sqrt(pCTSrc[ lLineBytes*j + i ].real() * pCTSrc[ lLineBytes*j + i ].real()
+pCTSrc[lLineBytes*j + i ].imag() * pCTSrc[ lLineBytes*j +i].imag());
//選擇歸一化因子
if( MaxNum < temp)
MaxNum = temp;
}
}
//生成偽隨機(jī)數(shù)種子
srand((unsigned)time(NULL));
//轉(zhuǎn)換為圖像,并加入偽隨機(jī)噪聲
for (j = 0;j < lHeight ;j++)
{
for(i = 0;i < lLineBytes ;i++)
{
// 產(chǎn)生的噪聲
NoisePoint = rand()/2048-8;
// 指向源圖像倒數(shù)第j行,第i個(gè)象素的指針
lpSrc = (unsigned char *)lpDIBBits + lLineBytes * j + i;
// 時(shí)域加噪,存儲(chǔ)象素值
*lpSrc = (unsigned char) (pCTSrc[(lLineBytes)*j + i].real()*255.0/MaxNum + NoisePoint);
//如果象素值過大,直接賦值255
if(*lpSrc > 255)
*lpSrc = 255 ;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -