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

📄 globalapi.cpp

📁 用vc实现的小波分析的mallat算法用以实现图像融合
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		ReleaseDC( NULL, hDC );
		
		return FALSE;
	}

	// 将指针保存在CDib对象的数据成员中
	pDibDest->m_lpBMIH  = lpBMIH;
	pDibDest->m_lpImage = lpImage;
	pDibDest->m_nBmihAlloc = pDibDest->m_nImageAlloc = pDibDest->crtAlloc;


	// 删除临时变量
	SelectPalette(hDC, hPal, TRUE); 
	RealizePalette(hDC); 
	ReleaseDC(NULL, hDC); 
	return TRUE;
}


/*************************************************************************
 *
 * \函数名称:
 *   CopyDIB()
 *
 * \输入参数:
 *   CDib*	pDibSrc			- 指向源数据的CDib对象指针
 *   CDib*	pDibDst			- 指向拷贝目标的CDib对象指针
 *
 * \返回值:
 *   BOOL				- 如果操作成功,则返回TRUE
 *
 * \说明:
 *   该函数将源CDib类pDibSrc中的数据拷贝到pDibDst中,并对相应的数据成员赋值
 *
 *************************************************************************
 */
BOOL CopyDIB(CDib* pDibSrc, CDib* pDibDst)
{
	// 将目的CDib对象清空
	pDibDst->Empty();
	
	// 计算信息头加上调色板的大小,并分配相应的内存
	int nSizeHdr = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * pDibSrc->m_nColorTableEntries;

	pDibDst->m_lpBMIH = (LPBITMAPINFOHEADER) new char[nSizeHdr];
	pDibDst->m_nBmihAlloc = pDibDst->m_nImageAlloc = pDibDst->crtAlloc;

	try{
		
		// 拷贝信息头和调色板
		memcpy(pDibDst->m_lpBMIH,pDibSrc->m_lpBMIH,nSizeHdr);
		
		
		// 如果结构的长度不对,则进行错误处理
		if(pDibDst->m_lpBMIH->biSize != sizeof(BITMAPINFOHEADER)) {
			TRACE("Not a valid Windows bitmap -- probably an OS/2 bitmap\n");
			throw new CException;
		}

		// 保存图象数据内存大小到CDib对象的数据成员中
		pDibDst->m_dwSizeImage = pDibDst->m_lpBMIH->biSizeImage;

		// 如果图象数据内存大小为0,则重新计算
		if(pDibDst->m_dwSizeImage == 0) {
			DWORD dwBytes = ((DWORD) pDibDst->m_lpBMIH->biWidth * pDibDst->m_lpBMIH->biBitCount) / 32;
			if(((DWORD) pDibDst->m_lpBMIH->biWidth * pDibDst->m_lpBMIH->biBitCount) % 32) {
				dwBytes++;
			}
			dwBytes *= 4;
			pDibDst->m_dwSizeImage = dwBytes * pDibDst->m_lpBMIH->biHeight; 
		}

		// 设置DIB中的调色板指针
		pDibDst->m_lpvColorTable = (LPBYTE) pDibDst->m_lpBMIH + sizeof(BITMAPINFOHEADER);

		// 计算调色板的表项数
		pDibDst->ComputePaletteSize(pDibDst->m_lpBMIH->biBitCount);

		// 如果DIB中存在调色板,则创建一个Windows调色板
		pDibDst->MakePalette();

		// 分配图象数据内存,并拷贝图象数据
		pDibDst->m_lpImage = (LPBYTE) new char[pDibDst->m_dwSizeImage];
		memcpy(pDibDst->m_lpImage, pDibSrc->m_lpImage,pDibDst->m_dwSizeImage);
	}

	catch(CException* pe) 
	{
		AfxMessageBox("Copy DIB error");
		pDibDst->Empty();
		pe->Delete();
		return FALSE;
	}
	
	return TRUE;
}


/*************************************************************************
 *
 * \函数名称:
 *   CopyScreenToDIB
 *
 * \输入参数:
 *   LPRECT	lpRect			- 需要拷贝的屏幕区域
 *   CDib*	pDibDest		- 指向目标CDib对象的指针
 *
 * \返回值:
 *   BOOL				- 如果操作成功,则返回TRUE
 *
 * \说明:
 *   该函数将指定矩形位置内的屏幕内容拷贝到DIB中源CDib类pDibSrc中的数据拷贝到pDibDst中
 *
 *************************************************************************
 */
BOOL CopyScreenToDIB(LPRECT lpRect, CDib* pDibDest)
{
	// 屏幕设备上下文和内存设备上下文句柄
	HDC         hScrDC, hMemDC;         

	// 声明BITMAP临时句柄和以前的BITMAP句柄
	HBITMAP     hBitmap, hOldBitmap;    

	// 调色板句柄
	HPALETTE    hPalette;       
    
	// 获取矩形区域的坐标
	int         nX, nY, nX2, nY2;

	// DIB图象的高度和宽度
	int         nWidth, nHeight; 

	// 屏幕分辨率
	int         xScrn, yScrn;    
 
        // 如果给定的矩形区域为空,则不进行进一步的处理
	if (IsRectEmpty(lpRect)) 
		return FALSE; 
 
    	// 得到一个屏幕设备上下文
	hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL); 

	// 创建与屏幕设备兼容的内存设备上下文
	hMemDC = CreateCompatibleDC(hScrDC); 
 
	// 得到矩形的区域坐标
	nX = lpRect->left; 
	nY = lpRect->top; 
	nX2 = lpRect->right; 
	nY2 = lpRect->bottom; 
 
	// 得到屏幕的分辨率,以便后面的判断处理
	xScrn = GetDeviceCaps(hScrDC, HORZRES); 
	yScrn = GetDeviceCaps(hScrDC, VERTRES); 
 
	// 判断矩形区域是否超出屏幕
 
	if (nX < 0) 
		nX = 0; 
	if (nY < 0) 
	        nY = 0; 
	if (nX2 > xScrn) 
	        nX2 = xScrn; 
	if (nY2 > yScrn) 
	        nY2 = yScrn; 
 
	// 计算DIB图象的高度和宽度
	nWidth = nX2 - nX; 
	nHeight = nY2 - nY; 
 
	// 创建一个与屏幕设备上下文兼容的DDB位图
	hBitmap = CreateCompatibleBitmap(hScrDC, nWidth, nHeight); 
 
	// 将DDB位图选入内存设备上下文
	hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap); 
 
	// 将屏幕中指定区域的图象传输到内存设备上下文中
	BitBlt(hMemDC, 0, 0, nWidth, nHeight, hScrDC, nX, nY, SRCCOPY); 
 
	// 然后将以前的图象选入,并得到屏幕区域的DDB图象句柄
	hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap); 
 
	// 将临时的设备上下文删除
	DeleteDC(hScrDC); 
	DeleteDC(hMemDC); 
 
	// 得到当前系统调色板
	hPalette = GetSystemPalette(); 
 
	// 将DDB图象转换为DIB图象
	pDibDest->ConvertFromDDB(hBitmap,hPalette);
	
	// 删除临时对象
	DeleteObject(hPalette); 
	DeleteObject(hBitmap); 
	
	return TRUE;
}

void Laplacian(LPBYTE lpImage, int nWidth, int nHeight, int nSaveWidth, double* pdGrad)
{
	int x, y;
	// 初始化
	for(y=0; y<nHeight ; y++ )
		for(x=0 ; x<nWidth ; x++ )
		{
			*(pdGrad+y*nWidth+x)=0;
		}

	// 设置模板系数
	static int nWeight[3][3] ;
	nWeight[0][0] = -1 ;   
	nWeight[0][1] = -1 ;   
	nWeight[0][2] = -1 ;   
	nWeight[1][0] = -1 ;   
	nWeight[1][1] =  8 ;   
	nWeight[1][2] = -1 ;   
	nWeight[2][0] = -1 ;   
	nWeight[2][1] = -1 ;   
	nWeight[2][2] = -1 ;   



	//这个变量用来表示Laplacian算子象素值
	int nTmp[3][3];
	
	// 临时变量
	double dGrad;

	// 模板循环控制变量
	int yy ;
	int xx ;

	
	// 下面开始利用Laplacian算子进行计算,为了保证计算所需要的
	// 的数据位于图像数据的内部,下面的两重循环的条件是
	// y<nHeight-2 而不是y<nHeight,相应的x方向也是x<nWidth-2
	// 而不是x<nWidth
	for(y=1; y<nHeight-2 ; y++ )
		for(x=1 ; x<nWidth-2 ; x++ )
		{
			dGrad = 0 ; 
			// Laplacian算子需要的各点象素值

			// 模板第一行
			nTmp[0][0] = lpImage[(y-1)*nSaveWidth + x - 1 ] ; 
			nTmp[0][1] = lpImage[(y-1)*nSaveWidth + x     ] ; 
			nTmp[0][2] = lpImage[(y-1)*nSaveWidth + x + 1 ] ; 

			// 模板第二行
			nTmp[1][0] = lpImage[y*nSaveWidth + x - 1 ] ; 
			nTmp[1][1] = lpImage[y*nSaveWidth + x     ] ; 
			nTmp[1][2] = lpImage[y*nSaveWidth + x + 1 ] ; 

			// 模板第三行
			nTmp[2][0] = lpImage[(y+1)*nSaveWidth + x - 1 ] ; 
			nTmp[2][1] = lpImage[(y+1)*nSaveWidth + x     ] ; 
			nTmp[2][2] = lpImage[(y+1)*nSaveWidth + x + 1 ] ; 
			
			// 计算梯度
			for(yy=0; yy<3; yy++)
				for(xx=0; xx<3; xx++)
				{
					dGrad += nTmp[yy][xx] * nWeight[yy][xx] ;
				}
			
			// 梯度值写入内存
			*(pdGrad+y*nWidth+x)=dGrad;
		}
}

void MakeGauss(double sigma, double **pdKernel, int *pnWindowSize)
{
	// 循环控制变量
	int i   ;
	
	// 数组的中心点
	int nCenter;

	// 数组的某一点到中心点的距离
	double  dDis  ; 

	double PI = 3.14159;
	// 中间变量
	double  dValue; 
	double  dSum  ;
	dSum = 0 ; 
	
	// 数组长度,根据概率论的知识,选取[-3*sigma, 3*sigma]以内的数据。
	// 这些数据会覆盖绝大部分的滤波系数
	*pnWindowSize = 1 + 2 * ceil(3 * sigma);
	
	// 中心
	nCenter = (*pnWindowSize) / 2;
	
	// 分配内存
	*pdKernel = new double[*pnWindowSize] ;
	
	for(i=0; i< (*pnWindowSize); i++)
	{
		dDis = (double)(i - nCenter);
		dValue = exp(-(1/2)*dDis*dDis/(sigma*sigma)) / (sqrt(2 * PI) * sigma );
		(*pdKernel)[i] = dValue ;
		dSum += dValue;
	}
	
	// 归一化
	for(i=0; i<(*pnWindowSize) ; i++)
	{
		(*pdKernel)[i] /= dSum;
	}
}

/*************************************************************************
 *
 * \函数名称:
 *   GaussianSmooth()
 *
 * \输入参数:
 *   unsigned char * pUnchImg				- 指向图象数据的指针
 *   int nWidth											- 图象数据宽度
 *   int nHeight										- 图象数据高度
 *   double dSigma									- 高斯函数的标准差
 *   unsigned char * pUnchSmthdImg	- 指向经过平滑之后的图象数据
 *
 * \返回值:
 *   无
 *
 * \说明:
 *   为了抑止噪声,采用高斯滤波对图象进行滤波,滤波先对x方向进行,然后对
 *   y方向进行。
 *   
 *************************************************************************
 */
void GaussianSmooth(unsigned char *pUnchImg, int nWidth, int nHeight, 
										double sigma, unsigned char * pUnchSmthdImg)
{
	// 循环控制变量
  int y;
	int x;
	
	int i;
	
	// 高斯滤波器的数组长度
	
	int nWindowSize;
	
	//  窗口长度的1/2
	int	nHalfLen;   
	
	// 一维高斯数据滤波器
	double *pdKernel ;
	
	// 高斯系数与图象数据的点乘
	double  dDotMul     ;
	
	// 高斯滤波系数的总和
	double  dWeightSum     ;          
  
	// 中间变量
	double * pdTmp ;
	
	// 分配内存
	pdTmp = new double[nWidth*nHeight];
	
	// 产生一维高斯数据滤波器
	// MakeGauss(sigma, &dKernel, &nWindowSize);
	MakeGauss(sigma, &pdKernel, &nWindowSize) ;
	
	// MakeGauss返回窗口的长度,利用此变量计算窗口的半长
	nHalfLen = nWindowSize / 2;
	
  // x方向进行滤波
	for(y=0; y<nHeight; y++)
	{
		for(x=0; x<nWidth; x++)
		{
			dDotMul		= 0;
			dWeightSum = 0;
			for(i=(-nHalfLen); i<=nHalfLen; i++)
			{
				// 判断是否在图象内部
				if( (i+x) >= 0  && (i+x) < nWidth )
				{
					dDotMul += (double)pUnchImg[y*nWidth + (i+x)] * pdKernel[nHalfLen+i];
					dWeightSum += pdKernel[nHalfLen+i];
				}
			}
			pdTmp[y*nWidth + x] = dDotMul/dWeightSum ;
		}
	}
	
	// y方向进行滤波
	for(x=0; x<nWidth; x++)
	{
		for(y=0; y<nHeight; y++)
		{
			dDotMul		= 0;
			dWeightSum = 0;
			for(i=(-nHalfLen); i<=nHalfLen; i++)
			{
				// 判断是否在图象内部
				if( (i+y) >= 0  && (i+y) < nHeight )
				{
					dDotMul += (double)pdTmp[(y+i)*nWidth + x] * pdKernel[nHalfLen+i];
					dWeightSum += pdKernel[nHalfLen+i];
				}
			}
			pUnchSmthdImg[y*nWidth + x] = (unsigned char)(int)dDotMul/dWeightSum ;
		}
	}

	// 释放内存
	delete []pdKernel;
	pdKernel = NULL ;
	
	delete []pdTmp;
	pdTmp = NULL;
}


/*************************************************************************
 *
 * \函数名称:
 *   DirGrad()
 *
 * \输入参数:
 *   unsigned char *pUnchSmthdImg					- 经过高斯滤波后的图象
 *   int nWidht														- 图象宽度
 *   int nHeight      										- 图象高度
 *   int *pnGradX                         - x方向的方向导数
 *   int *pnGradY                         - y方向的方向导数
 * \返回值:
 *   无
 *
 * \说明:
 *   这个函数计算方向倒数,采用的微分算子是(-1 0 1) 和 (-1 0 1)'(转置)
 *   计算的时候对边界象素采用了特殊处理
 *   
 *   
 *************************************************************************
 */
void DirGrad(unsigned char *pUnchSmthdImg, int nWidth, int nHeight,
										 int *pnGradX , int *pnGradY)
{
	// 循环控制变量
	int y ;
	int x ;
	
	// 计算x方向的方向导数,在边界出进行了处理,防止要访问的象素出界
	for(y=0; y<nHeight; y++)
	{
		for(x=0; x<nWidth; x++)
		{
			pnGradX[y*nWidth+x] = (int) ( pUnchSmthdImg[y*nWidth+min(nWidth-1,x+1)]  
													          - pUnchSmthdImg[y*nWidth+max(0,x-1)]     );
		}
	}

	// 计算y方向的方向导数,在边界出进行了处理,防止要访问的象素出界
	for(x=0; x<nWidth; x++)
	{
		for(y=0; y<nHeight; y++)
		{
			pnGradY[y*nWidth+x] = (int) ( pUnchSmthdImg[min(nHeight-1,y+1)*nWidth + x]  
																		- pUnchSmthdImg[max(0,y-1)*nWidth+ x ]     );
		}
	}
}
/*************************************************************************
 *
 * \函数名称:
 *   GradMagnitude()
 *
 * \输入参数:
 *   int *pnGradX                         - x方向的方向导数
 *   int *pnGradY                         - y方向的方向导数
 *   int nWidht														- 图象宽度
 *   int nHeight      										- 图象高度
 *   int *pnMag                           - 梯度幅度   
 *
 * \返回值:
 *   无
 *
 * \说明:
 *   这个函数利用方向倒数计算梯度幅度,方向倒数是DirGrad函数计算的结果
 *   
 *************************************************************************
 */
void GradMagnitude(int *pnGradX, int *pnGradY, int nWidth, int nHeight, int *pnMag)

⌨️ 快捷键说明

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