?? enhance.cpp
字號:
}
// 梯度值寫入內(nèi)存
*(pdGrad+y*nWidth+x)=dGrad;
}
for(y=0; y<nHeight ; y++ )
{
for(x=0 ; x<nWidth ; x++ )
{
lpImage[y*nWidth+x] = (unsigned char)max(0,min(255,(lpImage[y*nWidth+x] + (int)pdGrad[y*nWidth+x]) ));
}
}
delete []pdGrad ;
pdGrad = NULL ;
}
/*************************************************************************
*
* 函數(shù)名稱:
* ReplaceDIBColorTable()
*
* 參數(shù):
* CDib * pDib - 指向CDib類的指針,含有原始圖象信息
* LPBYTE pColorsTable - 偽彩色編碼表
*
* 返回值:
* BOOL - 成功返回TRUE,否則返回FALSE。
*
* 說明:
* 該函數(shù)用指定的偽彩色編碼表來替換指定的DIB圖像的顏色表,參數(shù)pColorsTable
* 指向要替換的偽彩色編碼表。
*
************************************************************************/
BOOL ReplaceDIBColorTable(CDib* pDib, LPBYTE pColorsTable)
{
// 循環(huán)變量
int i;
// 顏色表的表項數(shù)
int nColorEntries;
// 臨時變量
LPRGBQUAD pDibQuad;
// 指向DIB的顏色表
pDibQuad = (LPRGBQUAD) pDib->m_lpvColorTable;
// 獲取DIB中顏色表中的表項數(shù)
nColorEntries = pDib->m_nColorTableEntries;
// 判斷顏色數(shù)目是否是256色
if (nColorEntries == 256)
{
// 讀取偽彩色編碼,更新DIB顏色表
for (i = 0; i < nColorEntries; i++)
{
// 更新DIB調(diào)色板紅色分量
pDibQuad->rgbRed = pColorsTable[i * 4];
// 更新DIB調(diào)色板綠色分量
pDibQuad->rgbGreen = pColorsTable[i * 4 + 1];
// 更新DIB調(diào)色板藍色分量
pDibQuad->rgbBlue = pColorsTable[i * 4 + 2];
// 更新DIB調(diào)色板保留位
pDibQuad->rgbReserved = 0;
pDibQuad++;
}
}
// 如果不是256色的DIB,則不進行處理
else
return FALSE;
// 返回
return TRUE;
}
/*************************************************************************
*
* \函數(shù)名稱:
* LowPassFilterEnhance()
*
* \輸入?yún)?shù):
* LPBYTE lpImage - 指向需要增強得圖象數(shù)據(jù)
* int nWidth - 數(shù)據(jù)寬度
* int nHeight - 數(shù)據(jù)高度
* int nRadius - 低通濾波的濾波半徑
*
* \返回值:
* 無
*
* \說明:
* lpImage 是指向需要增強的數(shù)據(jù)指針。注意,這個指針指向的數(shù)據(jù)區(qū)不能是CDib指向的數(shù)據(jù)區(qū)
* 因為CDib指向的數(shù)據(jù)區(qū)的每一行是DWORD對齊的。
* 經(jīng)過低通濾波的數(shù)據(jù)存儲在lpImage當中。
*
*************************************************************************
*/
void LowPassFilterEnhance(LPBYTE lpImage, int nWidth, int nHeight, int nRadius)
{
// 循環(huán)控制變量
int y ;
int x ;
double dTmpOne ;
double dTmpTwo ;
// 傅立葉變換的寬度和高度(2的整數(shù)次冪)
int nTransWidth ;
int nTransHeight;
// 圖象象素值
unsigned char unchValue;
// 指向時域數(shù)據(jù)的指針
complex<double> * pCTData ;
// 指向頻域數(shù)據(jù)的指針
complex<double> * pCFData ;
// 計算進行傅立葉變換的點數(shù) (2的整數(shù)次冪)
dTmpOne = log(nWidth)/log(2);
dTmpTwo = ceil(dTmpOne) ;
dTmpTwo = pow(2,dTmpTwo) ;
nTransWidth = (int) dTmpTwo ;
// 計算進行傅立葉變換的點數(shù) (2的整數(shù)次冪)
dTmpOne = log(nHeight)/log(2);
dTmpTwo = ceil(dTmpOne) ;
dTmpTwo = pow(2,dTmpTwo) ;
nTransHeight = (int) dTmpTwo ;
// 傅立葉變換的實部和虛部
double dReal;
double dImag;
// 低通濾波的半徑不能超過頻域的最大半徑
if(nRadius>nTransWidth-1 || nRadius>nTransHeight-1)
{
return ;
}
// 分配內(nèi)存
pCTData=new complex<double>[nTransWidth * nTransHeight];
pCFData=new complex<double>[nTransWidth * nTransHeight];
// 初始化
// 圖像數(shù)據(jù)的寬和高不一定是2的整數(shù)次冪,所以pCTData
// 有一部分數(shù)據(jù)需要補0
for(y=0; y<nTransHeight; y++)
{
for(x=0; x<nTransWidth; x++)
{
pCTData[y*nTransWidth + x]=complex<double>(0,0);
}
}
// 把圖像數(shù)據(jù)傳給pCTData
for(y=0; y<nHeight; y++)
{
for(x=0; x<nWidth; x++)
{
unchValue = lpImage[y*nWidth +x];
pCTData[y*nTransWidth + x]=complex<double>(unchValue,0);
}
}
// 傅立葉正變換
DIBFFT_2D(pCTData, nWidth, nHeight, pCFData) ;
// 下面開始實施低通濾波,把所有大于nRadius的高頻分量設置為0
// 注意這里高頻分量采用的范數(shù)不是歐式距離,而是無窮大范數(shù)
// || (u,v)-(0,0) || = max(|u|,|v|)
for(y=nRadius; y<nTransHeight; y++)
{
for(x=nRadius; x<nTransWidth; x++)
{
pCFData[y*nTransWidth + x]=complex<double>(0,0);
}
}
// 經(jīng)過低通濾波的圖象進行反變換
IFFT_2D(pCFData, pCTData, nWidth, nHeight);
// 反變換的數(shù)據(jù)傳給lpImage
for(y=0; y<nHeight; y++)
{
for(x=0; x<nWidth; x++)
{
dReal = pCTData[y*nTransWidth + x].real() ;
dImag = pCTData[y*nTransWidth + x].imag() ;
unchValue = (unsigned char)max(0,min(255,sqrt(dReal*dReal+dImag*dImag) ));
lpImage[y*nWidth + x] = unchValue ;
}
}
// 釋放內(nèi)存
delete pCTData;
delete pCFData;
pCTData = NULL;
pCFData = NULL;
}
/*************************************************************************
*
* \函數(shù)名稱:
* HighPassFilterEnhance()
*
* \輸入?yún)?shù):
* LPBYTE lpImage - 指向需要增強得圖象數(shù)據(jù)
* int nWidth - 數(shù)據(jù)寬度
* int nHeight - 數(shù)據(jù)高度
* int nRadius - 高通濾波的濾波半徑
*
* \返回值:
* 無
*
* \說明:
* lpImage 是指向需要增強的數(shù)據(jù)指針。注意,這個指針指向的數(shù)據(jù)區(qū)不能是CDib指向的數(shù)據(jù)區(qū)
* 因為CDib指向的數(shù)據(jù)區(qū)的每一行是DWORD對齊的。
* 經(jīng)過高通濾波的數(shù)據(jù)存儲在lpImage當中。
*
*************************************************************************
*/
void HighPassFilterEnhance(LPBYTE lpImage, int nWidth, int nHeight, int nRadius)
{
// 循環(huán)控制變量
int y ;
int x ;
double dTmpOne ;
double dTmpTwo ;
// 傅立葉變換的寬度和高度(2的整數(shù)次冪)
int nTransWidth ;
int nTransHeight;
// 圖象象素值
unsigned char unchValue;
// 指向時域數(shù)據(jù)的指針
complex<double> * pCTData ;
// 指向頻域數(shù)據(jù)的指針
complex<double> * pCFData ;
double dReal;
double dImag;
// 計算進行傅立葉變換的點數(shù) (2的整數(shù)次冪)
dTmpOne = log(nWidth)/log(2);
dTmpTwo = ceil(dTmpOne) ;
dTmpTwo = pow(2,dTmpTwo) ;
nTransWidth = (int) dTmpTwo ;
// 計算進行傅立葉變換的點數(shù) (2的整數(shù)次冪)
dTmpOne = log(nHeight)/log(2);
dTmpTwo = ceil(dTmpOne) ;
dTmpTwo = pow(2,dTmpTwo) ;
nTransHeight = (int) dTmpTwo ;
// 濾波的半徑不能超過頻域的最大半徑
if(nRadius>nTransWidth-1 || nRadius>nTransHeight-1)
{
return ;
}
// 分配內(nèi)存
pCTData=new complex<double>[nTransWidth * nTransHeight];
pCFData=new complex<double>[nTransWidth * nTransHeight];
// 初始化
// 圖像數(shù)據(jù)的寬和高不一定是2的整數(shù)次冪,所以pCTData
// 有一部分數(shù)據(jù)需要補0
for(y=0; y<nTransHeight; y++)
{
for(x=0; x<nTransWidth; x++)
{
pCTData[y*nTransWidth + x]=complex<double>(0,0);
}
}
// 把圖像數(shù)據(jù)傳給pCTData
for(y=0; y<nHeight; y++)
{
for(x=0; x<nWidth; x++)
{
unchValue = lpImage[y*nWidth +x];
pCTData[y*nTransWidth + x]=complex<double>(unchValue,0);
}
}
// 傅立葉正變換
DIBFFT_2D(pCTData, nWidth, nHeight, pCFData) ;
// 下面開始濾波,把所有小于nRadius的低頻分量設置為0
// 采用的范數(shù)不是歐式距離,而是無窮大范數(shù)
// || (u,v)-(0,0) || = max(|u|,|v|)
for(y=0; y<nRadius; y++)
{
for(x=0; x<nRadius; x++)
{
pCFData[y*nTransWidth + x]=complex<double>(0,0);
}
}
// 經(jīng)過濾波的圖象進行反變換
IFFT_2D(pCFData, pCTData, nWidth, nHeight);
// 反變換的數(shù)據(jù)傳給lpImage
for(y=0; y<nHeight; y++)
{
for(x=0; x<nWidth; x++)
{
// 因為高通濾波器會把低頻成分去掉,所以圖象看起來會比較暗,為了解決這個問題
// 在經(jīng)過增強后的圖象加上一個常數(shù),使圖象變得亮起來。嚴格來講這種處理相當于
// 增加了一些低頻分量(在頻率(0,0))。不過如果不加一個常數(shù),高通效果在觀看
// 上就不是很方便。
dReal = pCTData[y*nTransWidth + x].real() ;
dImag = pCTData[y*nTransWidth + x].imag() ;
unchValue = (unsigned char)max(0,min(255,(sqrt(dReal*dReal+dImag*dImag)+100 )));
lpImage[y*nWidth + x] = unchValue ;
}
}
// 釋放內(nèi)存
delete pCTData;
delete pCFData;
pCTData = NULL;
pCFData = NULL;
}
/*************************************************************************
*
* \函數(shù)名稱:
* ButterWorthLowPass()
*
* \輸入?yún)?shù):
* LPBYTE lpImage - 指向需要增強得圖象數(shù)據(jù)
* int nWidth - 數(shù)據(jù)寬度
* int nHeight - 數(shù)據(jù)高度
* int nRadius - ButterWorth低通濾波的“半功率”點
*
* \返回值:
* 無
*
* \說明:
* lpImage 是指向需要增強的數(shù)據(jù)指針。注意,這個指針指向的數(shù)據(jù)區(qū)不能是CDib指向的數(shù)據(jù)區(qū)
* 因為CDib指向的數(shù)據(jù)區(qū)的每一行是DWORD對齊的。
* 經(jīng)過ButterWorth低通濾波的數(shù)據(jù)存儲在lpImage當中。
*
*************************************************************************
*/
void ButterWorthLowPass(LPBYTE lpImage, int nWidth, int nHeight, int nRadius)
{
// 循環(huán)控制變量
int y ;
int x ;
double dTmpOne ;
double dTmpTwo ;
// ButterWorth 濾波系數(shù)
double H ;
// 傅立葉變換的寬度和高度(2的整數(shù)次冪)
int nTransWidth ;
int nTransHeight;
double dReal ;
double dImag ;
// 圖象象素值
unsigned char unchValue;
// 指向時域數(shù)據(jù)的指針
complex<double> * pCTData ;
// 指向頻域數(shù)據(jù)的指針
complex<double> * pCFData ;
// 計算進行傅立葉變換的點數(shù) (2的整數(shù)次冪)
dTmpOne = log(nWidth)/log(2);
dTmpTwo = ceil(dTmpOne) ;
dTmpTwo = pow(2,dTmpTwo) ;
nTransWidth = (int) dTmpTwo ;
// 計算進行傅立葉變換的點數(shù) (2的整數(shù)次冪)
dTmpOne = log(nHeight)/log(2);
dTmpTwo = ceil(dTmpOne) ;
dTmpTwo = pow(2,dTmpTwo) ;
nTransHeight = (int) dTmpTwo ;
// 分配內(nèi)存
pCTData=new complex<double>[nTransWidth * nTransHeight];
pCFData=new complex<double>[nTransWidth * nTransHeight];
// 初始化
// 圖像數(shù)據(jù)的寬和高不一定是2的整數(shù)次冪,所以pCTData
// 有一部分數(shù)據(jù)需要補0
for(y=0; y<nTransHeight; y++)
{
for(x=0; x<nTransWidth; x++)
{
pCTData[y*nTransWidth + x]=complex<double>(0,0);
}
}
// 把圖像數(shù)據(jù)傳給pCTData
for(y=0; y<nHeight; y++)
{
for(x=0; x<nWidth; x++)
{
unchValue = lpImage[y*nWidth +x];
pCTData[y*nTransWidth + x]=complex<double>(unchValue,0);
}
}
// 傅立葉正變換
DIBFFT_2D(pCTData, nWidth, nHeight, pCFData) ;
// 下面開始實施ButterWorth低通濾波
for(y=0; y<nTransHeight; y++)
{
for(x=0; x<nTransWidth; x++)
{
H = (double)(y*y+x*x) ;
H = H / (nRadius * nRadius);
H = 1/(1+H) ;
pCFData[y*nTransWidth + x]=complex<double>(pCFData[y*nTransWidth + x].real()*H,
pCFData[y*nTransWidth + x].imag()*H);
}
}
// 經(jīng)過ButterWorth低通濾波的圖象進行反變換
IFFT_2D(pCFData, pCTData, nWidth, nHeight);
// 反變換的數(shù)據(jù)傳給lpImage
for(y=0; y<nHeight; y++)
{
for(x=0; x<nWidth; x++)
{
dReal = pCTData[y*nTransWidth + x].real() ;
dImag = pCTData[y*nTransWidth + x].imag() ;
unchValue = (unsigned char)max(0,min(255,sqrt(dReal*dReal+dImag*dImag) ));
lpImage[y*nWidth + x] = unchValue ;
}
}
// 釋放內(nèi)存
delete pCTData;
delete pCFData;
pCTData = NULL;
pCFData = NULL;
}
/*************************************************************************
*
* \函數(shù)名稱:
* ButterWorthHighPass()
*
* \輸入?yún)?shù):
* LPBYTE lpImage - 指向需要增強得圖象數(shù)據(jù)
* int nWidth - 數(shù)據(jù)寬度
* int nHeight - 數(shù)據(jù)高度
* int nRadius - ButterWorth高通濾波的“半功率”點
*
* \返回值:
* 無
*
* \說明:
* lpImage 是指向需要增強的數(shù)據(jù)指針。注意,這個指針指向的數(shù)據(jù)區(qū)不能是
* CDib指向的數(shù)據(jù)區(qū), 因為CDib指向的數(shù)據(jù)區(qū)的每一行是DWORD對齊的。
* 經(jīng)過ButterWorth高通濾波的數(shù)據(jù)存儲在lpImage當中。
*
*************************************************************************
*/
void ButterWorthHighPass(LPBYTE lpImage, int nWidth, int nHeight, int nRadius)
{
// 循環(huán)控制變量
int y ;
int x ;
double dTmpOne ;
double dTmpTwo ;
// ButterWorth 濾波系數(shù)
double H ;
// 傅立葉變換的寬度和高度(2的整數(shù)次冪)
int nTransWidth ;
int nTransHeight;
double dReal ;
double dImag ;
// 圖象象素值
unsigned char unchValue;
// 指向時域數(shù)據(jù)的指針
complex<double> * pCTData ;
// 指向頻域數(shù)據(jù)的指針
complex<double> * pCFData ;
// 計算進行傅立葉變換的點數(shù) (2的整數(shù)次冪)
dTmpOne = log(nWidth)/log(2);
dTmpTwo = ceil(dTmpOne) ;
dTmpTwo = pow(2,dTmpTwo) ;
nTransWidth = (int) dTmpTwo ;
// 計算進行傅立葉變換的點數(shù) (2的整數(shù)次冪)
dTmpOne = log(nHeight)/log(2);
dTmpTwo = ceil(dTmpOne) ;
dTmpTwo = pow(2,dTmpTwo) ;
nTransHeight = (int) dTmpTwo ;
// 分配內(nèi)存
pCTData=new complex<double>[nTransWidth * nTransHeight];
pCFData=new complex<double>[nTransWidth * nTransHeight];
// 初始化
// 圖像數(shù)據(jù)的寬和高不一定是2的整數(shù)次冪,所以pCTData
// 有一部分數(shù)據(jù)需要補0
for(y=0; y<nTransHeight; y++)
{
for(x=0; x<nTransWidth; x++)
{
pCTData[y*nTransWidth + x]=complex<double>(0,0);
}
}
// 把圖像數(shù)據(jù)傳給pCTData
for(y=0; y<nHeight; y++)
{
for(x=0; x<nWidth; x++)
{
unchValue = lpImage[y*nWidth +x];
pCTData[y*nTransWidth + x]=complex<double>(unchValue,0);
}
}
// 傅立葉正變換
DIBFFT_2D(pCTData, nWidth, nHeight, pCFData) ;
// 下面開始實施ButterWorth高通濾波
for(y=0; y<nTransHeight; y++)
{
for(x=0; x<nTransWidth; x++)
{
H = (double)(y*y+x*x) ;
H = (nRadius * nRadius) / H ;
H = 1/(1+H) ;
pCFData[y*nTransWidth + x]=complex<double>(H*(pCFData[y*nTransWidth + x].real()),
H*(pCFData[y*nTransWidth + x].imag()) );
}
}
// 經(jīng)過ButterWorth高通濾波的圖象進行反變換
IFFT_2D(pCFData, pCTData, nWidth, nHeight);
// 反變換的數(shù)據(jù)傳給lpImage
for(y=0; y<nHeight; y++)
{
for(x=0; x<nWidth; x++)
{
dReal = pCTData[y*nTransWidth + x].real() ;
dImag = pCTData[y*nTransWidth + x].imag() ;
unchValue = (unsigned char)max(0,min(255,sqrt(dReal*dReal+dImag*dImag)+100 ));
lpImage[y*nWidth + x] = unchValue ;
}
}
// 釋放內(nèi)存
delete pCTData;
delete pCFData;
pCTData = NULL;
pCFData = NULL;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -