📄 subject_43785.htm
字号:
<blockquote><p>
<font color=red>答案被接受</font><br>回复者:刘畅 回复日期:2003-06-14 10:08:19
<br>内容:// ************************************************************************<BR>// 文件名:edgecontour.cpp<BR>//<BR>// 图像边缘与轮廓运算API函数库:<BR>//<BR>// RobertDIB() - robert边缘检测运算<BR>// SobelDIB() - sobel边缘检测运算<BR>// PrewittDIB() - prewitt边缘检测运算<BR>// KirschDIB() - kirsch边缘检测运算<BR>// GaussDIB() - gauss边缘检测运算<BR>// HoughDIB() - 利用Hough变换检测平行直线<BR>// ContourDIB() - 轮廓提取<BR>// TraceDIB() - 轮廓跟踪<BR>// FillDIB() - 种子填充算法1<BR>// Fill2DIB() - 种子填充算法2<BR><BR>//<BR>// ************************************************************************<BR><BR>#include "stdafx.h"<BR>#include "edgecontour.h"<BR>#include "TemplateTrans.h"<BR>#include "DIBAPI.h"<BR><BR>#include <math.h><BR>#include <direct.h><BR><BR>/*************************************************************************<BR> *<BR> * 函数名称:<BR> * RobertDIB()<BR> *<BR> * 参数:<BR> * LPSTR lpDIBBits - 指向源DIB图像指针<BR> * LONG lWidth - 源图像宽度(象素数,必须是4的倍数)<BR> * LONG lHeight - 源图像高度(象素数)<BR> * 返回值:<BR> * BOOL - 边缘检测成功返回TRUE,否则返回FALSE。<BR> *<BR> * 说明:<BR> * 该函数用Robert边缘检测算子对图像进行边缘检测运算。<BR> * <BR> * 要求目标图像为灰度图像。<BR> ************************************************************************/<BR><BR>BOOL WINAPI RobertDIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight)<BR>{<BR> <BR> // 指向源图像的指针<BR> LPSTR lpSrc;<BR> <BR> // 指向缓存图像的指针<BR> LPSTR lpDst;<BR> <BR> // 指向缓存DIB图像的指针<BR> LPSTR lpNewDIBBits;<BR> HLOCAL hNewDIBBits;<BR><BR> //循环变量<BR> long i;<BR> long j;<BR><BR> //像素值<BR> double result;<BR> unsigned char pixel[4];<BR><BR> // 暂时分配内存,以保存新图像<BR> hNewDIBBits = LocalAlloc(LHND, lWidth * lHeight);<BR><BR> if (hNewDIBBits == NULL)<BR> {<BR> // 分配内存失败<BR> return FALSE;<BR> }<BR> <BR> // 锁定内存<BR> lpNewDIBBits = (char * )LocalLock(hNewDIBBits);<BR><BR> // 初始化新分配的内存,设定初始值为255<BR> lpDst = (char *)lpNewDIBBits;<BR> memset(lpDst, (BYTE)255, lWidth * lHeight);<BR><BR><BR> //使用水平方向的结构元素进行腐蚀<BR> for(j = lHeight-1; j > 0; j--)<BR> {<BR> for(i = 0;i <lWidth-1; i++)<BR> {<BR> //由于使用2×2的模板,为防止越界,所以不处理最下边和最右边的两列像素<BR><BR> // 指向源图像第j行,第i个象素的指针 <BR> lpSrc = (char *)lpDIBBits + lWidth * j + i;<BR><BR> // 指向目标图像第j行,第i个象素的指针 <BR> lpDst = (char *)lpNewDIBBits + lWidth * j + i;<BR><BR> //取得当前指针处2*2区域的像素值,注意要转换为unsigned char型<BR> pixel[0] = (unsigned char)*lpSrc;<BR> pixel[1] = (unsigned char)*(lpSrc + 1);<BR> pixel[2] = (unsigned char)*(lpSrc - lWidth);<BR> pixel[3] = (unsigned char)*(lpSrc - lWidth + 1);<BR><BR> //计算目标图像中的当前点<BR> result = sqrt(( pixel[0] - pixel[3] )*( pixel[0] - pixel[3] ) + \<BR> ( pixel[1] - pixel[2] )*( pixel[1] - pixel[2] ));<BR> *lpDst = (unsigned char)result;<BR> <BR> }<BR> }<BR><BR> // 复制腐蚀后的图像<BR> memcpy(lpDIBBits, lpNewDIBBits, lWidth * lHeight);<BR><BR> // 释放内存<BR> LocalUnlock(hNewDIBBits);<BR> LocalFree(hNewDIBBits);<BR><BR> // 返回<BR> return TRUE;<BR>}<BR><BR>/*************************************************************************<BR> *<BR> * 函数名称:<BR> * SobelDIB()<BR> *<BR> * 参数:<BR> * LPSTR lpDIBBits - 指向源DIB图像指针<BR> * LONG lWidth - 源图像宽度(象素数,必须是4的倍数)<BR> * LONG lHeight - 源图像高度(象素数)<BR> * 返回值:<BR> * BOOL - 边缘检测成功返回TRUE,否则返回FALSE。<BR> *<BR> * 说明:<BR> * 该函数用Sobel边缘检测算子对图像进行边缘检测运算。<BR> * <BR> * 要求目标图像为灰度图像。<BR> ************************************************************************/<BR><BR>BOOL WINAPI SobelDIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight)<BR>{<BR> <BR> // 指向缓存图像的指针<BR> LPSTR lpDst1;<BR> LPSTR lpDst2;<BR> <BR> // 指向缓存DIB图像的指针<BR> LPSTR lpNewDIBBits1;<BR> HLOCAL hNewDIBBits1;<BR> LPSTR lpNewDIBBits2;<BR> HLOCAL hNewDIBBits2;<BR><BR> //循环变量<BR> long i;<BR> long j;<BR><BR> // 模板高度<BR> int iTempH;<BR> <BR> // 模板宽度<BR> int iTempW;<BR> <BR> // 模板系数<BR> FLOAT fTempC;<BR> <BR> // 模板中心元素X坐标<BR> int iTempMX;<BR> <BR> // 模板中心元素Y坐标<BR> int iTempMY;<BR> <BR> //模板数组<BR> FLOAT aTemplate[9];<BR><BR> // 暂时分配内存,以保存新图像<BR> hNewDIBBits1 = LocalAlloc(LHND, lWidth * lHeight);<BR><BR> if (hNewDIBBits1 == NULL)<BR> {<BR> // 分配内存失败<BR> return FALSE;<BR> }<BR> <BR> // 锁定内存<BR> lpNewDIBBits1 = (char * )LocalLock(hNewDIBBits1);<BR><BR> // 暂时分配内存,以保存新图像<BR> hNewDIBBits2 = LocalAlloc(LHND, lWidth * lHeight);<BR><BR> if (hNewDIBBits2 == NULL)<BR> {<BR> // 分配内存失败<BR> return FALSE;<BR> }<BR> <BR> // 锁定内存<BR> lpNewDIBBits2 = (char * )LocalLock(hNewDIBBits2);<BR><BR> // 拷贝源图像到缓存图像中<BR> lpDst1 = (char *)lpNewDIBBits1;<BR> memcpy(lpNewDIBBits1, lpDIBBits, lWidth * lHeight);<BR> lpDst2 = (char *)lpNewDIBBits2;<BR> memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight);<BR><BR> // 设置Sobel模板参数<BR> iTempW = 3;<BR> iTempH = 3;<BR> fTempC = 1.0;<BR> iTempMX = 1;<BR> iTempMY = 1;<BR> aTemplate[0] = -1.0;<BR> aTemplate[1] = -2.0;<BR> aTemplate[2] = -1.0;<BR> aTemplate[3] = 0.0;<BR> aTemplate[4] = 0.0;<BR> aTemplate[5] = 0.0;<BR> aTemplate[6] = 1.0;<BR> aTemplate[7] = 2.0;<BR> aTemplate[8] = 1.0;<BR><BR> // 调用Template()函数<BR> if (!Template(lpNewDIBBits1, lWidth, lHeight, <BR> iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC))<BR> {<BR> return FALSE;<BR> }<BR><BR> // 设置Sobel模板参数<BR> aTemplate[0] = -1.0;<BR> aTemplate[1] = 0.0;<BR> aTemplate[2] = 1.0;<BR> aTemplate[3] = -2.0;<BR> aTemplate[4] = 0.0;<BR> aTemplate[5] = 2.0;<BR> aTemplate[6] = -1.0;<BR> aTemplate[7] = 0.0;<BR> aTemplate[8] = 1.0;<BR><BR> // 调用Template()函数<BR> if (!Template(lpNewDIBBits2, lWidth, lHeight, <BR> iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC))<BR> {<BR> return FALSE;<BR> }<BR><BR> //求两幅缓存图像的最大值<BR> for(j = 0; j <lHeight; j++)<BR> {<BR> for(i = 0;i <lWidth-1; i++)<BR> {<BR><BR> // 指向缓存图像1倒数第j行,第i个象素的指针 <BR> lpDst1 = (char *)lpNewDIBBits1 + lWidth * j + i;<BR><BR> // 指向缓存图像2倒数第j行,第i个象素的指针 <BR> lpDst2 = (char *)lpNewDIBBits2 + lWidth * j + i;<BR> <BR> if(*lpDst2 > *lpDst1)<BR> *lpDst1 = *lpDst2;<BR> <BR> }<BR> }<BR><BR> // 复制经过模板运算后的图像到源图像<BR> memcpy(lpDIBBits, lpNewDIBBits1, lWidth * lHeight);<BR><BR> // 释放内存<BR> LocalUnlock(hNewDIBBits1);<BR> LocalFree(hNewDIBBits1);<BR><BR> LocalUnlock(hNewDIBBits2);<BR> LocalFree(hNewDIBBits2);<BR> // 返回<BR> return TRUE;<BR>}<BR><BR>/*************************************************************************<BR> *<BR> * 函数名称:<BR> * PrewittDIB()<BR> *<BR> * 参数:<BR> * LPSTR lpDIBBits - 指向源DIB图像指针<BR> * LONG lWidth - 源图像宽度(象素数,必须是4的倍数)<BR> * LONG lHeight - 源图像高度(象素数)<BR> * 返回值:<BR> * BOOL - 边缘检测成功返回TRUE,否则返回FALSE。<BR> *<BR> * 说明:<BR> * 该函数用Prewitt边缘检测算子对图像进行边缘检测运算。<BR> * <BR> * 要求目标图像为灰度图像。<BR> ************************************************************************/<BR><BR>BOOL WINAPI PrewittDIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight)<BR>{<BR> <BR> // 指向缓存图像的指针<BR> LPSTR lpDst1;<BR> LPSTR lpDst2;<BR> <BR> // 指向缓存DIB图像的指针<BR> LPSTR lpNewDIBBits1;<BR> HLOCAL hNewDIBBits1;<BR> LPSTR lpNewDIBBits2;<BR> HLOCAL hNewDIBBits2;<BR><BR> //循环变量<BR> long i;<BR> long j;<BR><BR> // 模板高度<BR> int iTempH;<BR> <BR> // 模板宽度<BR> int iTempW;<BR> <BR> // 模板系数<BR> FLOAT fTempC;<BR> <BR> // 模板中心元素X坐标<BR> int iTempMX;<BR> <BR> // 模板中心元素Y坐标<BR> int iTempMY;<BR> <BR> //模板数组<BR> FLOAT aTemplate[9];<BR><BR> // 暂时分配内存,以保存新图像<BR> hNewDIBBits1 = LocalAlloc(LHND, lWidth * lHeight);<BR><BR> if (hNewDIBBits1 == NULL)<BR> {<BR> // 分配内存失败<BR> return FALSE;<BR> }<BR> <BR> // 锁定内存<BR> lpNewDIBBits1 = (char * )LocalLock(hNewDIBBits1);<BR><BR> // 暂时分配内存,以保存新图像<BR> hNewDIBBits2 = LocalAlloc(LHND, lWidth * lHeight);<BR><BR> if (hNewDIBBits2 == NULL)<BR> {<BR> // 分配内存失败<BR> return FALSE;<BR> }<BR> <BR> // 锁定内存<BR> lpNewDIBBits2 = (char * )LocalLock(hNewDIBBits2);<BR><BR> // 拷贝源图像到缓存图像中<BR> lpDst1 = (char *)lpNewDIBBits1;<BR> memcpy(lpNewDIBBits1, lpDIBBits, lWidth * lHeight);<BR> lpDst2 = (char *)lpNewDIBBits2;<BR> memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight);<BR><BR><BR> // 设置Prewitt模板参数<BR> iTempW = 3;<BR> iTempH = 3;<BR> fTempC = 1.0;<BR> iTempMX = 1;<BR> iTempMY = 1;<BR> aTemplate[0] = -1.0;<BR> aTemplate[1] = -1.0;<BR> aTemplate[2] = -1.0;<BR> aTemplate[3] = 0.0;<BR> aTemplate[4] = 0.0;<BR> aTemplate[5] = 0.0;<BR> aTemplate[6] = 1.0;<BR> aTemplate[7] = 1.0;<BR> aTemplate[8] = 1.0;<BR><BR> // 调用Template()函数<BR> if (!Template(lpNewDIBBits1, lWidth, lHeight, <BR> iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC))<BR> {<BR> return FALSE;<BR> }<BR><BR> // 设置Prewitt模板参数<BR> aTemplate[0] = 1.0;<BR> aTemplate[1] = 0.0;<BR> aTemplate[2] = -1.0;<BR> aTemplate[3] = 1.0;<BR> aTemplate[4] = 0.0;<BR> aTemplate[5] = -1.0;<BR> aTemplate[6] = 1.0;<BR> aTemplate[7] = 0.0;<BR> aTemplate[8] = -1.0;<BR><BR> // 调用Template()函数<BR> if (!Template(lpNewDIBBits2, lWidth, lHeight, <BR> iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC))<BR> {<BR> return FALSE;<BR> }<BR><BR> //求两幅缓存图像的最大值<BR> for(j = 0; j <lHeight; j++)<BR> {<BR> for(i = 0;i <lWidth-1; i++)<BR> {<BR><BR> // 指向缓存图像1倒数第j行,第i个象素的指针 <BR> lpDst1 = (char *)lpNewDIBBits1 + lWidth * j + i;<BR><BR> // 指向缓存图像2倒数第j行,第i个象素的指针 <BR> lpDst2 = (char *)lpNewDIBBits2 + lWidth * j + i;<BR> <BR> if(*lpDst2 > *lpDst1)<BR> *lpDst1 = *lpDst2;<BR> <BR> }<BR> }<BR><BR> // 复制经过模板运算后的图像到源图像<BR> memcpy(lpDIBBits, lpNewDIBBits1, lWidth * lHeight);<BR><BR> // 释放内存<BR> LocalUnlock(hNewDIBBits1);<BR> LocalFree(hNewDIBBits1);<BR><BR> LocalUnlock(hNewDIBBits2);<BR> LocalFree(hNewDIBBits2);<BR> // 返回<BR> return TRUE;<BR>}<BR><BR>/*************************************************************************<BR> *<BR> * 函数名称:<BR> * KirschDIB()<BR> *<BR> * 参数:<BR> * LPSTR lpDIBBits - 指向源DIB图像指针<BR> * LONG lWidth - 源图像宽度(象素数,必须是4的倍数)<BR> * LONG lHeight - 源图像高度(象素数)<BR> * 返回值:<BR> * BOOL - 边缘检测成功返回TRUE,否则返回FALSE。<BR> *<BR> * 说明:<BR> * 该函数用kirsch边缘检测算子对图像进行边缘检测运算。<BR> * <BR> * 要求目标图像为灰度图像。<BR> ************************************************************************/<BR><BR>BOOL WINAPI KirschDIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight)<BR>{<BR> <BR> // 指向缓存图像的指针<BR> LPSTR lpDst1;<BR> LPSTR lpDst2;<BR> <BR> // 指向缓存DIB图像的指针<BR> LPSTR lpNewDIBBits1;<BR> HLOCAL hNewDIBBits1;<BR> LPSTR lpNewDIBBits2;<BR> HLOCAL hNewDIBBits2;<BR><BR> //循环变量<BR> long i;<BR> long j;<BR><BR> // 模板高度<BR> int iTempH;<BR> <BR> // 模板宽度<BR> int iTempW;<BR> <BR> // 模板系数<BR> FLOAT fTempC;<BR> <BR> // 模板中心元素X坐标<BR> int iTempMX;<BR> <BR> // 模板中心元素Y坐标<BR> int iTempMY;<BR> <BR> //模板数组<BR> FLOAT aTemplate[9];<BR><BR> // 暂时分配内存,以保存新图像<BR> hNewDIBBits1 = LocalAlloc(LHND, lWidth * lHeight);<BR><BR> if (hNewDIBBits1 == NULL)<BR> {<BR> // 分配内存失败<BR> return FALSE;<BR> }<BR> <BR> // 锁定内存<BR> lpNewDIBBits1 = (char * )LocalLock(hNewDIBBits1);<BR><BR> // 暂时分配内存,以保存新图像<BR> hNewDIBBits2 = LocalAlloc(LHND, lWidth * lHeight);<BR><BR> if (hNewDIBBits2 == NULL)<BR> {<BR> // 分配内存失败<BR> return FALSE;<BR> }<BR> <BR> // 锁定内存<BR> lpNewDIBBits2 = (char * )LocalLock(hNewDIBBits2);<BR><BR> // 拷贝源图像到缓存图像中<BR> lpDst1 = (char *)lpNewDIBBits1;<BR> memcpy(lpNewDIBBits1, lpDIBBits, lWidth * lHeight);<BR> lpDst2 = (char *)lpNewDIBBits2;<BR> memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight);<BR><BR><BR> // 设置Kirsch模板1参数<BR> iTempW = 3;<BR> iTempH = 3;<BR> fTempC = 1.0;<BR> iTempMX = 1;<BR> iTempMY = 1;<BR> aTemplate[0] = 5.0;<BR> aTemplate[1] = 5.0;<BR> aTemplate[2] = 5.0;<BR> aTemplate[3] = -3.0;<BR> aTemplate[4] = 0.0;<BR> aTemplate[5] = -3.0;<BR> aTemplate[6] = -3.0;<BR> aTemplate[7] = -3.0;<BR> aTemplate[8] = -3.0;<BR><BR> // 调用Template()函数<BR> if (!Template(lpNewDIBBits1, lWidth, lHeight, <BR> iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC))<BR> {<BR> return FALSE;<BR> }<BR><BR> // 设置Kirsch模板2参数<BR> aTemplate[0] = -3.0;<BR> aTemplate[1] = 5.0;<BR> aTemplate[2] = 5.0;<BR> aTemplate[3] = -3.0;<BR> aTemplate[4] = 0.0;<BR> aTemplate[5] = 5.0;<BR> aTemplate[6] = -3.0;<BR> aTemplate[7] = -3.0;<BR> aTemplate[8] = -3.0;<BR><BR> // 调用Template()函数<BR> if (!Template(lpNewDIBBits2, lWidth, lHeight, <BR> iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC))<BR> {<BR> return FALSE;<BR> }<BR><BR> //求两幅缓存图像的最大值<BR> for(j = 0; j <lHeight; j++)<BR> {<BR> for(i = 0;i <lWidth-1; i++)<BR> {<BR><BR> // 指向缓存图像1倒数第j行,第i个象素的指针 <BR> lpDst1 = (char *)lpNewDIBBits1 + lWidth * j + i;<BR><BR> // 指向缓存图像2倒数第j行,第i个象素的指针 <BR> lpDst2 = (char *)lpNewDIBBits2 + lWidth * j + i;<BR> <BR> if(*lpDst2 > *lpDst1)<BR> *lpDst1 = *lpDst2;<BR> <BR> }<BR> }<BR><BR> // 拷贝源图像到缓存图像中<BR> memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight);<BR><BR> // 设置Kirsch模板3参数<BR> aTemplate[0] = -3.0;<BR> aTemplate[1] = -3.0;<BR> aTemplate[2] = 5.0;<BR> aTemplate[3] = -3.0;<BR> aTemplate[4] = 0.0;<BR> aTemplate[5] = 5.0;<BR> aTemplate[6] = -3.0;<BR> aTemplate[7] = -3.0;<BR> aTemplate[8] = 5.0;<BR><BR> // 调用Template()函数<BR> if (!Template(lpNewDIBBits2, lWidth, lHeight, <BR> iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC))<BR> {<BR> return FALSE;<BR> }<BR><BR> //求两幅缓存图像的最大值<BR> for(j = 0; j <lHeight; j++)<BR> {<BR> for(i = 0;i <lWidth-1; i++)<BR> {<BR><BR> // 指向缓存图像1倒数第j行,第i个象素的指针 <BR> lpDst1 = (char *)lpNewDIBBits1 + lWidth * j + i;<BR><BR> // 指向缓存图像2倒数第j行,第i个象素的指针 <BR> lpDst2 = (char *)lpNewDIBBits2 + lWidth * j + i;<BR> <BR> if(*lpDst2 > *lpDst1)<BR> *lpDst1 = *lpDst2;<BR> <BR> }<BR> }<BR><BR> // 拷贝源图像到缓存图像中<BR> memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight);<BR> <BR> // 设置Kirsch模板4参数<BR> aTemplate[0] = -3.0;<BR> aTemplate[1] = -3.0;<BR> aTemplate[2] = -3.0;<BR> aTemplate[3] = -3.0;<BR> aTemplate[4] = 0.0;<BR> aTemplate[5] = 5.0;<BR> aTemplate[6] = -3.0;<BR> aTemplate[7] = 5.0;<BR> aTemplate[8] = 5.0;<BR><BR> // 调用Template()函数<BR> if (!Template(lpNewDIBBits2, lWidth, lHeight, <BR> iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC))<BR> {<BR> return FALSE;<BR> }<BR><BR> //求两幅缓存图像的最大值<BR> for(j = 0; j <lHeight; j++)<BR> {<BR> for(i = 0;i <lWidth-1; i++)<BR> {<BR><BR> // 指向缓存图像1倒数第j行,第i个象素的指针 <BR> lpDst1 = (char *)lpNewDIBBits1 + lWidth * j + i;<BR><BR> // 指向缓存图像2倒数第j行,第i个象素的指针 <BR> lpDst2 = (char *)lpNewDIBBits2 + lWidth * j + i;<BR> <BR> if(*lpDst2 > *lpDst1)<BR> *lpDst1 = *lpDst2;<BR> <BR> }<BR> }<BR><BR> // 拷贝源图像到缓存图像中<BR> memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight);<BR> <BR> // 设置Kirsch模板5参数<BR> aTemplate[0] = -3.0;<BR> aTemplate[1] = -3.0;<BR> aTemplate[2] = -3.0;<BR> aTemplate[3] = -3.0;<BR> aTemplate[4] = 0.0;<BR> aTemplate[5] = -3.0;<BR> aTemplate[6] = 5.0;<BR> aTemplate[7] = 5.0;<BR> aTemplate[8] = 5.0;<BR><BR> // 调用Template()函数<BR> if (!Template(lpNewDIBBits2, lWidth, lHeight, <BR> iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC))<BR> {<BR> return FALSE;<BR> }<BR><BR> // 拷贝源图像到缓存图像中<BR> memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight);<BR> //求两幅缓存图像的最大值<BR> for(j = 0; j <lHeight; j++)<BR> {<BR> for(i = 0;i <lWidth-1; i++)<BR> {<BR><BR> // 指向缓存图像1倒数第j行,第i个象素的指针 <BR> lpDst1 = (char *)lpNewDIBBits1 + lWidth * j + i;<BR><BR> // 指向缓存图像2倒数第j行,第i个象素的指针 <BR> lpDst2 = (char *)lpNewDIBBits2 + lWidth * j + i;<BR> <BR> if(*lpDst2 > *lpDst1)<BR> *lpDst1 = *lpDst2;<BR> <BR> }<BR> }<BR><BR> // 拷贝源图像到缓存图像中<BR> memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight);<BR> <BR> // 设置Kirsch模板6参数<BR> aTemplate[0] = -3.0;<BR> aTemplate[1] = -3.0;<BR> aTemplate[2] = -3.0;<BR> aTemplate[3] = 5.0;<BR> aTemplate[4] = 0.0;<BR> aTemplate[5] = -3.0;<BR> aTemplate[6] = 5.0;<BR> aTemplate[7] = 5.0;<BR> aTemplate[8] = -3.0;<BR><BR> // 调用Template()函数<BR> if (!Template(lpNewDIBBits2, lWidth, lHeight, <BR> iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC))<BR> {<BR> return FALSE;<BR> }<BR><BR> //求两幅缓存图像的最大值<BR> for(j = 0; j <lHeight; j++)<BR> {<BR> for(i = 0;i <lWidth-1; i++)<BR> {<BR><BR> // 指向缓存图像1倒数第j行,第i个象素的指针 <BR> lpDst1 = (char *)lpNewDIBBits1 + lWidth * j + i;<BR><BR> // 指向缓存图像2倒数第j行,第i个象素的指针 <BR> lpDst2 = (char *)lpNewDIBBits2 + lWidth * j + i;<BR> <BR> if(*lpDst2 > *lpDst1)<BR> *lpDst1 = *lpDst2;<BR> <BR> }<BR> }<BR><BR> // 拷贝源图像到缓存图像中<BR> memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight);<BR> <BR> // 设置Kirsch模板7参数<BR> aTemplate[0] = 5.0;<BR> aTemplate[1] = -3.0;<BR> aTemplate[2] = -3.0;<BR> aTemplate[3] = 5.0;<BR> aTemplate[4] = 0.0;<BR> aTemplate[5] = -3.0;<BR> aTemplate[6] = 5.0;<BR> aTemplate[7] = -3.0;<BR> aTemplate[8] = -3.0;<BR><BR> // 调用Template()函数<BR> if (!Template(lpNewDIBBits2, lWidth, lHeight, <BR> iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC))<BR> {<BR> return FALSE;<BR> }<BR><BR> //求两幅缓存图像的最大值<BR> for(j = 0; j <lHeight; j++)<BR> {<BR> for(i = 0;i <lWidth-1; i++)<BR> {<BR><BR> // 指向缓存图像1倒数第j行,第i个象素的指针 <BR> lpDst1 = (char *)lpNewDIBBits1 + lWidth * j + i;<BR><BR> // 指向缓存图像2倒数第j行,第i个象素的指针 <BR> lpDst2 = (char *)lpNewDIBBits2 + lWidth * j + i;<BR> <BR> if(*lpDst2 > *lpDst1)<BR> *lpDst1 = *lpDst2;<BR> <BR> }<BR> }<BR><BR> // 拷贝源图像到缓存图像中<BR> memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight);<BR> <BR> // 设置Kirsch模板8参数<BR> aTemplate[0] = 5.0;<BR> aTemplate[1] = 5.0;<BR> aTemplate[2] = -3.0;<BR> aTemplate[3] = 5.0;<BR> aTemplate[4] = 0.0;<BR> aTemplate[5] = -3.0;<BR> aTemplate[6] = -3.0;<BR> aTemplate[7] = -3.0;<BR> aTemplate[8] = -3.0;<BR><BR> // 调用Template()函数<BR> if (!Template(lpNewDIBBits2, lWidth, lHeight, <BR> iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC))<BR> {<BR> return FALSE;<BR> }<BR><BR> //求两幅缓存图像的最大值<BR> for(j = 0; j <lHeight; j++)<BR> {<BR> for(i = 0;i <lWidth-1; i++)<BR> {<BR><BR> // 指向缓存图像1倒数第j行,第i个象素的指针 <BR> lpDst1 = (char *)lpNewDIBBits1 + lWidth * j + i;<BR><BR> // 指向缓存图像2倒数第j行,第i个象素的指针 <BR> lpDst2 = (char *)lpNewDIBBits2 + lWidth * j + i;<BR> <BR> if(*lpDst2 > *lpDst1)<BR> *lpDst1 = *lpDst2;<BR> <BR> }<BR> }<BR><BR> // 复制经过模板运算后的图像到源图像<BR> memcpy(lpDIBBits, lpNewDIBBits1, lWidth * lHeight);<BR><BR> // 释放内存<BR> LocalUnlock(hNewDIBBits1);<BR> LocalFree(hNewDIBBits1);<BR><BR> LocalUnlock(hNewDIBBits2);<BR> LocalFree(hNewDIBBits2);<BR> // 返回<BR> return TRUE;<BR>}<BR><BR>/*************************************************************************<BR> *<BR> * 函数名称:<BR> * GaussDIB()<BR> *<BR> * 参数:<BR> * LPSTR lpDIBBits - 指向源DIB图像指针<BR> * LONG lWidth - 源图像宽度(象素数,必须是4的倍数)<BR> * LONG lHeight - 源图像高度(象素数)<BR> * 返回值:<BR> * BOOL - 边缘检测成功返回TRUE,否则返回FALSE。<BR> *<BR> * 说明:<BR> * 该函数用高斯拉普拉斯边缘检测算子对图像进行边缘检测运算。<BR> * <BR> * 要求目标图像为灰度图像。<BR> ************************************************************************/<BR><BR>BOOL WINAPI GaussDIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight)<BR>{<BR> <BR> // 指向缓存图像的指针<BR> LPSTR lpDst1;<BR> LPSTR lpDst2;<BR> <BR> // 指向缓存DIB图像的指针<BR> LPSTR lpNewDIBBits1;<BR> HLOCAL hNewDIBBits1;<BR> LPSTR lpNewDIBBits2;<BR> HLOCAL hNewDIBBits2;<BR><BR> // 模板高度<BR> int iTempH;<BR> <BR> // 模板宽度<BR> int iTempW;<BR> <BR> // 模板系数<BR> FLOAT fTempC;<BR> <BR> // 模板中心元素X坐标<BR> int iTempMX;<BR> <BR> // 模板中心元素Y坐标<BR> int iTempMY;<BR> <BR> //模板数组<BR> FLOAT aTemplate[25];<BR><BR> // 暂时分配内存,以保存新图像<BR> hNewDIBBits1 = LocalAlloc(LHND, lWidth * lHeight);<BR><BR> if (hNewDIBBits1 == NULL)<BR> {<BR> // 分配内存失败<BR> return FALSE;<BR> }<BR> <BR> // 锁定内存<BR> lpNewDIBBits1 = (char * )LocalLock(hNewDIBBits1);<BR><BR> // 暂时分配内存,以保存新图像<BR> hNewDIBBits2 = LocalAlloc(LHND, lWidth * lHeight);<BR><BR> if (hNewDIBBits2 == NULL)<BR> {<BR> // 分配内存失败<BR> return FALSE;<BR> }<BR> <BR> // 锁定内存<BR> lpNewDIBBits2 = (char * )LocalLock(hNewDIBBits2);<BR><BR> // 拷贝源图像到缓存图像中<BR> lpDst1 = (char *)lpNewDIBBits1;<BR> memcpy(lpNewDIBBits1, lpDIBBits, lWidth * lHeight);<BR> lpDst2 = (char *)lpNewDIBBits2;<BR> memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight);<BR><BR><BR> // 设置Gauss模板参数<BR> iTempW = 5;<BR> iTempH = 5;<BR> fTempC = 1.0;<BR> iTempMX = 3;<BR> iTempMY = 3;<BR> aTemplate[0] = -2.0;<BR> aTemplate[1] = -4.0;<BR> aTemplate[2] = -4.0;<BR> aTemplate[3] = -4.0;<BR> aTemplate[4] = -2.0;<BR> aTemplate[5] = -4.0;<BR> aTemplate[6] = 0.0;<BR> aTemplate[7] = 8.0;<BR> aTemplate[8] = 0.0;<BR> aTemplate[9] = -4.0;<BR> aTemplate[10] = -4.0;<BR> aTemplate[11] = 8.0;<BR> aTemplate[12] = 24.0;<BR> aTemplate[13] = 8.0;<BR> aTemplate[14] = -4.0;<BR> aTemplate[15] = -4.0;<BR> aTemplate[16] = 0.0;<BR> aTemplate[17] = 8.0;<BR> aTemplate[18] = 0.0;<BR> aTemplate[19] = -4.0;<BR> aTemplate[20] = -2.0;<BR> aTemplate[21] = -4.0;<BR> aTemplate[22] = -4.0;<BR> aTemplate[23] = -4.0;<BR> aTemplate[24] = -2.0;<BR><BR> // 调用Template()函数<BR> if (!Template(lpNewDIBBits1, lWidth, lHeight, <BR> iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC))<BR> {<BR> return FALSE;<BR> }<BR><BR> // 复制经过模板运算后的图像到源图像<BR> memcpy(lpDIBBits, lpNewDIBBits1, lWidth * lHeight);<BR><BR> // 释放内存<BR> LocalUnlock(hNewDIBBits1);<BR> LocalFree(hNewDIBBits1);<BR><BR> LocalUnlock(hNewDIBBits2);<BR> LocalFree(hNewDIBBits2);<BR> // 返回<BR> return TRUE;<BR>}<BR><BR>/*************************************************************************<BR> *<BR> * 函数名称:<BR> * HoughDIB()<BR> *<BR> * 参数:<BR> * LPSTR lpDIBBits - 指向源DIB图像指针<BR> * LONG lWidth - 源图像宽度(象素数,必须是4的倍数)<BR> * LONG lHeight - 源图像高度(象素数)<BR> * 返回值:<BR> * BOOL - 运算成功返回TRUE,否则返回FALSE。<BR> *<BR> * 说明:<BR> * 该函数用于对检测图像中的平行直线。如果图像中有两条平行的直线,则将这两条平行直线<BR> * 提取出来。<BR> * <BR> * 要求目标图像为只有0和255两个灰度值的灰度图像。<BR> ************************************************************************/<BR><BR>BOOL WINAPI HoughDIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight)<BR>{<BR> <BR> // 指向源图像的指针<BR> LPSTR lpSrc;<BR> <BR> // 指向缓存图像的指针<BR> LPSTR lpDst;<BR> <BR> // 指向变换域的指针<BR> LPSTR lpTrans;<BR><BR> // 图像每行的字节数<BR> LONG lLineBytes;<BR> <BR> // 指向缓存DIB图像的指针<BR> LPSTR lpNewDIBBits;<BR> HLOCAL hNewDIBBits;<BR><BR> //指向变换域的指针<BR> LPSTR lpTransArea;<BR> HLOCAL hTransArea;<BR><BR> //变换域的尺寸<BR> int iMaxDist;<BR> int iMaxAngleNumber;<BR><BR> //变换域的坐标<BR> int iDist;<BR> int iAngleNumber;<BR><BR> //循环变量<BR> long i;<BR> long j;<BR><BR> //像素值<BR> unsigned char pixel;<BR><BR> //存储变换域中的两个最大值<BR> MaxValue MaxValue1;<BR> MaxValue MaxValue2;<BR><BR> // 暂时分配内存,以保存新图像<BR> hNewDIBBits = LocalAlloc(LHND, lWidth * lHeight);<BR><BR> if (hNewDIBBits == NULL)<BR> {<BR> // 分配内存失败<BR> return FALSE;<BR> }<BR> <BR> // 锁定内存<BR> lpNewDIBBits = (char * )LocalLock(hNewDIBBits);<BR><BR> // 初始化新分配的内存,设定初始值为255<BR> lpDst = (char *)lpNewDIBBits;<BR> memset(lpDst, (BYTE)255, lWidth * lHeight);<BR><BR> //计算变换域的尺寸<BR> //最大距离<BR> iMaxDist = (int) sqrt(lWidth*lWidth + lHeight*lHeight);<BR><BR> //角度从0-180,每格2度<BR> iMaxAngleNumber = 90;<BR><BR> //为变换域分配内存<BR> hTransArea = LocalAlloc(LHND, lWidth * lHeight * sizeof(int));<BR><BR> if (hNewDIBBits == NULL)<BR> {<BR> // 分配内存失败<BR> return FALSE;<BR> }<BR> <BR> // 锁定内存<BR> lpTransArea = (char * )LocalLock(hTransArea);<BR> <BR> // 初始化新分配的内存,设定初始值为0<BR> lpTrans = (char *)lpTransArea;<BR> memset(lpTrans, 0, lWidth * lHeight * sizeof(int));<BR><BR> // 计算图像每行的字节数<BR> lLineBytes = WIDTHBYTES(lWidth * 8);<BR><BR> for(j = 0; j <lHeight; j++)<BR> {<BR> for(i = 0;i <lWidth; i++)<BR> {<BR><BR> // 指向源图像倒数第j行,第i个象素的指针 <BR> lpSrc = (char *)lpDIBBits + lLineBytes * j + i;<BR><BR> //取得当前指针处的像素值,注意要转换为unsigned char型<BR> pixel = (unsigned char)*lpSrc;<BR><BR> //目标图像中含有0和255外的其它灰度值<BR> if(pixel != 255 && *lpSrc != 0)<BR> return FALSE;<BR><BR> //如果是黑点,则在变换域的对应各点上加1<BR> if(pixel == 0)<BR> {<BR> //注意步长是2度<BR> for(iAngleNumber=0; iAngleNumber<iMaxAngleNumber; iAngleNumber++)<BR> {<BR> iDist = (int) fabs(i*cos(iAngleNumber*2*pi/180.0) + \<BR> j*sin(iAngleNumber*2*pi/180.0));<BR> <BR> //变换域的对应点上加1<BR> *(lpTransArea+iDist*iMaxAngleNumber+iAngleNumber) = \<BR> *(lpTransArea+iDist*iMaxAngleNumber+iAngleNumber) +1;<BR> }<BR> }<BR> <BR> }<BR> }<BR> <BR> //找到变换域中的两个最大值点<BR> MaxValue1.Value=0;<BR> MaxValue2.Value=0;<BR> <BR> //找到第一个最大值点<BR> for (iDist=0; iDist<iMaxDist;iDist++)<BR> {<BR> for(iAngleNumber=0; iAngleNumber<iMaxAngleNumber; iAngleNumber++)<BR> {<BR> if((int)*(lpTransArea+iDist*iMaxAngleNumber+iAngleNumber)>MaxValue1.Value)<BR> {<BR> MaxValue1.Value = (int)*(lpTransArea+iDist*iMaxAngleNumber+iAngleNumber);<BR> MaxValue1.Dist = iDist;<BR> MaxValue1.AngleNumber = iAngleNumber;<BR> }<BR><BR> }<BR> }<BR><BR> //将第一个最大值点附近清零<BR> for (iDist = -9;iDist < 10;iDist++)<BR> {<BR> for(iAngleNumber=-1; iAngleNumber<2; iAngleNumber++)<BR> {<BR> if(iDist+MaxValue1.Dist>=0 && iDist+MaxValue1.Dist<iMaxDist \<BR> && iAngleNumber+MaxValue1.AngleNumber>=0 && iAngleNumber+MaxValue1.AngleNumber<=iMaxAngleNumber)<BR> {<BR> *(lpTransArea+(iDist+MaxValue1.Dist)*iMaxAngleNumber+\<BR> (iAngleNumber+MaxValue1.AngleNumber))=0;<BR> }<BR> }<BR> }<BR><BR> //找到第二个最大值点<BR> for (iDist=0; iDist<iMaxDist;iDist++)<BR> {<BR> for(iAngleNumber=0; iAngleNumber<iMaxAngleNumber; iAngleNumber++)<BR> {<BR> if((int)*(lpTransArea+iDist*iMaxAngleNumber+iAngleNumber)>MaxValue2.Value)<BR> {<BR> MaxValue2.Value = (int)*(lpTransArea+iDist*iMaxAngleNumber+iAngleNumber);<BR> MaxValue2.Dist = iDist;<BR> MaxValue2.AngleNumber = iAngleNumber;<BR> }<BR><BR> }<BR> }<BR><BR><BR> //判断两直线是否平行<BR> if(abs(MaxValue1.AngleNumber-MaxValue2.AngleNumber)<=2)<BR> {<BR> //两直线平行,在缓存图像中重绘这两条直线<BR> for(j = 0; j <lHeight; j++)<BR> {<BR> for(i = 0;i <lWidth; i++)<BR> { <BR><BR> // 指向缓存图像倒数第j
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -