www.pudn.com > license_orientation.rar > TemplateTrans.cpp, change:2001-01-07,size:11344b


 
/************************************************************************** 
 *  文件名:TemplateTrans.cpp 
 * 
 *  图像模板变换API函数库: 
 * 
 *  Template()			- 图像模板变换,通过改变模板,可以用它实现 
 *						  图像的平滑、锐化、边缘识别等操作。 
 *  MedianFilter()		- 图像中值滤波。 
 *  GetMedianNum()		- 获取中值。被函数MedianFilter()调用来求中值。 
 *  ReplaceColorPal()	- 更换伪彩色编码表。 
 * 
 *************************************************************************/ 
 
#include "stdafx.h" 
#include "TemplateTrans.h" 
#include "DIBAPI.h" 
 
#include <math.h> 
#include <direct.h> 
 
/************************************************************************* 
 * 
 * 函数名称: 
 *   Template() 
 * 
 * 参数: 
 *   LPSTR lpDIBBits    - 指向源DIB图像指针 
 *   LONG  lWidth       - 源图像宽度(象素数) 
 *   LONG  lHeight      - 源图像高度(象素数) 
 *   int   iTempH		- 模板的高度 
 *   int   iTempW		- 模板的宽度 
 *   int   iTempMX		- 模板的中心元素X坐标 ( < iTempW - 1) 
 *   int   iTempMY		- 模板的中心元素Y坐标 ( < iTempH - 1) 
 *	 FLOAT * fpArray	- 指向模板数组的指针 
 *	 FLOAT fCoef		- 模板系数 
 * 
 * 返回值: 
 *   BOOL               - 成功返回TRUE,否则返回FALSE。 
 * 
 * 说明: 
 *   该函数用指定的模板(任意大小)来对图像进行操作,参数iTempH指定模板 
 * 的高度,参数iTempW指定模板的宽度,参数iTempMX和iTempMY指定模板的中心 
 * 元素坐标,参数fpArray指定模板元素,fCoef指定系数。 
 * 
 ************************************************************************/ 
 
BOOL WINAPI Template(LPSTR lpDIBBits, LONG lWidth, LONG lHeight,  
					 int iTempH, int iTempW,  
					 int iTempMX, int iTempMY, 
					 FLOAT * fpArray, FLOAT fCoef) 
{ 
	// 指向复制图像的指针 
	LPSTR	lpNewDIBBits; 
	HLOCAL	hNewDIBBits; 
	 
	// 指向源图像的指针 
	unsigned char*	lpSrc; 
	 
	// 指向要复制区域的指针 
	unsigned char*	lpDst; 
	 
	// 循环变量 
	LONG	i; 
	LONG	j; 
	LONG	k; 
	LONG	l; 
	 
	// 计算结果 
	FLOAT	fResult; 
	 
	// 图像每行的字节数 
	LONG lLineBytes; 
	 
	// 计算图像每行的字节数 
	lLineBytes = WIDTHBYTES(lWidth * 8); 
	 
	// 暂时分配内存,以保存新图像 
	hNewDIBBits = LocalAlloc(LHND, lLineBytes * lHeight); 
	 
	// 判断是否内存分配失败 
	if (hNewDIBBits == NULL) 
	{ 
		// 分配内存失败 
		return FALSE; 
	} 
	 
	// 锁定内存 
	lpNewDIBBits = (char * )LocalLock(hNewDIBBits); 
	 
	// 初始化图像为原始图像 
	memcpy(lpNewDIBBits, lpDIBBits, lLineBytes * lHeight); 
	 
	// 行(除去边缘几行) 
	for(i = iTempMY; i < lHeight - iTempH + iTempMY + 1; i++) 
	{ 
		// 列(除去边缘几列) 
		for(j = iTempMX; j < lWidth - iTempW + iTempMX + 1; j++) 
		{ 
			// 指向新DIB第i行,第j个象素的指针 
			lpDst = (unsigned char*)lpNewDIBBits + lLineBytes * (lHeight - 1 - i) + j; 
			 
			fResult = 0; 
			 
			// 计算 
			for (k = 0; k < iTempH; k++) 
			{ 
				for (l = 0; l < iTempW; l++) 
				{ 
					// 指向DIB第i - iTempMY + k行,第j - iTempMX + l个象素的指针 
					lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i + iTempMY - k) 
						+ j - iTempMX + l; 
					 
					// 保存象素值 
					fResult += (* lpSrc) * fpArray[k * iTempW + l]; 
				} 
			} 
			 
			// 乘上系数 
			fResult *= fCoef; 
			 
			// 取绝对值 
			fResult = (FLOAT ) fabs(fResult); 
			 
			// 判断是否超过255 
			if(fResult > 255) 
			{ 
				// 直接赋值为255 
				* lpDst = 255; 
			} 
			else 
			{ 
				// 赋值 
				* lpDst = (unsigned char) (fResult + 0.5); 
			} 
			 
		} 
	} 
	 
	// 复制变换后的图像 
	memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight); 
	 
	// 释放内存 
	LocalUnlock(hNewDIBBits); 
	LocalFree(hNewDIBBits); 
	 
	// 返回 
	return TRUE; 
 
} 
 
