?? restore.cpp
字號:
// ************************************************************************
// 文件名:restore.cpp
//
// 圖像復原API函數庫:
//
// DIBNoRestriction() - 圖像模糊
// DIBInverseFilter() - 圖像逆濾波復原
// DIBNoiseDegeneration() - 圖像模糊加噪
// DIBWinnerFilter() - 圖像維納濾波
// DIBMotionDegeneration() - 圖像運動模糊
// DIBMotionRestore() - 圖像運動模糊復原
//
// *************************************************************************
#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
/*************************************************************************
*
* 函數名稱:
* DIBNoRestriction()
*
* 參數:
* CDib *pDib - 指向CDib類的指針
*
* 返回值:
* BOOL - 成功返回TRUE,否則返回FALSE。
*
* 說明:
* 該函數用來對DIB圖像進行模糊操作。
*
************************************************************************/
BOOL WINAPI DIBNoRestriction(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;
// 實際進行付立葉變換的寬度和高度
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;
//圖像歸一化因子
double MaxNum;
//輸入圖象的長和寬必須為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];
// 將數據存入時域數組
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);
}
else
{
pCTH[ lLineBytes*j + i ] = complex<double>(0.0 , 0.0);
}
pCFH[ lLineBytes*j + i ] = complex<double>(0.0 , 0.0);
}
}
//對源圖像進行FFT
::DIBFFT_2D(pCTSrc, lLineBytes, lHeight, pCFSrc);
//對變換核圖像進行FFT
::DIBFFT_2D(pCTH, lLineBytes, lHeight, pCFH);
//頻域相乘
for (i = 0;i <lHeight*lLineBytes;i++)
{
pCFSrc[i] = pCFSrc[i]*pCFH[i];
}
//對結果圖像進行反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;
}
}
//轉換為圖像
for (j = 0;j < lHeight ;j++)
{
for(i = 0;i < lLineBytes ;i++)
{
// 指向源圖像倒數第j行,第i個象素的指針
lpSrc = (unsigned char *)lpDIBBits + lLineBytes * j + i;
*lpSrc = (unsigned char) (pCTSrc[(lLineBytes)*j + i].real()*255.0/MaxNum);
}
}
//釋放存儲空間
delete pCTSrc;
delete pCTH;
delete pCFSrc;
delete pCFH;
// 返回
return true;
}
/*************************************************************************
*
* 函數名稱:
* DIBInverseFilter()
*
* 參數:
* CDib *pDib - 指向CDib類的指針
*
* 返回值:
* BOOL - 成功返回TRUE,否則返回FALSE
*
* 說明:
* 該函數用來對DIBNoRestriction()生成的DIB圖像進行復原操作。
*
************************************************************************/
BOOL WINAPI DIBInverseFilter (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 tempre, tempim, a, b, c, d;
// 實際進行付立葉變換的寬度和高度
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;
//圖像歸一化因子
double MaxNum;
//輸入退化圖象的長和寬必須為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];
// 將退化圖象數據存入時域數組
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);
}
else
{
pCTH[ lLineBytes*j + i ] = complex<double>(0.0 , 0.0);
}
pCFH[ lLineBytes*j + i ] = complex<double>(0.0 , 0.0);
}
}
//對退化圖像進行FFT
::DIBFFT_2D(pCTSrc, lLineBytes, lHeight, pCFSrc);
//對變換核圖像進行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);
}
//對復原圖像進行反FFT
IFFT_2D(pCFSrc, pCTSrc, lLineBytes, lHeight);
//確定歸一化因子
MaxNum=300;
//轉換為復原圖像
for (j = 0;j < lHeight ;j++)
{
for(i = 0;i < lLineBytes ;i++)
{
// 指向復原圖像倒數第j行,第i個象素的指針
lpSrc = (unsigned char *)lpDIBBits + lLineBytes * j + i;
*lpSrc = (unsigned char) (pCTSrc[(lLineBytes)*j + i].real()*255.0/MaxNum);
}
}
//釋放存儲空間
delete pCTSrc;
delete pCTH;
delete pCFSrc;
delete pCFH;
// 返回
return true;
}
/*************************************************************************
*
* 函數名稱:
* DIBNoiseDegeneration()
*
* 參數:
* CDib *pDib - 指向CDib類的指針
*
* 返回值:
* BOOL - 模糊加噪操作成功返回TRUE,否則返回FALSE。
*
* 說明:
* 該函數用來對DIB圖像進行模糊加噪操作。
*
************************************************************************/
BOOL WINAPI DIBNoiseDegeneration (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;
//轉換為圖像,加噪
unsigned char NoisePoint;
//臨時變量
double temp;
//圖像歸一化因子
double MaxNum;
// 實際進行付立葉變換的寬度和高度
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;
// 為時域和頻域的數組分配空間
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++)
{
// 指向源圖像倒數第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);
}
else
{
pCTH[ lLineBytes*j + i ] = complex<double>(0.0 , 0.0);
}
// 頻域賦零值
pCFH[ lLineBytes*j + i ] = complex<double>(0.0 , 0.0);
}
}
//對源圖像進行FFT
::DIBFFT_2D(pCTSrc, lLineBytes, lHeight, pCFSrc);
//對變換核圖像進行FFT
::DIBFFT_2D(pCTH, lLineBytes, lHeight, pCFH);
//頻域相乘
for (i = 0;i <lHeight*lLineBytes;i++)
{
pCFSrc[i] = pCFSrc[i]*pCFH[i];
}
//對結果圖像進行反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;
}
}
//生成偽隨機數種子
srand((unsigned)time(NULL));
//轉換為圖像,并加入偽隨機噪聲
for (j = 0;j < lHeight ;j++)
{
for(i = 0;i < lLineBytes ;i++)
{
// 產生的噪聲
NoisePoint = rand()/2048-8;
// 指向源圖像倒數第j行,第i個象素的指針
lpSrc = (unsigned char *)lpDIBBits + lLineBytes * j + i;
// 時域加噪,存儲象素值
*lpSrc = (unsigned char) (pCTSrc[(lLineBytes)*j + i].real()*255.0/MaxNum + NoisePoint);
//如果象素值過大,直接賦值255
if(*lpSrc > 255)
*lpSrc = 255 ;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -