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

📄 restore.cpp

📁 提供了图像识别
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// ************************************************************************
//  文件名: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 + -