📄 enhance.cpp
字号:
}
// 梯度值写入内存
*(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 ;
}
/*************************************************************************
*
* 函数名称:
* ReplaceDIBColorTable()
*
* 参数:
* CDib * pDib - 指向CDib类的指针,含有原始图象信息
* LPBYTE pColorsTable - 伪彩色编码表
*
* 返回值:
* BOOL - 成功返回TRUE,否则返回FALSE。
*
* 说明:
* 该函数用指定的伪彩色编码表来替换指定的DIB图像的颜色表,参数pColorsTable
* 指向要替换的伪彩色编码表。
*
************************************************************************/
BOOL ReplaceDIBColorTable(CDib* pDib, LPBYTE pColorsTable)
{
// 循环变量
int i;
// 颜色表的表项数
int nColorEntries;
// 临时变量
LPRGBQUAD pDibQuad;
// 指向DIB的颜色表
pDibQuad = (LPRGBQUAD) pDib->m_lpvColorTable;
// 获取DIB中颜色表中的表项数
nColorEntries = pDib->m_nColorTableEntries;
// 判断颜色数目是否是256色
if (nColorEntries == 256)
{
// 读取伪彩色编码,更新DIB颜色表
for (i = 0; i < nColorEntries; i++)
{
// 更新DIB调色板红色分量
pDibQuad->rgbRed = pColorsTable[i * 4];
// 更新DIB调色板绿色分量
pDibQuad->rgbGreen = pColorsTable[i * 4 + 1];
// 更新DIB调色板蓝色分量
pDibQuad->rgbBlue = pColorsTable[i * 4 + 2];
// 更新DIB调色板保留位
pDibQuad->rgbReserved = 0;
pDibQuad++;
}
}
// 如果不是256色的DIB,则不进行处理
else
return FALSE;
// 返回
return TRUE;
}
/*************************************************************************
*
* \函数名称:
* LowPassFilterEnhance()
*
* \输入参数:
* LPBYTE lpImage - 指向需要增强得图象数据
* int nWidth - 数据宽度
* int nHeight - 数据高度
* int nRadius - 低通滤波的滤波半径
*
* \返回值:
* 无
*
* \说明:
* lpImage 是指向需要增强的数据指针。注意,这个指针指向的数据区不能是CDib指向的数据区
* 因为CDib指向的数据区的每一行是DWORD对齐的。
* 经过低通滤波的数据存储在lpImage当中。
*
*************************************************************************
*/
void LowPassFilterEnhance(LPBYTE lpImage, int nWidth, int nHeight, int nRadius)
{
// 循环控制变量
int y ;
int x ;
double dTmpOne ;
double dTmpTwo ;
// 傅立叶变换的宽度和高度(2的整数次幂)
int nTransWidth ;
int nTransHeight;
// 图象象素值
unsigned char unchValue;
// 指向时域数据的指针
complex<double> * pCTData ;
// 指向频域数据的指针
complex<double> * pCFData ;
// 计算进行傅立叶变换的点数 (2的整数次幂)
dTmpOne = log(nWidth)/log(2);
dTmpTwo = ceil(dTmpOne) ;
dTmpTwo = pow(2,dTmpTwo) ;
nTransWidth = (int) dTmpTwo ;
// 计算进行傅立叶变换的点数 (2的整数次幂)
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 ;
}
// 分配内存
pCTData=new complex<double>[nTransWidth * nTransHeight];
pCFData=new complex<double>[nTransWidth * nTransHeight];
// 初始化
// 图像数据的宽和高不一定是2的整数次幂,所以pCTData
// 有一部分数据需要补0
for(y=0; y<nTransHeight; y++)
{
for(x=0; x<nTransWidth; x++)
{
pCTData[y*nTransWidth + x]=complex<double>(0,0);
}
}
// 把图像数据传给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
// 注意这里高频分量采用的范数不是欧式距离,而是无穷大范数
// || (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);
}
}
// 经过低通滤波的图象进行反变换
IFFT_2D(pCFData, pCTData, nWidth, nHeight);
// 反变换的数据传给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 ;
}
}
// 释放内存
delete pCTData;
delete pCFData;
pCTData = NULL;
pCFData = NULL;
}
/*************************************************************************
*
* \函数名称:
* HighPassFilterEnhance()
*
* \输入参数:
* LPBYTE lpImage - 指向需要增强得图象数据
* int nWidth - 数据宽度
* int nHeight - 数据高度
* int nRadius - 高通滤波的滤波半径
*
* \返回值:
* 无
*
* \说明:
* lpImage 是指向需要增强的数据指针。注意,这个指针指向的数据区不能是CDib指向的数据区
* 因为CDib指向的数据区的每一行是DWORD对齐的。
* 经过高通滤波的数据存储在lpImage当中。
*
*************************************************************************
*/
void HighPassFilterEnhance(LPBYTE lpImage, int nWidth, int nHeight, int nRadius)
{
// 循环控制变量
int y ;
int x ;
double dTmpOne ;
double dTmpTwo ;
// 傅立叶变换的宽度和高度(2的整数次幂)
int nTransWidth ;
int nTransHeight;
// 图象象素值
unsigned char unchValue;
// 指向时域数据的指针
complex<double> * pCTData ;
// 指向频域数据的指针
complex<double> * pCFData ;
double dReal;
double dImag;
// 计算进行傅立叶变换的点数 (2的整数次幂)
dTmpOne = log(nWidth)/log(2);
dTmpTwo = ceil(dTmpOne) ;
dTmpTwo = pow(2,dTmpTwo) ;
nTransWidth = (int) dTmpTwo ;
// 计算进行傅立叶变换的点数 (2的整数次幂)
dTmpOne = log(nHeight)/log(2);
dTmpTwo = ceil(dTmpOne) ;
dTmpTwo = pow(2,dTmpTwo) ;
nTransHeight = (int) dTmpTwo ;
// 滤波的半径不能超过频域的最大半径
if(nRadius>nTransWidth-1 || nRadius>nTransHeight-1)
{
return ;
}
// 分配内存
pCTData=new complex<double>[nTransWidth * nTransHeight];
pCFData=new complex<double>[nTransWidth * nTransHeight];
// 初始化
// 图像数据的宽和高不一定是2的整数次幂,所以pCTData
// 有一部分数据需要补0
for(y=0; y<nTransHeight; y++)
{
for(x=0; x<nTransWidth; x++)
{
pCTData[y*nTransWidth + x]=complex<double>(0,0);
}
}
// 把图像数据传给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
// 采用的范数不是欧式距离,而是无穷大范数
// || (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);
}
}
// 经过滤波的图象进行反变换
IFFT_2D(pCFData, pCTData, nWidth, nHeight);
// 反变换的数据传给lpImage
for(y=0; y<nHeight; y++)
{
for(x=0; x<nWidth; x++)
{
// 因为高通滤波器会把低频成分去掉,所以图象看起来会比较暗,为了解决这个问题
// 在经过增强后的图象加上一个常数,使图象变得亮起来。严格来讲这种处理相当于
// 增加了一些低频分量(在频率(0,0))。不过如果不加一个常数,高通效果在观看
// 上就不是很方便。
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 ;
}
}
// 释放内存
delete pCTData;
delete pCFData;
pCTData = NULL;
pCFData = NULL;
}
/*************************************************************************
*
* \函数名称:
* ButterWorthLowPass()
*
* \输入参数:
* LPBYTE lpImage - 指向需要增强得图象数据
* int nWidth - 数据宽度
* int nHeight - 数据高度
* int nRadius - ButterWorth低通滤波的“半功率”点
*
* \返回值:
* 无
*
* \说明:
* lpImage 是指向需要增强的数据指针。注意,这个指针指向的数据区不能是CDib指向的数据区
* 因为CDib指向的数据区的每一行是DWORD对齐的。
* 经过ButterWorth低通滤波的数据存储在lpImage当中。
*
*************************************************************************
*/
void ButterWorthLowPass(LPBYTE lpImage, int nWidth, int nHeight, int nRadius)
{
// 循环控制变量
int y ;
int x ;
double dTmpOne ;
double dTmpTwo ;
// ButterWorth 滤波系数
double H ;
// 傅立叶变换的宽度和高度(2的整数次幂)
int nTransWidth ;
int nTransHeight;
double dReal ;
double dImag ;
// 图象象素值
unsigned char unchValue;
// 指向时域数据的指针
complex<double> * pCTData ;
// 指向频域数据的指针
complex<double> * pCFData ;
// 计算进行傅立叶变换的点数 (2的整数次幂)
dTmpOne = log(nWidth)/log(2);
dTmpTwo = ceil(dTmpOne) ;
dTmpTwo = pow(2,dTmpTwo) ;
nTransWidth = (int) dTmpTwo ;
// 计算进行傅立叶变换的点数 (2的整数次幂)
dTmpOne = log(nHeight)/log(2);
dTmpTwo = ceil(dTmpOne) ;
dTmpTwo = pow(2,dTmpTwo) ;
nTransHeight = (int) dTmpTwo ;
// 分配内存
pCTData=new complex<double>[nTransWidth * nTransHeight];
pCFData=new complex<double>[nTransWidth * nTransHeight];
// 初始化
// 图像数据的宽和高不一定是2的整数次幂,所以pCTData
// 有一部分数据需要补0
for(y=0; y<nTransHeight; y++)
{
for(x=0; x<nTransWidth; x++)
{
pCTData[y*nTransWidth + x]=complex<double>(0,0);
}
}
// 把图像数据传给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);
}
}
// 经过ButterWorth低通滤波的图象进行反变换
IFFT_2D(pCFData, pCTData, nWidth, nHeight);
// 反变换的数据传给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 ;
}
}
// 释放内存
delete pCTData;
delete pCFData;
pCTData = NULL;
pCFData = NULL;
}
/*************************************************************************
*
* \函数名称:
* ButterWorthHighPass()
*
* \输入参数:
* LPBYTE lpImage - 指向需要增强得图象数据
* int nWidth - 数据宽度
* int nHeight - 数据高度
* int nRadius - ButterWorth高通滤波的“半功率”点
*
* \返回值:
* 无
*
* \说明:
* lpImage 是指向需要增强的数据指针。注意,这个指针指向的数据区不能是
* CDib指向的数据区, 因为CDib指向的数据区的每一行是DWORD对齐的。
* 经过ButterWorth高通滤波的数据存储在lpImage当中。
*
*************************************************************************
*/
void ButterWorthHighPass(LPBYTE lpImage, int nWidth, int nHeight, int nRadius)
{
// 循环控制变量
int y ;
int x ;
double dTmpOne ;
double dTmpTwo ;
// ButterWorth 滤波系数
double H ;
// 傅立叶变换的宽度和高度(2的整数次幂)
int nTransWidth ;
int nTransHeight;
double dReal ;
double dImag ;
// 图象象素值
unsigned char unchValue;
// 指向时域数据的指针
complex<double> * pCTData ;
// 指向频域数据的指针
complex<double> * pCFData ;
// 计算进行傅立叶变换的点数 (2的整数次幂)
dTmpOne = log(nWidth)/log(2);
dTmpTwo = ceil(dTmpOne) ;
dTmpTwo = pow(2,dTmpTwo) ;
nTransWidth = (int) dTmpTwo ;
// 计算进行傅立叶变换的点数 (2的整数次幂)
dTmpOne = log(nHeight)/log(2);
dTmpTwo = ceil(dTmpOne) ;
dTmpTwo = pow(2,dTmpTwo) ;
nTransHeight = (int) dTmpTwo ;
// 分配内存
pCTData=new complex<double>[nTransWidth * nTransHeight];
pCFData=new complex<double>[nTransWidth * nTransHeight];
// 初始化
// 图像数据的宽和高不一定是2的整数次幂,所以pCTData
// 有一部分数据需要补0
for(y=0; y<nTransHeight; y++)
{
for(x=0; x<nTransWidth; x++)
{
pCTData[y*nTransWidth + x]=complex<double>(0,0);
}
}
// 把图像数据传给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()) );
}
}
// 经过ButterWorth高通滤波的图象进行反变换
IFFT_2D(pCFData, pCTData, nWidth, nHeight);
// 反变换的数据传给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 ;
}
}
// 释放内存
delete pCTData;
delete pCFData;
pCTData = NULL;
pCFData = NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -