⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 restore.cpp

📁 用C++实现的数字图像处理各个算法源代码 我精心整理的 很难的啊 希望可以给大家带来帮助
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Restore.cpp: implementation of the CRestore class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "dip.h"
#include "Restore.h"


IMPLEMENT_DYNCREATE(CRestore, CObject)

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CRestore::CRestore()
{


}

CRestore::~CRestore()
{
	exitM();
}

CRestore::CRestore(CDibObject *pDibObject)
{
	m_pDibObject=pDibObject;
	initM(MATCOM_VERSION);
}

/******************************************************************
*
*    函数名:InvFilter()
*
*    参  数:无
*  
*    返回值:布尔类型
*
*    功  能:对一幅图像进行逆滤波复原
*  
*    备  注:该函数适用于对由卷积所造成的图像模糊进行复原
*
*******************************************************************/
BOOL CRestore::InvFilter()
{
	/************************************读取图像数据******************************/

	//图像指针为空,无法操作返回
	if(m_pDibObject == NULL) return(FALSE);
	
	//对1位及4位图像不作任何操作直接返回
	if(m_pDibObject->GetNumBits() != 8) return( FALSE );
	
	//获取图像宽度和高度(以像素为单位)
	int nWidth = m_pDibObject->GetWidth();
	int nHeight = m_pDibObject->GetHeight();
			
	//定义变量
	unsigned char *pBuffer, *pBits;
	RGBQUAD *pPalette;
	int nWidthBytes, nNewWidthBytes, nNumColors;
	

	//获得图像指针
	pBuffer = (unsigned char *) m_pDibObject->GetDIBPointer( &nWidthBytes, 
		m_pDibObject->GetNumBits(),
		&nNewWidthBytes, 8);
	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)];
	if( pBuffer == NULL ) return( NULL );
 
    

    /******************************将图像数据转换成二维矩阵,以进行矩阵运算*******************************/
	
	//图像数据总字节数,其中nWidthBytes为每行图像数据占用的字节数
	DWORD SizeImage = nWidthBytes * nHeight;

	//通过创建一个1×SizeImage的一维矩阵0矩阵,为矩阵变量分配内存
	m_matBits = zeros(1, SizeImage);

	//将矩阵由double型转换为unsigned char型,以便将图像数据赋给矩阵
	m_matBits = muint8(m_matBits);

	//首先利用m_matBits.addr()获得矩阵实部的内存指针,
	//然后利用memcpy()将图像数据一次性赋给矩阵变量。
	memcpy(m_matBits.addr(), pBits, SizeImage);

	//由于Mm型的矩阵在内存中是按先列后行的顺序存储的,
	//先用Matrix<LIB>C++的库函数reshape()将一维矩阵m_matBits变维为
	//nWidthBytes×nHeight的二维矩阵,再用rot90()函数将其逆时针旋转90度,
	//将矩阵变为nHeight×nWidthBytes的二维矩阵,使图像的第nHeight-1行数据
	//存储在矩阵的第0行,从而完成将图像数据按从下到上的顺序存储。
	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);
    
    //定义模板,大小为7x7
	Mm m_matFilter;
	m_matFilter=zeros(nHeight,nWidth);
	int i,j;
	for(i=1;i<7;i++)
	{
		for(j=1;j<7;j++){
			m_matFilter.r(i,j)=0.02;
		}

	}


    /**********************************对图像进行卷积模糊处理****************************/

	//对原图像进行快速傅立叶变换,将图像从空域变换到频域
	m_matBits=fft2(m_matBits);
	//对模板进行快速傅立叶变换
	m_matFilter=fft2(m_matFilter);

	//频率相乘
	double a,b,c,d;
	for(i=1;i<=nHeight;i++)
	{
		for(j=1;j<=nWidth;j++)
		{
			a=m_matBits.r(i,j);
			b=m_matBits.i(i,j);
			c=m_matFilter.r(i,j);
			d=m_matFilter.i(i,j);
			if(c*c+d*d>0.003)
			{
				m_matBits.r(i,j)=(a*c+b*d)/(c*c+d*d);
				m_matBits.i(i,j)=(b*c-a*d)/(c*c+d*d);
			}
		}
	}

	//对图像进行快速逆傅立叶变换,将图像从频域变换到空域
	m_matBits=ifft2(m_matBits);


	/**********************************图像处理结果保存**********************************/

	//用Matrix<LIB>C++的库函数将矩阵数据范围限定于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补齐为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)));
	}
	//将图像数据矩阵顺时针旋转90度(原因同前)
	m_matBits = rot90(m_matBits, -1);
	//将图像数据矩阵存回图像数据区
	memcpy(pBits, m_matBits.addr(), (nWidthBytes * nHeight)*sizeof(unsigned char));
	
	return TRUE;
}