/************************************************************************* 
 * 
 * 函数名称: 
 *   MedianFilter() 
 * 
 * 参数: 
 *   LPSTR lpDIBBits		- 指向源DIB图像指针 
 *   LONG  lWidth			- 源图像宽度(象素数) 
 *   LONG  lHeight			- 源图像高度(象素数) 
 *   int   iFilterH			- 滤波器的高度 
 *   int   iFilterW			- 滤波器的宽度 
 *   int   iFilterMX		- 滤波器的中心元素X坐标 
 *   int   iFilterMY		- 滤波器的中心元素Y坐标 
 * 
 * 返回值: 
 *   BOOL					- 成功返回TRUE,否则返回FALSE。 
 * 
 * 说明: 
 *   该函数对DIB图像进行中值滤波。 
 * 
 ************************************************************************/ 
 
BOOL WINAPI MedianFilter(LPSTR lpDIBBits, LONG lWidth, LONG lHeight,  
						 int iFilterH, int iFilterW,  
						 int iFilterMX, int iFilterMY) 
{ 
	 
	// 指向源图像的指针 
	unsigned char*	lpSrc; 
	 
	// 指向要复制区域的指针 
	unsigned char*	lpDst; 
	 
	// 指向复制图像的指针 
	LPSTR			lpNewDIBBits; 
	HLOCAL			hNewDIBBits; 
	 
	// 指向滤波器数组的指针 
	unsigned char	* aValue; 
	HLOCAL			hArray; 
	 
	// 循环变量 
	LONG			i; 
	LONG			j; 
	LONG			k; 
	LONG			l; 
	 
	// 图像每行的字节数 
	LONG			lLineBytes; 
	 
	// 计算图像每行的字节数 
	lLineBytes = WIDTHBYTES(lWidth * 8); 
	 
	// 暂时分配内存,以保存新图像 
	hNewDIBBits = LocalAlloc(LHND, lLineBytes * lHeight); 
	 
	// 判断是否内存分配失败 
	if (hNewDIBBits == NULL) 
	{ 
		// 分配内存失败 
		return FALSE; 
	} 
	 
	// 锁定内存 
	lpNewDIBBits = (char * )LocalLock(hNewDIBBits); 
	 
	// 初始化图像为原始图像 
	memcpy(lpNewDIBBits, lpDIBBits, lLineBytes * lHeight); 
	 
	// 暂时分配内存,以保存滤波器数组 
	hArray = LocalAlloc(LHND, iFilterH * iFilterW); 
	 
	// 判断是否内存分配失败 
	if (hArray == NULL) 
	{ 
		// 释放内存 
		LocalUnlock(hNewDIBBits); 
		LocalFree(hNewDIBBits); 
		 
		// 分配内存失败 
		return FALSE; 
	} 
	 
	// 锁定内存 
	aValue = (unsigned char * )LocalLock(hArray); 
	 
	// 开始中值滤波 
	// 行(除去边缘几行) 
	for(i = iFilterMY; i < lHeight - iFilterH + iFilterMY + 1; i++) 
	{ 
		// 列(除去边缘几列) 
		for(j = iFilterMX; j < lWidth - iFilterW + iFilterMX + 1; j++) 
		{ 
			// 指向新DIB第i行,第j个象素的指针 
			lpDst = (unsigned char*)lpNewDIBBits + lLineBytes * (lHeight - 1 - i) + j; 
			 
			// 读取滤波器数组 
			for (k = 0; k < iFilterH; k++) 
			{ 
				for (l = 0; l < iFilterW; l++) 
				{ 
					// 指向DIB第i - iFilterMY + k行,第j - iFilterMX + l个象素的指针 
					lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i + iFilterMY - k) + j - iFilterMX + l; 
					 
					// 保存象素值 
					aValue[k * iFilterW + l] = *lpSrc; 
				} 
			} 
			 
			// 获取中值 
			* lpDst = GetMedianNum(aValue, iFilterH * iFilterW); 
		} 
	} 
	 
	// 复制变换后的图像 
	memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight); 
	 
	// 释放内存 
	LocalUnlock(hNewDIBBits); 
	LocalFree(hNewDIBBits); 
	LocalUnlock(hArray); 
	LocalFree(hArray); 
	 
	// 返回 
	return TRUE; 
} 
 
/************************************************************************* 
 * 
 * 函数名称: 
 *   GetMedianNum() 
 * 
 * 参数: 
 *   unsigned char * bpArray	- 指向要获取中值的数组指针 
 *   int   iFilterLen			- 数组长度 
 * 
 * 返回值: 
 *   unsigned char      - 返回指定数组的中值。 
 * 
 * 说明: 
 *   该函数用冒泡法对一维数组进行排序,并返回数组元素的中值。 
 * 
 ************************************************************************/ 
 
unsigned char WINAPI GetMedianNum(unsigned char * bArray, int iFilterLen) 
{ 
	// 循环变量 
	int		i; 
	int		j; 
	 
	// 中间变量 
	unsigned char bTemp; 
	 
	// 用冒泡法对数组进行排序 
	for (j = 0; j < iFilterLen - 1; j ++) 
	{ 
		for (i = 0; i < iFilterLen - j - 1; i ++) 
		{ 
			if (bArray[i] > bArray[i + 1]) 
			{ 
				// 互换 
				bTemp = bArray[i]; 
				bArray[i] = bArray[i + 1]; 
				bArray[i + 1] = bTemp; 
			} 
		} 
	} 
	 
	// 计算中值 
	if ((iFilterLen & 1) > 0) 
	{ 
		// 数组有奇数个元素,返回中间一个元素 
		bTemp = bArray[(iFilterLen + 1) / 2]; 
	} 
	else 
	{ 
		// 数组有偶数个元素,返回中间两个元素平均值 
		bTemp = (bArray[iFilterLen / 2] + bArray[iFilterLen / 2 + 1]) / 2; 
	} 
	 
	// 返回中值 
	return bTemp; 
} 
 
/************************************************************************* 
 * 
 * 函数名称: 
 *   GradSharp() 
 * 
 * 参数: 
 *   LPSTR lpDIBBits    - 指向源DIB图像指针 
 *   LONG  lWidth       - 源图像宽度(象素数) 
 *   LONG  lHeight      - 源图像高度(象素数) 
 *   BYTE  bThre		- 阈值 
 * 
 * 返回值: 
 *   BOOL               - 成功返回TRUE,否则返回FALSE。 
 * 
 * 说明: 
 *   该函数用来对图像进行梯度锐化。 
 * 
 ************************************************************************/ 
