📄 freqpro.cpp
字号:
// AreaPro.cpp: implementation of the CFreqPro class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "FreqPro.h"
#define AVERAGE 0
#define DISK 1
#define GAUSSIAN 2
#define LAPLACIAN 3
#define LOG 4
#define MOTION 5
#define PREWITT 6
#define SOBEL 7
#define UNSHARP 8
IMPLEMENT_DYNCREATE(CFreqPro, CObject)
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//Diagnostics and dump member functions, overridden
#ifdef _DEBUG
void CFreqPro::Dump(CDumpContext &dc) const
{
//call base class function first
CObject::Dump(dc);
}
#endif
#ifdef _DEBUG
void CFreqPro::AssertValid() const
{
//call inherited AssertValid first
CObject::AssertValid();
//Check CDibObject members...
ASSERT(m_pDibObject != NULL); //Must exist
}
#endif
/***********************************************************************
* *
* 频域处理类 *
* *
***********************************************************************/
////////////////////////////////////////////////////////////////////////
//构造函数CFreqPro()
//----------------------------------------------------------------------
//基本功能:构造一个CFreqPro类的对象,如不传入CDibObject对象。第一次调
// 用某一个处理函数时必须给出一个CDibObject对象指针。
//----------------------------------------------------------------------
//参数说明:无
//----------------------------------------------------------------------
//返 回:无
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
CFreqPro::CFreqPro()
{
//初始化Matrix<LIB>类库
initM(MATCOM_VERSION);
}
////////////////////////////////////////////////////////////////////////
//构造函数CFreqPro()
//----------------------------------------------------------------------
//基本功能:构造一个CFreqPro类的对象并传入CDibObject对象。所有的操作都
// 针对该对象,直到另一个对象作为参数被传给图像处理函数。
//----------------------------------------------------------------------
//参数说明:CDibObject *pDibObject
//----------------------------------------------------------------------
//返 回:无
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
CFreqPro::CFreqPro(CDibObject *pDibObject)
{
//初始化Matrix<LIB>类库
initM(MATCOM_VERSION);
m_pDibObject = pDibObject;
}
//析构函数
CFreqPro::~CFreqPro()
{
//结束Matrix<LIB>类库调用
exitM();
}
////////////////////////////////////////////////////////////////////////
//void SetDibObjectClass(CDibObject *pDibObject)
//----------------------------------------------------------------------
//基本功能:本函数为CFreqPro类对象指定一个CDibObject对象指针
//----------------------------------------------------------------------
//参数说明:CDibObject *pDibObject, 默认为NULL。
//----------------------------------------------------------------------
//返 回:无。
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
void CFreqPro::SetDibObjectClass( CDibObject *pDibObject )
{
m_pDibObject = pDibObject;
}
////////////////////////////////////////////////////////////////////////
//Mm GetMatData()
//----------------------------------------------------------------------
//基本功能:本函数根据CDibObject对象指针指定的图像,生成图像数据矩阵。
//----------------------------------------------------------------------
//参数说明:无。
//----------------------------------------------------------------------
//返 回:Mm 图像数据矩阵
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
Mm CFreqPro::GetMatData()
{
//图像指针为空,无法操作返回
if(m_pDibObject == NULL) return(NULL);
//对不是8位的图像不作任何操作直接返回
if(m_pDibObject->GetNumBits() != 8)
{
AfxMessageBox("目前只支持8位图像的处理!");
return( NULL );
}
//获取图像宽度和高度(以像素为单位)
int nWidth = m_pDibObject->GetWidth();
int nHeight = m_pDibObject->GetHeight();
//定义变量
unsigned char *pBuffer, *pBits;
RGBQUAD *pPalette;
int nWidthBytes, nNumColors;
//获得图像指针
pBuffer = (unsigned char *) m_pDibObject->GetDIBPointer( &nWidthBytes,
m_pDibObject->GetNumBits());
if( pBuffer == NULL ) return( NULL );
//获得颜色数
nNumColors = m_pDibObject->GetNumColors();
//获得调色板指针
pPalette = (RGBQUAD *) &pBuffer[sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)];
//获得位图数据指针
pBits = (unsigned char *) &pBuffer[sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)
+ nNumColors * sizeof(RGBQUAD)];
//图像数据区大小(字节总数)
DWORD SizeImage = nWidthBytes * nHeight;
//创建图像数据矩阵,并将其元素初始值设为0
m_matBits = zeros(1, SizeImage);
//默认的矩阵数据类型是double,
//首先将其转换为unsigned char型,
//以便用memcpy内存拷贝命令将图像数据赋给矩阵。
m_matBits = muint8(m_matBits);
//通过Matrix<LIB>C++库的.addr()函数返回矩阵变量的内存指针,以完成对矩阵单元的访问。
//用memcpy内存拷贝命令将图像数据赋给矩阵。
memcpy(m_matBits.addr(), pBits, SizeImage);
//由于Mm类型的矩阵是按先列后行的顺序排列,
//在此用reshape()函数将创建的一维矩阵m_matBits变维为nWidthBytes×nHeight的二维矩阵。
//再用rot90()函数将二维矩阵逆时针旋转90度,将矩阵变为nHeight×nWidthBytes的二维矩阵,
//并使的矩阵的第nHeight行对应图像数据的第一行数据。
m_matBits = rot90(reshape(m_matBits, nWidthBytes, nHeight));
//若图像宽度与其字节宽度不同,
//则将由系统补齐的每行字节数为4的整数倍的各列0删除,以减小矩阵大小加快处理速度。
if(nWidthBytes != nWidth)
{
//相当于Matlab中的X=X(:,1:nWidth)操作
m_matBits = m_matBits(c_p, colon(1, 1, nWidth));
}
//将矩阵由unsigned char型转换为double型,以便进行运算
m_matBits = mdouble(m_matBits);
//内存解锁
::GlobalUnlock(m_pDibObject->GetDib());
return( m_matBits );
}
////////////////////////////////////////////////////////////////////////
//BOOL SetBits()
//----------------------------------------------------------------------
//基本功能:本函数根据用图像数据矩阵重设图像数据区
//----------------------------------------------------------------------
//参数说明:无。
//----------------------------------------------------------------------
//返 回:BOOL
// 成功时返回TRUE,失败时返回FALSE。
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
BOOL CFreqPro::SetBits()
{
//图像指针为空,无法操作返回
if(m_pDibObject == NULL) return(FALSE);
//对1位及4位图像不作任何操作直接返回
if(m_pDibObject->GetNumBits() != 8)
{
AfxMessageBox("目前只支持8位灰度图像的处理!");
return( FALSE );
}
//获取图像宽度和高度(以像素为单位)
int nWidth = m_pDibObject->GetWidth();
int nHeight = m_pDibObject->GetHeight();
//定义变量
unsigned char *pBuffer, *pBits;
RGBQUAD *pPalette;
int nWidthBytes, nNumColors;
//获得图像指针
pBuffer = (unsigned char *) m_pDibObject->GetDIBPointer( &nWidthBytes,
m_pDibObject->GetNumBits());
if( pBuffer == NULL ) return( NULL );
//获得颜色数
nNumColors = m_pDibObject->GetNumColors();
//获得调色板指针
pPalette = (RGBQUAD *) &pBuffer[sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)];
//获得位图数据指针
pBits = (unsigned char *) &pBuffer[sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)
+ nNumColors * sizeof(RGBQUAD)];
//创建矩阵变换,其元素初始值设为0
if(isempty(m_matBits) == 1)
{
return FALSE;
}
//将矩阵数据范围限定于(0——255)
m_matBits = mabs(m_matBits);
Mm L = m_matBits > 255.0;
Mm NotL = !L;
m_matBits = times(m_matBits, NotL) + L * 255.0;
//将矩阵由double型转换为unsigned char型,以便将图像数据赋给矩阵
m_matBits = muint8(m_matBits);
//补0,以满足BMP图像对行宽字节数为4的整数倍的要求。
int nTmp = (int)rem(nWidth, 4);
int nPadding;
if(nTmp > 0)
{
nPadding = 4 - nTmp;
m_matBits = cat(2, m_matBits,
repmat(muint8(0), (BR(size(m_matBits, 1)), nPadding)));
}
else
{
nPadding = 0;
}
//对矩阵进行转置操作
m_matBits = rot90(m_matBits, -1);
//将图像数据赋绘矩阵
memcpy(pBits, m_matBits.addr(), (nWidthBytes * nHeight)*sizeof(unsigned char));
//内存解锁
::GlobalUnlock(m_pDibObject->GetDib());
return( TRUE );
}
////////////////////////////////////////////////////////////////////////
//Mm FFT2()
//----------------------------------------------------------------------
//基本功能:本函数完成图像的快速傅立叶变换。
//----------------------------------------------------------------------
//参数说明:CDibObject *pDibObject 图像对象指针。
//----------------------------------------------------------------------
//返 回:Mm 返回变换结果矩阵
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
Mm CFreqPro::FFT2(CDibObject *pDibObject)
{
//CDibObject对象指针
if( pDibObject != NULL ) m_pDibObject = pDibObject;
//若未指定 CDibObject 对象指针返回FALSE
if( m_pDibObject == NULL ) return( FALSE );
//创建图像数据矩阵
GetMatData();
//获得矩阵的行数和列数
Mm mSize = size(m_matBits);
//调用Matrix<Lib>C++库函数fft2()完成二维离散傅立叶变换
Mm ff = fft2(m_matBits);
Mm matTransed = ff;
//调用Matrix<Lib>C++库函数fftshift()将频域中心移到矩阵中心
ff = fftshift(ff);
//调用Matrix<Lib>C++库函数mabs()计算频谱
m_matBits = mabs(ff) / sqrt(mSize.r(1,1)*mSize.r(1,2));
//将矩阵数据赋给图像数据区
SetBits();
return matTransed;
}
////////////////////////////////////////////////////////////////////////
//BOOL NFFT2()
//----------------------------------------------------------------------
//基本功能:本函数完成图像的快速傅立叶逆变换。
//----------------------------------------------------------------------
//参数说明:Mm matTransed 被变换的矩阵
//----------------------------------------------------------------------
//返 回:BOOL
// 成功时返回TRUE,失败时返回FALSE。
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
BOOL CFreqPro::NFFT2(Mm matTransed)
{
//若未指定 CDibObject 对象指针返回FALSE
if( m_pDibObject == NULL ) return( FALSE );
//调用Matrix<Lib>C++库函数fft2()完成二维离散傅立叶变换
m_matBits = ifft2(matTransed);
//将矩阵数据赋给图像数据区
SetBits();
return(TRUE);
}
////////////////////////////////////////////////////////////////////////
//Mm DCT2()
//----------------------------------------------------------------------
//基本功能:本函数完成图像的离散余弦变换。
//----------------------------------------------------------------------
//参数说明:CDibObject *pDibObject 图像对象指针。
//----------------------------------------------------------------------
//返 回:Mm 返回变换结果矩阵
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
Mm CFreqPro::DCT2(CDibObject *pDibObject)
{
//CDibObject对象指针
if( pDibObject != NULL ) m_pDibObject = pDibObject;
//若未指定 CDibObject 对象指针返回FALSE
if( m_pDibObject == NULL ) return( FALSE );
//创建图像数据矩阵
GetMatData();
Mm ff = dct2(m_matBits);
Mm matTransed = ff;
//调用Matrix<Lib>C++库函数mabs()计算频谱
m_matBits = mabs(ff);
//将矩阵数据赋给图像数据区
SetBits();
return matTransed;
}
////////////////////////////////////////////////////////////////////////
//Mm WHT2()
//----------------------------------------------------------------------
//基本功能:本函数完成图像的离散沃尔什哈达玛变换。
//----------------------------------------------------------------------
//参数说明:CDibObject *pDibObject 图像对象指针。
//----------------------------------------------------------------------
//返 回:Mm 返回变换结果矩阵
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
Mm CFreqPro::WHT2(CDibObject *pDibObject)
{
//CDibObject对象指针
if( pDibObject != NULL ) m_pDibObject = pDibObject;
//若未指定 CDibObject 对象指针返回FALSE
if( m_pDibObject == NULL ) return( FALSE );
//创建图像数据矩阵
GetMatData();
//获得矩阵的行数和列数
Mm mSize = size(m_matBits);
BOOL bPowered = FALSE;
if(bIs2Power((int)mSize.r(1,1))) bPowered = TRUE;
if(bIs2Power((int)mSize.r(1,1)/12)) bPowered = TRUE;
if(bIs2Power((int)mSize.r(1,1)/20)) bPowered = TRUE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -