www.pudn.com > Image_Manage.rar > FUNCAPI.CPP
/************************************************************************** * 文件名:funcapi.cpp * * 图像点运算API函数库: * * Template() - 用指定的模板(任意大小)来对图像进行操作 * *************************************************************************/ #include "stdafx.h" #include "DIBAPI.H" #include "FUNCAPI.H" #include#include /************************************************************************* * * 函数名称: * 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 - 模板系数 * int nBitCount - 像素位数 * * 返回值: * 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, int nBitCount) { // 指向复制图像的指针 LPSTR lpNewDIBBits; HLOCAL hNewDIBBits; // 指向源图像的指针 unsigned char* lpSrc; // 指向要复制区域的指针 unsigned char* lpDst; // 循环变量 LONG i; LONG j; LONG k; LONG l; int rgb; // 计算结果 FLOAT fResult; // 图像每行的字节数 LONG lLineBytes; // 计算图像每行的字节数 switch(nBitCount) { case 8: lLineBytes = WIDTHBYTES(lWidth * 8); break; case 24: lLineBytes = WIDTHBYTES(lWidth * 24); } // 暂时分配内存,以保存新图像 hNewDIBBits = LocalAlloc(LHND, lLineBytes * lHeight); // 判断是否内存分配失败 if (hNewDIBBits == NULL) { // 分配内存失败 return FALSE; } // 锁定内存 lpNewDIBBits = (char * )LocalLock(hNewDIBBits); // 初始化图像为原始图像 memcpy(lpNewDIBBits, lpDIBBits, lLineBytes * lHeight); switch(nBitCount) { // 256色图像 case 8: // 行(除去边缘几行) 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); } } } break; // 真彩色图像 case 24: // 行(除去边缘几行) for(i = iTempMY; i < lHeight - iTempH + iTempMY + 1; i++) { // 列(除去边缘几列) for(j = iTempMX; j < lWidth - iTempW + iTempMX + 1; j++) { // 分别处理R, G, B 三种颜色 for(rgb=0;rgb<3;rgb++) { // 指向新DIB第i行,第j个象素的指针 lpDst = (unsigned char*)lpNewDIBBits + lLineBytes * (lHeight - 1 - i) + j * 3 + rgb; 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) * 3 +rgb; // 保存象素值 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); } } } } break; } // 复制变换后的图像 memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight); // 释放内存 LocalUnlock(hNewDIBBits); LocalFree(hNewDIBBits); // 返回 return TRUE; } /************************************************************************* * * 函数名称: * GradSharp() * * 参数: * LPSTR lpDIBBits - 指向源DIB图像指针 * LONG lWidth - 源图像宽度(象素数) * LONG lHeight - 源图像高度(象素数) * BYTE bThre - 阈值 * int nBitCount - 像素位数 * * 返回值: * BOOL - 成功返回TRUE,否则返回FALSE。 * * 说明: * 该函数用来对图像进行梯度锐化。 * ************************************************************************/ BOOL WINAPI GradSharp(LPSTR lpDIBBits, LONG lWidth, LONG lHeight, BYTE bThre, int nBitCount) { // 指向源图像的指针 unsigned char* lpSrc; unsigned char* lpSrc1; unsigned char* lpSrc2; // 循环变量 LONG i; LONG j; int k; // 图像每行的字节数 LONG lLineBytes; // 中间变量 BYTE bTemp; // 计算图像每行的字节数 switch(nBitCount) { case 8: 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; } } } break; case 24: lLineBytes = WIDTHBYTES(lWidth * 24); // 每行 for(i = 0; i < lHeight - 1; i++) { // 每列 for(j = 0; j < lWidth - 1; j++) { // 分别对每个像素的R, G, B值进行操作 for(k = 0; k < 3; k++) { // 指向DIB第i行,第j个象素的指针 lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j * 3 + k; // 指向DIB第i+1行,第j个象素的指针 lpSrc1 = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 2 - i) + j * 3 + k; // 指向DIB第i行,第j+1个象素的指针 lpSrc2 = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j * 3 + 3 + k; bTemp = abs((*lpSrc)-(*lpSrc1)) + abs((*lpSrc)-(*lpSrc2)); // 判断是否小于阈值 if (bTemp < 255) { // 判断是否大于阈值,对于小于情况,灰度值不变。 if (bTemp >= bThre) { // 直接赋值为bTemp *lpSrc = bTemp; } } else { // 直接赋值为255 *lpSrc = 255; } } } } } // 返回 return TRUE; } /************************************************************************* * * 函数名称: * MedianFilter() * * 参数: * LPSTR lpDIBBits - 指向源DIB图像指针 * LONG lWidth - 源图像宽度(象素数) * LONG lHeight - 源图像高度(象素数) * int iFilterH - 滤波器的高度 * int iFilterW - 滤波器的宽度 * int iFilterMX - 滤波器的中心元素X坐标 * int iFilterMY - 滤波器的中心元素Y坐标 * int nBitCount - 像素位数 * * 返回值: * BOOL - 成功返回TRUE,否则返回FALSE。 * * 说明: * 该函数对DIB图像进行中值滤波。 * ************************************************************************/ BOOL WINAPI MedianFilter(LPSTR lpDIBBits, LONG lWidth, LONG lHeight, int iFilterH, int iFilterW, int iFilterMX, int iFilterMY, int nBitCount) { // 指向源图像的指针 unsigned char* lpSrc; // 指向要复制区域的指针 unsigned char* lpDst; // 指向复制图像的指针 LPSTR lpNewDIBBits; HLOCAL hNewDIBBits; // 指向滤波器数组的指针 unsigned char * aValue; HLOCAL hArray; // 循环变量 LONG i; LONG j; LONG k; LONG l; int rgb; // 图像每行的字节数 LONG lLineBytes; // 计算图像每行的字节数 switch(nBitCount) { case 8: lLineBytes = WIDTHBYTES(lWidth * 8); break; case 24: lLineBytes = WIDTHBYTES(lWidth * 24); } // 暂时分配内存,以保存新图像 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); // 开始中值滤波 switch(nBitCount) { case 8: // 行(除去边缘几行) 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); } } break; case 24: // 行(除去边缘几行) for(i = iFilterMY; i < lHeight - iFilterH + iFilterMY + 1; i++) { // 列(除去边缘几列) for(j = iFilterMX; j < lWidth - iFilterW + iFilterMX + 1; j++) { for(rgb = 0; rgb < 3; rgb++) { // 指向新DIB第i行,第j个象素的指针 lpDst = (unsigned char*)lpNewDIBBits + lLineBytes * (lHeight - 1 - i) + j * 3 + rgb; // 读取滤波器数组 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) * 3 + rgb; // 保存象素值 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; } /************************************************************************* * * 函数名称: * GaussDIB() * * 参数: * LPSTR lpDIBBits - 指向源DIB图像指针 * LONG lWidth - 源图像宽度(象素数,必须是4的倍数) * LONG lHeight - 源图像高度(象素数) * 返回值: * BOOL - 边缘检测成功返回TRUE,否则返回FALSE。 * * 说明: * 该函数用高斯拉普拉斯边缘检测算子对图像进行边缘检测运算。 * * 要求目标图像为灰度图像。 ************************************************************************/ BOOL WINAPI GaussDIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight, int nBitCount) { // 指向缓存图像的指针 LPSTR lpDst1; LPSTR lpDst2; // 指向缓存DIB图像的指针 LPSTR lpNewDIBBits1; HLOCAL hNewDIBBits1; LPSTR lpNewDIBBits2; HLOCAL hNewDIBBits2; // 模板高度 int iTempH; // 模板宽度 int iTempW; // 模板系数 FLOAT fTempC; // 模板中心元素X坐标 int iTempMX; // 模板中心元素Y坐标 int iTempMY; //模板数组 FLOAT aTemplate[25]; // 暂时分配内存,以保存新图像 hNewDIBBits1 = LocalAlloc(LHND, lWidth * lHeight * (nBitCount / 8)); if (hNewDIBBits1 == NULL) { // 分配内存失败 return FALSE; } // 锁定内存 lpNewDIBBits1 = (char * )LocalLock(hNewDIBBits1); // 暂时分配内存,以保存新图像 hNewDIBBits2 = LocalAlloc(LHND, lWidth * lHeight * (nBitCount / 8)); if (hNewDIBBits2 == NULL) { // 分配内存失败 return FALSE; } // 锁定内存 lpNewDIBBits2 = (char * )LocalLock(hNewDIBBits2); // 拷贝源图像到缓存图像中 lpDst1 = (char *)lpNewDIBBits1; memcpy(lpNewDIBBits1, lpDIBBits, lWidth * lHeight * (nBitCount / 8)); lpDst2 = (char *)lpNewDIBBits2; memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight * (nBitCount / 8)); // 设置Gauss模板参数 iTempW = 5; iTempH = 5; fTempC = 1.0; iTempMX = 3; iTempMY = 3; aTemplate[0] = -2.0; aTemplate[1] = -4.0; aTemplate[2] = -4.0; aTemplate[3] = -4.0; aTemplate[4] = -2.0; aTemplate[5] = -4.0; aTemplate[6] = 0.0; aTemplate[7] = 8.0; aTemplate[8] = 0.0; aTemplate[9] = -4.0; aTemplate[10] = -4.0; aTemplate[11] = 8.0; aTemplate[12] = 24.0; aTemplate[13] = 8.0; aTemplate[14] = -4.0; aTemplate[15] = -4.0; aTemplate[16] = 0.0; aTemplate[17] = 8.0; aTemplate[18] = 0.0; aTemplate[19] = -4.0; aTemplate[20] = -2.0; aTemplate[21] = -4.0; aTemplate[22] = -4.0; aTemplate[23] = -4.0; aTemplate[24] = -2.0; // 调用Template()函数 if (!Template(lpNewDIBBits1, lWidth, lHeight, iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC, nBitCount)) { return FALSE; } // 复制经过模板运算后的图像到源图像 memcpy(lpDIBBits, lpNewDIBBits1, lWidth * lHeight * (nBitCount / 8)); // 释放内存 LocalUnlock(hNewDIBBits1); LocalFree(hNewDIBBits1); LocalUnlock(hNewDIBBits2); LocalFree(hNewDIBBits2); // 返回 return TRUE; } /************************************************************************* * * 函数名称: * KirschDIB() * * 参数: * LPSTR lpDIBBits - 指向源DIB图像指针 * LONG lWidth - 源图像宽度(象素数,必须是4的倍数) * LONG lHeight - 源图像高度(象素数) * 返回值: * BOOL - 边缘检测成功返回TRUE,否则返回FALSE。 * * 说明: * 该函数用kirsch边缘检测算子对图像进行边缘检测运算。 * * 要求目标图像为灰度图像。 ************************************************************************/ BOOL WINAPI KirschDIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight, int nBitCount) { // 指向缓存图像的指针 LPSTR lpDst1; LPSTR lpDst2; // 指向缓存DIB图像的指针 LPSTR lpNewDIBBits1; HLOCAL hNewDIBBits1; LPSTR lpNewDIBBits2; HLOCAL hNewDIBBits2; //循环变量 long i; long j; int k; // 模板高度 int iTempH; // 模板宽度 int iTempW; // 模板系数 FLOAT fTempC; // 模板中心元素X坐标 int iTempMX; // 模板中心元素Y坐标 int iTempMY; //模板数组 FLOAT aTemplate[9]; // 暂时分配内存,以保存新图像 hNewDIBBits1 = LocalAlloc(LHND, lWidth * lHeight * (nBitCount / 8)); if (hNewDIBBits1 == NULL) { // 分配内存失败 return FALSE; } // 锁定内存 lpNewDIBBits1 = (char * )LocalLock(hNewDIBBits1); // 暂时分配内存,以保存新图像 hNewDIBBits2 = LocalAlloc(LHND, lWidth * lHeight * (nBitCount / 8)); if (hNewDIBBits2 == NULL) { // 分配内存失败 return FALSE; } // 锁定内存 lpNewDIBBits2 = (char * )LocalLock(hNewDIBBits2); // 拷贝源图像到缓存图像中 lpDst1 = (char *)lpNewDIBBits1; memcpy(lpNewDIBBits1, lpDIBBits, lWidth * lHeight * (nBitCount / 8)); lpDst2 = (char *)lpNewDIBBits2; memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight * (nBitCount / 8)); // 设置Kirsch模板1参数 iTempW = 3; iTempH = 3; fTempC = 1.0; iTempMX = 1; iTempMY = 1; aTemplate[0] = 5.0; aTemplate[1] = 5.0; aTemplate[2] = 5.0; aTemplate[3] = -3.0; aTemplate[4] = 0.0; aTemplate[5] = -3.0; aTemplate[6] = -3.0; aTemplate[7] = -3.0; aTemplate[8] = -3.0; // 调用Template()函数 if (!Template(lpNewDIBBits1, lWidth, lHeight, iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC, nBitCount)) { return FALSE; } // 设置Kirsch模板2参数 aTemplate[0] = -3.0; aTemplate[1] = 5.0; aTemplate[2] = 5.0; aTemplate[3] = -3.0; aTemplate[4] = 0.0; aTemplate[5] = 5.0; aTemplate[6] = -3.0; aTemplate[7] = -3.0; aTemplate[8] = -3.0; // 调用Template()函数 if (!Template(lpNewDIBBits2, lWidth, lHeight, iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC, nBitCount)) { return FALSE; } //求两幅缓存图像的最大值 for(j = 0; j *lpDst1) *lpDst1 = *lpDst2; } } } // 拷贝源图像到缓存图像中 memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight * (nBitCount / 8)); // 设置Kirsch模板3参数 aTemplate[0] = -3.0; aTemplate[1] = -3.0; aTemplate[2] = 5.0; aTemplate[3] = -3.0; aTemplate[4] = 0.0; aTemplate[5] = 5.0; aTemplate[6] = -3.0; aTemplate[7] = -3.0; aTemplate[8] = 5.0; // 调用Template()函数 if (!Template(lpNewDIBBits2, lWidth, lHeight, iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC, nBitCount)) { return FALSE; } //求两幅缓存图像的最大值 for(j = 0; j *lpDst1) *lpDst1 = *lpDst2; } } } // 拷贝源图像到缓存图像中 memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight * (nBitCount / 8)); // 设置Kirsch模板4参数 aTemplate[0] = -3.0; aTemplate[1] = -3.0; aTemplate[2] = -3.0; aTemplate[3] = -3.0; aTemplate[4] = 0.0; aTemplate[5] = 5.0; aTemplate[6] = -3.0; aTemplate[7] = 5.0; aTemplate[8] = 5.0; // 调用Template()函数 if (!Template(lpNewDIBBits2, lWidth, lHeight, iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC, nBitCount)) { return FALSE; } //求两幅缓存图像的最大值 for(j = 0; j *lpDst1) *lpDst1 = *lpDst2; } } } // 拷贝源图像到缓存图像中 memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight * (nBitCount / 8)); // 设置Kirsch模板5参数 aTemplate[0] = -3.0; aTemplate[1] = -3.0; aTemplate[2] = -3.0; aTemplate[3] = -3.0; aTemplate[4] = 0.0; aTemplate[5] = -3.0; aTemplate[6] = 5.0; aTemplate[7] = 5.0; aTemplate[8] = 5.0; // 调用Template()函数 if (!Template(lpNewDIBBits2, lWidth, lHeight, iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC, nBitCount)) { return FALSE; } // 拷贝源图像到缓存图像中 memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight * (nBitCount / 8)); //求两幅缓存图像的最大值 for(j = 0; j *lpDst1) *lpDst1 = *lpDst2; } } } // 拷贝源图像到缓存图像中 memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight * (nBitCount / 8)); // 设置Kirsch模板6参数 aTemplate[0] = -3.0; aTemplate[1] = -3.0; aTemplate[2] = -3.0; aTemplate[3] = 5.0; aTemplate[4] = 0.0; aTemplate[5] = -3.0; aTemplate[6] = 5.0; aTemplate[7] = 5.0; aTemplate[8] = -3.0; // 调用Template()函数 if (!Template(lpNewDIBBits2, lWidth, lHeight, iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC, nBitCount)) { return FALSE; } //求两幅缓存图像的最大值 for(j = 0; j *lpDst1) *lpDst1 = *lpDst2; } } } // 拷贝源图像到缓存图像中 memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight * (nBitCount / 8)); // 设置Kirsch模板7参数 aTemplate[0] = 5.0; aTemplate[1] = -3.0; aTemplate[2] = -3.0; aTemplate[3] = 5.0; aTemplate[4] = 0.0; aTemplate[5] = -3.0; aTemplate[6] = 5.0; aTemplate[7] = -3.0; aTemplate[8] = -3.0; // 调用Template()函数 if (!Template(lpNewDIBBits2, lWidth, lHeight, iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC, nBitCount)) { return FALSE; } //求两幅缓存图像的最大值 for(j = 0; j *lpDst1) *lpDst1 = *lpDst2; } } } // 拷贝源图像到缓存图像中 memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight * (nBitCount / 8)); // 设置Kirsch模板8参数 aTemplate[0] = 5.0; aTemplate[1] = 5.0; aTemplate[2] = -3.0; aTemplate[3] = 5.0; aTemplate[4] = 0.0; aTemplate[5] = -3.0; aTemplate[6] = -3.0; aTemplate[7] = -3.0; aTemplate[8] = -3.0; // 调用Template()函数 if (!Template(lpNewDIBBits2, lWidth, lHeight, iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC, nBitCount)) { return FALSE; } //求两幅缓存图像的最大值 for(j = 0; j *lpDst1) *lpDst1 = *lpDst2; } } } // 复制经过模板运算后的图像到源图像 memcpy(lpDIBBits, lpNewDIBBits1, lWidth * lHeight * (nBitCount / 8)); // 释放内存 LocalUnlock(hNewDIBBits1); LocalFree(hNewDIBBits1); LocalUnlock(hNewDIBBits2); LocalFree(hNewDIBBits2); // 返回 return TRUE; } /************************************************************************* * * 函数名称: * PrewittDIB() * * 参数: * LPSTR lpDIBBits - 指向源DIB图像指针 * LONG lWidth - 源图像宽度(象素数,必须是4的倍数) * LONG lHeight - 源图像高度(象素数) * 返回值: * BOOL - 边缘检测成功返回TRUE,否则返回FALSE。 * * 说明: * 该函数用Prewitt边缘检测算子对图像进行边缘检测运算。 * * 要求目标图像为灰度图像。 ************************************************************************/ BOOL WINAPI PrewittDIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight, int nBitCount) { // 指向缓存图像的指针 LPSTR lpDst1; LPSTR lpDst2; // 指向缓存DIB图像的指针 LPSTR lpNewDIBBits1; HLOCAL hNewDIBBits1; LPSTR lpNewDIBBits2; HLOCAL hNewDIBBits2; //循环变量 long i; long j; int k; // 模板高度 int iTempH; // 模板宽度 int iTempW; // 模板系数 FLOAT fTempC; // 模板中心元素X坐标 int iTempMX; // 模板中心元素Y坐标 int iTempMY; //模板数组 FLOAT aTemplate[9]; // 暂时分配内存,以保存新图像 hNewDIBBits1 = LocalAlloc(LHND, lWidth * lHeight * (nBitCount / 8)); if (hNewDIBBits1 == NULL) { // 分配内存失败 return FALSE; } // 锁定内存 lpNewDIBBits1 = (char * )LocalLock(hNewDIBBits1); // 暂时分配内存,以保存新图像 hNewDIBBits2 = LocalAlloc(LHND, lWidth * lHeight * (nBitCount / 8)); if (hNewDIBBits2 == NULL) { // 分配内存失败 return FALSE; } // 锁定内存 lpNewDIBBits2 = (char * )LocalLock(hNewDIBBits2); // 拷贝源图像到缓存图像中 lpDst1 = (char *)lpNewDIBBits1; memcpy(lpNewDIBBits1, lpDIBBits, lWidth * lHeight * (nBitCount / 8)); lpDst2 = (char *)lpNewDIBBits2; memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight * (nBitCount / 8)); // 设置Prewitt模板参数 iTempW = 3; iTempH = 3; fTempC = 1.0; iTempMX = 1; iTempMY = 1; aTemplate[0] = -1.0; aTemplate[1] = -1.0; aTemplate[2] = -1.0; aTemplate[3] = 0.0; aTemplate[4] = 0.0; aTemplate[5] = 0.0; aTemplate[6] = 1.0; aTemplate[7] = 1.0; aTemplate[8] = 1.0; // 调用Template()函数 if (!Template(lpNewDIBBits1, lWidth, lHeight, iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC, nBitCount)) { return FALSE; } // 设置Prewitt模板参数 aTemplate[0] = 1.0; aTemplate[1] = 0.0; aTemplate[2] = -1.0; aTemplate[3] = 1.0; aTemplate[4] = 0.0; aTemplate[5] = -1.0; aTemplate[6] = 1.0; aTemplate[7] = 0.0; aTemplate[8] = -1.0; // 调用Template()函数 if (!Template(lpNewDIBBits2, lWidth, lHeight, iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC, nBitCount)) { return FALSE; } //求两幅缓存图像的最大值 for(j = 0; j *lpDst1) *lpDst1 = *lpDst2; } } } // 复制经过模板运算后的图像到源图像 memcpy(lpDIBBits, lpNewDIBBits1, lWidth * lHeight * (nBitCount / 8)); // 释放内存 LocalUnlock(hNewDIBBits1); LocalFree(hNewDIBBits1); LocalUnlock(hNewDIBBits2); LocalFree(hNewDIBBits2); // 返回 return TRUE; } /************************************************************************* * * 函数名称: * RobertDIB() * * 参数: * LPSTR lpDIBBits - 指向源DIB图像指针 * LONG lWidth - 源图像宽度(象素数,必须是4的倍数) * LONG lHeight - 源图像高度(象素数) * 返回值: * BOOL - 边缘检测成功返回TRUE,否则返回FALSE。 * * 说明: * 该函数用Robert边缘检测算子对图像进行边缘检测运算。 * * 要求目标图像为灰度图像。 ************************************************************************/ BOOL WINAPI RobertDIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight, int nBitCount) { // 指向源图像的指针 LPSTR lpSrc; // 指向缓存图像的指针 LPSTR lpDst; // 指向缓存DIB图像的指针 LPSTR lpNewDIBBits; HLOCAL hNewDIBBits; //循环变量 long i; long j; int k; //像素值 double result; unsigned char pixel[4]; // 暂时分配内存,以保存新图像 hNewDIBBits = LocalAlloc(LHND, lWidth * lHeight * (nBitCount / 8)); if (hNewDIBBits == NULL) { // 分配内存失败 return FALSE; } // 锁定内存 lpNewDIBBits = (char * )LocalLock(hNewDIBBits); // 初始化新分配的内存,设定初始值为255 lpDst = (char *)lpNewDIBBits; memset(lpDst, (BYTE)255, lWidth * lHeight * (nBitCount / 8)); switch(nBitCount) { case 8: //使用水平方向的结构元素进行腐蚀 for(j = lHeight-1; j > 0; j--) { for(i = 0;i 0; j--) { for(i = 0; i < lWidth-1; i++) { //由于使用2×2的模板,为防止越界,所以不处理最下边和最右边的两列像素 for(k = 0; k < 3; k++) { // 指向源图像第j行,第i个象素的指针 lpSrc = (char *)lpDIBBits + lWidth * j * 3 + i * 3 + k; // 指向目标图像第j行,第i个象素的指针 lpDst = (char *)lpNewDIBBits + lWidth * j * 3 + i * 3 + k; //取得当前指针处2*2区域的像素值,注意要转换为unsigned char型 pixel[0] = (unsigned char)*lpSrc; pixel[1] = (unsigned char)*(lpSrc + 3); pixel[2] = (unsigned char)*(lpSrc - lWidth * 3); pixel[3] = (unsigned char)*(lpSrc - lWidth * 3 + 3); //计算目标图像中的当前点 result = sqrt(( pixel[0] - pixel[3] )*( pixel[0] - pixel[3] ) + \ ( pixel[1] - pixel[2] )*( pixel[1] - pixel[2] )); *lpDst = (unsigned char)result; } } } break; } // 复制腐蚀后的图像 memcpy(lpDIBBits, lpNewDIBBits, lWidth * lHeight * (nBitCount / 8)); // 释放内存 LocalUnlock(hNewDIBBits); LocalFree(hNewDIBBits); // 返回 return TRUE; } /************************************************************************* * * 函数名称: * SobelDIB() * * 参数: * LPSTR lpDIBBits - 指向源DIB图像指针 * LONG lWidth - 源图像宽度(象素数,必须是4的倍数) * LONG lHeight - 源图像高度(象素数) * 返回值: * BOOL - 边缘检测成功返回TRUE,否则返回FALSE。 * * 说明: * 该函数用Sobel边缘检测算子对图像进行边缘检测运算。 * * 要求目标图像为灰度图像。 ************************************************************************/ BOOL WINAPI SobelDIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight, int nBitCount) { // 指向缓存图像的指针 LPSTR lpDst1; LPSTR lpDst2; // 指向缓存DIB图像的指针 LPSTR lpNewDIBBits1; HLOCAL hNewDIBBits1; LPSTR lpNewDIBBits2; HLOCAL hNewDIBBits2; //循环变量 long i; long j; int k; // 模板高度 int iTempH; // 模板宽度 int iTempW; // 模板系数 FLOAT fTempC; // 模板中心元素X坐标 int iTempMX; // 模板中心元素Y坐标 int iTempMY; //模板数组 FLOAT aTemplate[9]; // 暂时分配内存,以保存新图像 hNewDIBBits1 = LocalAlloc(LHND, lWidth * lHeight * (nBitCount / 8)); if (hNewDIBBits1 == NULL) { // 分配内存失败 return FALSE; } // 锁定内存 lpNewDIBBits1 = (char * )LocalLock(hNewDIBBits1); // 暂时分配内存,以保存新图像 hNewDIBBits2 = LocalAlloc(LHND, lWidth * lHeight * (nBitCount / 8)); if (hNewDIBBits2 == NULL) { // 分配内存失败 return FALSE; } // 锁定内存 lpNewDIBBits2 = (char * )LocalLock(hNewDIBBits2); // 拷贝源图像到缓存图像中 lpDst1 = (char *)lpNewDIBBits1; memcpy(lpNewDIBBits1, lpDIBBits, lWidth * lHeight * (nBitCount / 8)); lpDst2 = (char *)lpNewDIBBits2; memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight * (nBitCount / 8)); // 设置Sobel模板参数 iTempW = 3; iTempH = 3; fTempC = 1.0; iTempMX = 1; iTempMY = 1; aTemplate[0] = -1.0; aTemplate[1] = -2.0; aTemplate[2] = -1.0; aTemplate[3] = 0.0; aTemplate[4] = 0.0; aTemplate[5] = 0.0; aTemplate[6] = 1.0; aTemplate[7] = 2.0; aTemplate[8] = 1.0; // 调用Template()函数 if (!Template(lpNewDIBBits1, lWidth, lHeight, iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC, nBitCount)) { return FALSE; } // 设置Sobel模板参数 aTemplate[0] = -1.0; aTemplate[1] = 0.0; aTemplate[2] = 1.0; aTemplate[3] = -2.0; aTemplate[4] = 0.0; aTemplate[5] = 2.0; aTemplate[6] = -1.0; aTemplate[7] = 0.0; aTemplate[8] = 1.0; // 调用Template()函数 if (!Template(lpNewDIBBits2, lWidth, lHeight, iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC, nBitCount)) { return FALSE; } //求两幅缓存图像的最大值 for(j = 0; j *lpDst1) *lpDst1 = *lpDst2; } } } // 复制经过模板运算后的图像到源图像 memcpy(lpDIBBits, lpNewDIBBits1, lWidth * lHeight * (nBitCount / 8)); // 释放内存 LocalUnlock(hNewDIBBits1); LocalFree(hNewDIBBits1); LocalUnlock(hNewDIBBits2); LocalFree(hNewDIBBits2); // 返回 return TRUE; } /************************************************************************* * * 函数名称: * To256DIB() * * 参数: * LPSTR lpDIBBits - 指向源DIB图像指针 * LONG lWidth - 源图像宽度(象素数,必须是4的倍数) * LONG lHeight - 源图像高度(象素数) * 返回值: * BOOL - 操作成功返回TRUE,否则返回FALSE。 * * 说明: * 该函数将真彩色转换为256等级灰度黑白图像。 * * 要求目标图像为24位位图图像。 ************************************************************************/ BOOL WINAPI To256DIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight) { // 指向复制图像的指针 LPSTR lpNewDIBBits; HLOCAL hNewDIBBits; // 指向源图像的指针 unsigned char* lpSrcR; unsigned char* lpSrcG; unsigned char* lpSrcB; // 指向要复制区域的指针 unsigned char* lpDstR; unsigned char* lpDstG; unsigned char* lpDstB; // 循环变量 LONG i; LONG j; // 中间变量 int bTemp; // 图像每行的字节数 LONG lLineBytes; lLineBytes = WIDTHBYTES(lWidth * 24); // 暂时分配内存,以保存新图像 hNewDIBBits = LocalAlloc(LHND, lLineBytes * lHeight); // 判断是否内存分配失败 if (hNewDIBBits == NULL) { // 分配内存失败 return FALSE; } // 锁定内存 lpNewDIBBits = (char * )LocalLock(hNewDIBBits); // 初始化图像为原始图像 memcpy(lpNewDIBBits, lpDIBBits, lLineBytes * lHeight); // 行(除去边缘几行) for(i = 0; i < lHeight; i++) { // 列(除去边缘几列) for(j = 0; j < lWidth; j++) { // 指向新DIB第i行,第j个象素的指针 lpDstR = (unsigned char*)lpNewDIBBits + lLineBytes * (lHeight - 1 - i) + j * 3; lpDstG = (unsigned char*)lpNewDIBBits + lLineBytes * (lHeight - 1 - i) + j * 3 + 1; lpDstB = (unsigned char*)lpNewDIBBits + lLineBytes * (lHeight - 1 - i) + j * 3 + 2; lpSrcR = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j * 3; lpSrcG = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j * 3 + 1; lpSrcB = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j * 3 + 2; bTemp = (int)(0.299 * (float)(* lpSrcR) + 0.587 * (float)(* lpSrcG) + 0.114 * (float)(* lpSrcB)); if(bTemp > 255) bTemp = 255; else { * lpDstR = bTemp; * lpDstG = bTemp; * lpDstB = bTemp; } } } // 复制变换后的图像 memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight); // 释放内存 LocalUnlock(hNewDIBBits); LocalFree(hNewDIBBits); // 返回 return TRUE; }