BOOL WINAPI GradSharp(LPSTR lpDIBBits, LONG lWidth, LONG lHeight, BYTE bThre) 
{ 
	 
	// 指向源图像的指针 
	unsigned char*	lpSrc; 
	unsigned char*	lpSrc1; 
	unsigned char*	lpSrc2; 
	 
	// 循环变量 
	LONG	i; 
	LONG	j; 
	 
	// 图像每行的字节数 
	LONG	lLineBytes; 
	 
	// 中间变量 
	BYTE	bTemp; 
	 
	// 计算图像每行的字节数 
	lLineBytes = WIDTHBYTES(lWidth * 8); 
	 
	// 每行 
	for(i = 0; i < lHeight; i++) 
	{ 
		// 每列 
		for(j = 0; j < lWidth; j++) 
		{ 
			// 指向DIB第i行,第j个象素的指针 
			lpSrc  = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j; 
			 
			// 指向DIB第i+1行,第j个象素的指针 
			lpSrc1 = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 2 - i) + j; 
			 
			// 指向DIB第i行,第j+1个象素的指针 
			lpSrc2 = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j + 1; 
			 
			bTemp = abs((*lpSrc)-(*lpSrc1)) + abs((*lpSrc)-(*lpSrc2)); 
			 
			// 判断是否小于阈值 
			if (bTemp < 255) 
			{ 
				// 判断是否大于阈值,对于小于情况,灰度值不变。 
				if (bTemp >= bThre) 
				{ 
					// 直接赋值为bTemp 
					*lpSrc = bTemp; 
				} 
			} 
			else 
			{ 
				// 直接赋值为255 
				*lpSrc = 255; 
			} 
		} 
	} 
	 
	// 返回 
	return TRUE; 
} 
 
/************************************************************************* 
 * 
 * 函数名称: 
 *   ReplaceColorPal() 
 * 
 * 参数: 
 *   LPSTR lpDIB			- 指向源DIB图像指针 
 *   BYTE * bpColorsTable	- 伪彩色编码表 
 * 
 * 返回值: 
 *   BOOL					- 成功返回TRUE,否则返回FALSE。 
 * 
 * 说明: 
 *   该函数用指定的伪彩色编码表来替换图像的调试板,参数bpColorsTable 
 * 指向要替换的伪彩色编码表。 
 * 
 ************************************************************************/ 
BOOL WINAPI ReplaceColorPal(LPSTR lpDIB, BYTE * bpColorsTable) 
{ 
	 
	// 循环变量 
	int i; 
	 
	// 颜色表中的颜色数目 
	WORD wNumColors; 
	 
	// 指向BITMAPINFO结构的指针(Win3.0) 
	LPBITMAPINFO lpbmi; 
	 
	// 指向BITMAPCOREINFO结构的指针 
	LPBITMAPCOREINFO lpbmc; 
	 
	// 表明是否是Win3.0 DIB的标记 
	BOOL bWinStyleDIB; 
	 
	// 创建结果 
	BOOL bResult = FALSE; 
	 
	// 获取指向BITMAPINFO结构的指针(Win3.0) 
	lpbmi = (LPBITMAPINFO)lpDIB; 
	 
	// 获取指向BITMAPCOREINFO结构的指针 
	lpbmc = (LPBITMAPCOREINFO)lpDIB; 
	 
	// 获取DIB中颜色表中的颜色数目 
	wNumColors = ::DIBNumColors(lpDIB); 
		 
	// 判断颜色数目是否是256色 
	if (wNumColors == 256) 
	{ 
		 
		// 判断是否是WIN3.0的DIB 
		bWinStyleDIB = IS_WIN30_DIB(lpDIB); 
		 
		// 读取伪彩色编码,更新DIB调色板 
		for (i = 0; i < (int)wNumColors; i++) 
		{ 
			if (bWinStyleDIB) 
			{ 
				// 更新DIB调色板红色分量 
				lpbmi->bmiColors[i].rgbRed = bpColorsTable[i * 4]; 
				 
				// 更新DIB调色板绿色分量 
				lpbmi->bmiColors[i].rgbGreen = bpColorsTable[i * 4 + 1]; 
				 
				// 更新DIB调色板蓝色分量 
				lpbmi->bmiColors[i].rgbBlue = bpColorsTable[i * 4 + 2]; 
				 
				// 更新DIB调色板保留位 
				lpbmi->bmiColors[i].rgbReserved = 0; 
			} 
			else 
			{ 
				// 更新DIB调色板红色分量 
				lpbmc->bmciColors[i].rgbtRed = bpColorsTable[i * 4]; 
				 
				// 更新DIB调色板绿色分量 
				lpbmc->bmciColors[i].rgbtGreen = bpColorsTable[i * 4 + 1]; 
				 
				// 更新DIB调色板蓝色分量 
				lpbmc->bmciColors[i].rgbtBlue = bpColorsTable[i * 4 + 2]; 
			} 
		} 
	} 
	 
	// 返回 
	return bResult;	 
 
}