/******************************************************************
*
*    函数名:ConvNoiseBlur()
*
*    参  数:无
*  
*    返回值:布尔类型
*
*    功  能:对一幅图像进行卷积噪音模糊
*  
*    备  注:无
*
*******************************************************************/
BOOL CRestore::ConvNoiseBlur()
{

	/************************************读取图像数据******************************/

	//图像指针为空,无法操作返回
	if(m_pDibObject == NULL) return(FALSE);
	
	//对1位及4位图像不作任何操作直接返回
	if(m_pDibObject->GetNumBits() != 8) return( FALSE );
	
	//获取图像宽度和高度(以像素为单位)
	int nWidth = m_pDibObject->GetWidth();
	int nHeight = m_pDibObject->GetHeight();
			
	//定义变量
	unsigned char *pBuffer, *pBits;
	RGBQUAD *pPalette;
	int nWidthBytes, nNewWidthBytes, nNumColors;
	

	//获得图像指针
	pBuffer = (unsigned char *) m_pDibObject->GetDIBPointer( &nWidthBytes, 
		m_pDibObject->GetNumBits(),
		&nNewWidthBytes, 8);
	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)];
	if( pBuffer == NULL ) return( NULL );
 
    

    /******************************将图像数据转换成二维矩阵,以进行矩阵运算*******************************/
	
	//图像数据总字节数,其中nWidthBytes为每行图像数据占用的字节数
	DWORD SizeImage = nWidthBytes * nHeight;

	//通过创建一个1×SizeImage的一维矩阵0矩阵,为矩阵变量分配内存
	m_matBits = zeros(1, SizeImage);

	//将矩阵由double型转换为unsigned char型,以便将图像数据赋给矩阵
	m_matBits = muint8(m_matBits);

	//首先利用m_matBits.addr()获得矩阵实部的内存指针,
	//然后利用memcpy()将图像数据一次性赋给矩阵变量。
	memcpy(m_matBits.addr(), pBits, SizeImage);

	//由于Mm型的矩阵在内存中是按先列后行的顺序存储的,
	//先用Matrix<LIB>C++的库函数reshape()将一维矩阵m_matBits变维为
	//nWidthBytes×nHeight的二维矩阵,再用rot90()函数将其逆时针旋转90度,
	//将矩阵变为nHeight×nWidthBytes的二维矩阵,使图像的第nHeight-1行数据
	//存储在矩阵的第0行,从而完成将图像数据按从下到上的顺序存储。
	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);
    


    //定义模板,大小为7x7
	Mm m_matFilter;
	m_matFilter=zeros(nHeight,nWidth);
	int i,j;
	for(i=1;i<7;i++)
	{
		for(j=1;j<7;j++){
			m_matFilter.r(i,j)=0.02;
		}

	}


   /**************************************对图像进行卷积噪声模糊处理******************************/

	//对原图像进行快速傅立叶变换,将图像从空域变换到频域
	m_matBits=fft2(m_matBits);
	//对模板进行快速傅立叶变换
	m_matFilter=fft2(m_matFilter);

	//频率相乘
	for(i=1;i<=nHeight;i++)
	{
		for(j=1;j<=nWidth;j++)
		{
			m_matBits.r(i,j)=m_matBits.r(i,j)*m_matFilter.r(i,j)-m_matBits.i(i,j)*m_matFilter.i(i,j);
			m_matBits.i(i,j)=m_matBits.r(i,j)*m_matFilter.i(i,j)+m_matBits.i(i,j)*m_matFilter.r(i,j);
		}
	}

	//对图像做快速逆傅立叶变换,将图像从频域变换到空域
	m_matBits=ifft2(m_matBits);

	for(i=1;i<=nHeight;i++)
	{
		for(j=1;j<=nWidth;j++)
		{
			if((i+j)==((int) (i+j)/8)*8)
			{
				m_matBits.r(i,j)=m_matBits.r(i,j)-16;
			}
		}
	}

	   
	
	/**********************************图像处理结果保存**********************************/

	//用Matrix<LIB>C++的库函数将矩阵数据范围限定于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补齐为4的整数倍

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -