📄 templatetrans.cpp
字号:
/************************************************************************** * 文件名: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; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -