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

📄 restore.cpp

📁 提供了图像识别
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		}
	}	
	
	//释放存储空间
	delete pCTSrc;
	delete pCTH;

	delete pCFSrc;
	delete pCFH;

	// 返回
	return true;
}

/*************************************************************************
 *
 * 函数名称:
 *   DIBWinnerFilter()
 *
 * 参数:
 *   CDib  *pDib       - 指向CDib类的指针
 *
 * 返回值:
 *   BOOL               - 维纳滤波复原操作成功返回TRUE,否则返回FALSE。
 *
 * 说明:
 *   该函数用来对DIB图像进行维纳滤波复原操作。
 *
 ************************************************************************/

BOOL WINAPI DIBWinnerFilter (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, tempre, tempim, 
			a, b, c, d, norm2;
	
	// 实际进行付立叶变换的宽度和高度
	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;
	
	//输入退化图象的长和宽必须为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];

	// 滤波器加权系数
	double *pCFFilter   = new 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);
				pCFFilter[ lLineBytes*j + i ] = 0.5;
			}
			else
			{
				pCTH[ lLineBytes*j + i ] = complex<double>(0.0 , 0.0);	
				pCFFilter[ lLineBytes*j + i ] = 0.05;
			}

			// 频域赋零值
			pCFH[ lLineBytes*j + i ] = complex<double>(0.0 , 0.0);
		}
	}
	
	//对退化图像进行FFT
	::DIBFFT_2D(pCTSrc, lLineBytes, lHeight, pCFSrc);
	
	//对变换核图像进行FFT
	::DIBFFT_2D(pCTH, lLineBytes, lHeight, pCFH);
	
	// 计算M
	for (i = 0; i < lHeight * lLineBytes; i++)
	{
			// 赋值
			a = pCFSrc[i].real();
			b = pCFSrc[i].imag();
			c = pCFH[i].real();
			d = pCFH[i].imag();

			// |H(u,v)|*|H(u,v)|
			norm2 = c * c + d * d;

			// |H(u,v)|*|H(u,v)|/(|H(u,v)|*|H(u,v)|+a)
			temp  = (norm2 ) / (norm2 + pCFFilter[i]);

			{				
				tempre = ( a*c + b*d ) / ( c*c + d*d );
				tempim = ( b*c - a*d ) / ( c*c + d*d );

				// 求得f(u,v)
				pCFSrc[i]= complex<double>(temp*tempre , temp*tempim);
			}						
	}

	//对复原图像进行反FFT
	IFFT_2D(pCFSrc, pCTSrc, lLineBytes, lHeight);

	//转换为复原图像
	for (j = 0;j < lHeight ;j++)
	{
		for(i = 0;i < lLineBytes ;i++)
		{
			// 指向复原图像倒数第j行,第i个象素的指针			
 			lpSrc = (unsigned char *)lpDIBBits + lLineBytes * j + i;

			a = pCTSrc[(lLineBytes)*j + i].real();
			b = pCTSrc[(lLineBytes)*j + i].imag();

			norm2  = a*a + b*b;
			norm2  = sqrt(norm2) + 40;
	
			if(norm2 > 255)
				norm2 = 255.0;
			if(norm2 < 0)
				norm2 = 0;	

			*lpSrc = (unsigned char) (norm2);			
		}
	}

	//释放存储空间
	delete pCTSrc;
	delete pCTH;

	delete pCFSrc;
	delete pCFH;
	delete pCFFilter;

	// 返回
	return true;
}

/*************************************************************************
 *
 * 函数名称:
 *   DIBMotionDegeneration()
 *
 * 参数:
 *   CDib  *pDib       - 指向CDib类的指针
 *
 * 返回值:
 *   BOOL               - 成功返回TRUE,否则返回FALSE。
 *
 * 说明:
 *   该函数用来对DIB图像模拟由匀速直线运动造成的模糊
 *
 ***********************************************************************
 */

BOOL WINAPI DIBMotionDegeneration(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 iColumn;
	long jRow;

	//临时变量
	int temp,m;

	// 临时变量
	double p,q;
	
	int nTotTime, nTotLen, nTime;

	//总的运动时间10s
	nTotTime = 10;

	// 总的运动距离10个象素点
	nTotLen = 10;
	
	// 摄像机的暴光系数
	double B;

	B = 0.1;

	//用来存储源图象和变换核的时域数据
	int *nImageDegener;

	// 为时域和频域的数组分配空间
	nImageDegener = new int [lHeight*lLineBytes];
	
	// 将数据存入时域数组
	for (jRow = 0; jRow < lHeight; jRow++)
	{
		for(iColumn = 0; iColumn < lLineBytes; iColumn++)
		{
			temp=0;
			
			// 指向源图像倒数第jRow行,第iColumn个象素的指针			
			lpSrc = (unsigned char *)lpDIBBits + lLineBytes * jRow + iColumn;

			// 象素点的象素值积累
			for ( nTime = 0; nTime < nTotTime; nTime++ )
			{
				p = (float)iColumn - (float)(nTotLen)*nTime/nTotTime;
				
				if (p > 0)
				{
					q = p - floor((double)p);
					
					if(q >= 0.5)
						m = (int)ceil((double)p);
					else
						m = (int)floor((double)p);

					// 累加
					lpSrc = (unsigned char *)lpDIBBits + lLineBytes * jRow + m;
					temp = temp + *lpSrc;
				}	
			}
			
			// 乘以摄像机的暴光系数
			temp = B * temp;

			temp=(int)ceil((double)temp);
			
			// 使得temp的取值符合取值范围
			if(temp<0)
				temp=0;

			if(temp>255)
				temp=255;

			nImageDegener[lLineBytes*jRow + iColumn] = temp;
		}
	}	
	
	//转换为图像
	for (jRow = 0;jRow < lHeight ;jRow++)
	{
		for(iColumn = 0;iColumn < lLineBytes ;iColumn++)
		{
			// 指向源图像倒数第jRow行,第iColumn个象素的指针			
 			lpSrc = (unsigned char *)lpDIBBits + lLineBytes * jRow + iColumn;
	
			*lpSrc = nImageDegener[lLineBytes*jRow + iColumn];
		}
	}
	
	//释放存储空间
	delete nImageDegener;
	
	// 返回
	return true;
}

/*************************************************************************
 *
 * 函数名称:
 *   DIBMotionRestore()
 *
 * 参数:
 *   CDib  *pDib       - 指向CDib类的指针
 *
 * 返回值:
 *   BOOL               - 成功返回TRUE,否则返回FALSE。
 *
 * 说明:
 *   该函数用来对拟由匀速直线运动造成的模糊图象进行复原
 *
 ***********************************************************************
 */

BOOL WINAPI DIBMotionRestore(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 iColumn;
	long jRow;

	int i,n,m;

	//临时变量
	int temp1,temp2,
		totalq,q1,q2,z;

	double p,q;

	// 常量A赋值
	int A = 80;
	
	//常量B赋值
	int B = 10;
	
	//总的移动距离
	int nTotLen=10;

	// 图象宽度包含多少个ntotlen
	int K=lLineBytes/nTotLen;
	
	int error[10];

	//用来存储源图象时域数据
	int *nImageDegener;

	// 为时域数组分配空间
	nImageDegener = new int [lHeight*lLineBytes];

	// 将象素存入数组中
	for (jRow = 0; jRow < lHeight; jRow++)
	{
		for(iColumn = 0; iColumn < lLineBytes; iColumn++)
		{
			lpSrc = (unsigned char *)lpDIBBits + lLineBytes * jRow + iColumn;
	
			nImageDegener[lLineBytes*jRow + iColumn] = (*lpSrc);
		}
	}	
	
	for (jRow = 0; jRow < lHeight; jRow++)
	{		
		// 计算error[i]
		for(i = 0; i < 10; i++)
		{
			
			error[i] = 0;
			
			for(n = 0; n < K; n++)
				for(m = 0; m <= n; m++)
				{
					// 象素是否为一行的开始处
					if(i == 0 && m == 0)
					{
						temp1=temp2=0;
					}
					
					// 进行差分运算
					else
					{
						lpSrc = (unsigned char *)lpDIBBits + lLineBytes * jRow + m*10+i;
						temp1=*lpSrc;
						
						lpSrc = (unsigned char *)lpDIBBits + lLineBytes * jRow + m*10+i-1;
						temp2 = *lpSrc;
					}
					
					error[i] = error[i] + temp1 - temp2;
					
				}				
			
				error[i] = B * error[i] / K;
		}
		
		for(iColumn = 0; iColumn < lLineBytes; iColumn++)
		{			
			// 计算m,以及z
			m = iColumn / nTotLen;
			z = iColumn - m*nTotLen;			
			
			// 初始化
			totalq = 0;
			q = 0;
			
			for(n = 0; n <= m; n++)
			{
				q1 = iColumn - nTotLen*n;
				
				if(q1 == 0)
					q = 0;
				
				// 进行差分运算
				else
				{
					q2 = q1 - 1;
					
					lpSrc = (unsigned char *)lpDIBBits + lLineBytes * jRow + q1;
					temp1 = *lpSrc;
					
					lpSrc = (unsigned char *)lpDIBBits + lLineBytes * jRow + q2;
					temp2 = *lpSrc;
					
					q = (temp1 - temp2) * B;				
				}
				
				totalq = totalq + q;
			}
			
			p = error[z];

			// 得到f(x,y)的值
			temp1 = totalq + A - p;
			
			// 使得象素的取值符合取值范围
			if(temp1 < 0)
				temp1 = 0;
			
			if(temp1 > 255)
				temp1 = 255;
						
			nImageDegener[lLineBytes*jRow + iColumn] = temp1;
		}
	}

	//转换为图像
	for (jRow = 0;jRow < lHeight ;jRow++)
	{
		for(iColumn = 0;iColumn < lLineBytes ;iColumn++)
		{
			// 指向源图像倒数第jRow行,第iColumn个象素的指针			
 			lpSrc = (unsigned char *)lpDIBBits + lLineBytes * jRow + iColumn;
	
			// 存储象素值
			*lpSrc = nImageDegener[lLineBytes*jRow + iColumn];
		}
	}	
	
	//释放存储空间
	delete nImageDegener;
	
	// 返回
	return true;
}
#undef SWAP

⌨️ 快捷键说明

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