📄 edgecontour.cpp
字号:
if (!Template(lpNewDIBBits2, lWidth, lHeight, iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC)) { return FALSE; } //求两幅缓存图像的最大值 for(j = 0; j <lHeight; j++) { for(i = 0;i <lWidth-1; i++) { // 指向缓存图像1倒数第j行,第i个象素的指针 lpDst1 = (char *)lpNewDIBBits1 + lWidth * j + i; // 指向缓存图像2倒数第j行,第i个象素的指针 lpDst2 = (char *)lpNewDIBBits2 + lWidth * j + i; if(*lpDst2 > *lpDst1) *lpDst1 = *lpDst2; } } // 拷贝源图像到缓存图像中 memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight); // 设置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)) { return FALSE; } //求两幅缓存图像的最大值 for(j = 0; j <lHeight; j++) { for(i = 0;i <lWidth-1; i++) { // 指向缓存图像1倒数第j行,第i个象素的指针 lpDst1 = (char *)lpNewDIBBits1 + lWidth * j + i; // 指向缓存图像2倒数第j行,第i个象素的指针 lpDst2 = (char *)lpNewDIBBits2 + lWidth * j + i; if(*lpDst2 > *lpDst1) *lpDst1 = *lpDst2; } } // 拷贝源图像到缓存图像中 memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight); // 设置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)) { return FALSE; } // 拷贝源图像到缓存图像中 memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight); //求两幅缓存图像的最大值 for(j = 0; j <lHeight; j++) { for(i = 0;i <lWidth-1; i++) { // 指向缓存图像1倒数第j行,第i个象素的指针 lpDst1 = (char *)lpNewDIBBits1 + lWidth * j + i; // 指向缓存图像2倒数第j行,第i个象素的指针 lpDst2 = (char *)lpNewDIBBits2 + lWidth * j + i; if(*lpDst2 > *lpDst1) *lpDst1 = *lpDst2; } } // 拷贝源图像到缓存图像中 memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight); // 设置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)) { return FALSE; } //求两幅缓存图像的最大值 for(j = 0; j <lHeight; j++) { for(i = 0;i <lWidth-1; i++) { // 指向缓存图像1倒数第j行,第i个象素的指针 lpDst1 = (char *)lpNewDIBBits1 + lWidth * j + i; // 指向缓存图像2倒数第j行,第i个象素的指针 lpDst2 = (char *)lpNewDIBBits2 + lWidth * j + i; if(*lpDst2 > *lpDst1) *lpDst1 = *lpDst2; } } // 拷贝源图像到缓存图像中 memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight); // 设置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)) { return FALSE; } //求两幅缓存图像的最大值 for(j = 0; j <lHeight; j++) { for(i = 0;i <lWidth-1; i++) { // 指向缓存图像1倒数第j行,第i个象素的指针 lpDst1 = (char *)lpNewDIBBits1 + lWidth * j + i; // 指向缓存图像2倒数第j行,第i个象素的指针 lpDst2 = (char *)lpNewDIBBits2 + lWidth * j + i; if(*lpDst2 > *lpDst1) *lpDst1 = *lpDst2; } } // 拷贝源图像到缓存图像中 memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight); // 设置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)) { return FALSE; } //求两幅缓存图像的最大值 for(j = 0; j <lHeight; j++) { for(i = 0;i <lWidth-1; i++) { // 指向缓存图像1倒数第j行,第i个象素的指针 lpDst1 = (char *)lpNewDIBBits1 + lWidth * j + i; // 指向缓存图像2倒数第j行,第i个象素的指针 lpDst2 = (char *)lpNewDIBBits2 + lWidth * j + i; if(*lpDst2 > *lpDst1) *lpDst1 = *lpDst2; } } // 复制经过模板运算后的图像到源图像 memcpy(lpDIBBits, lpNewDIBBits1, lWidth * lHeight); // 释放内存 LocalUnlock(hNewDIBBits1); LocalFree(hNewDIBBits1); LocalUnlock(hNewDIBBits2); LocalFree(hNewDIBBits2); // 返回 return TRUE;}/************************************************************************* * * 函数名称: * GaussDIB() * * 参数: * LPSTR lpDIBBits - 指向源DIB图像指针 * LONG lWidth - 源图像宽度(象素数,必须是4的倍数) * LONG lHeight - 源图像高度(象素数) * 返回值: * BOOL - 边缘检测成功返回TRUE,否则返回FALSE。 * * 说明: * 该函数用高斯拉普拉斯边缘检测算子对图像进行边缘检测运算。 * * 要求目标图像为灰度图像。 ************************************************************************/BOOL WINAPI GaussDIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight){ // 指向缓存图像的指针 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); if (hNewDIBBits1 == NULL) { // 分配内存失败 return FALSE; } // 锁定内存 lpNewDIBBits1 = (char * )LocalLock(hNewDIBBits1); // 暂时分配内存,以保存新图像 hNewDIBBits2 = LocalAlloc(LHND, lWidth * lHeight); if (hNewDIBBits2 == NULL) { // 分配内存失败 return FALSE; } // 锁定内存 lpNewDIBBits2 = (char * )LocalLock(hNewDIBBits2); // 拷贝源图像到缓存图像中 lpDst1 = (char *)lpNewDIBBits1; memcpy(lpNewDIBBits1, lpDIBBits, lWidth * lHeight); lpDst2 = (char *)lpNewDIBBits2; memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight); // 设置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)) { return FALSE; } // 复制经过模板运算后的图像到源图像 memcpy(lpDIBBits, lpNewDIBBits1, lWidth * lHeight); // 释放内存 LocalUnlock(hNewDIBBits1); LocalFree(hNewDIBBits1); LocalUnlock(hNewDIBBits2); LocalFree(hNewDIBBits2); // 返回 return TRUE;}/************************************************************************* * * 函数名称: * HoughDIB() * * 参数: * LPSTR lpDIBBits - 指向源DIB图像指针 * LONG lWidth - 源图像宽度(象素数,必须是4的倍数) * LONG lHeight - 源图像高度(象素数) * 返回值: * BOOL - 运算成功返回TRUE,否则返回FALSE。 * * 说明: * 该函数用于对检测图像中的平行直线。如果图像中有两条平行的直线,则将这两条平行直线 * 提取出来。 * * 要求目标图像为只有0和255两个灰度值的灰度图像。 ************************************************************************/BOOL WINAPI HoughDIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight){ // 指向源图像的指针 LPSTR lpSrc; // 指向缓存图像的指针 LPSTR lpDst; // 指向变换域的指针 LPSTR lpTrans; // 图像每行的字节数 LONG lLineBytes; // 指向缓存DIB图像的指针 LPSTR lpNewDIBBits; HLOCAL hNewDIBBits; //指向变换域的指针 LPSTR lpTransArea; HLOCAL hTransArea; //变换域的尺寸 int iMaxDist; int iMaxAngleNumber; //变换域的坐标 int iDist; int iAngleNumber; //循环变量 long i; long j; //像素值 unsigned char pixel; //存储变换域中的两个最大值 MaxValue MaxValue1; MaxValue MaxValue2; // 暂时分配内存,以保存新图像 hNewDIBBits = LocalAlloc(LHND, lWidth * lHeight); if (hNewDIBBits == NULL) { // 分配内存失败 return FALSE; } // 锁定内存 lpNewDIBBits = (char * )LocalLock(hNewDIBBits); // 初始化新分配的内存,设定初始值为255 lpDst = (char *)lpNewDIBBits; memset(lpDst, (BYTE)255, lWidth * lHeight); //计算变换域的尺寸 //最大距离 iMaxDist = (int) sqrt(lWidth*lWidth + lHeight*lHeight); //角度从0-180,每格2度 iMaxAngleNumber = 90; //为变换域分配内存 hTransArea = LocalAlloc(LHND, lWidth * lHeight * sizeof(int)); if (hNewDIBBits == NULL) { // 分配内存失败 return FALSE; } // 锁定内存 lpTransArea = (char * )LocalLock(hTransArea); // 初始化新分配的内存,设定初始值为0 lpTrans = (char *)lpTransArea; memset(lpTrans, 0, lWidth * lHeight * sizeof(int)); // 计算图像每行的字节数 lLineBytes = WIDTHBYTES(lWidth * 8); for(j = 0; j <lHeight; j++) { for(i = 0;i <lWidth; i++) { // 指向源图像倒数第j行,第i个象素的指针 lpSrc = (char *)lpDIBBits + lLineBytes * j + i; //取得当前指针处的像素值,注意要转换为unsigned char型 pixel = (unsigned char)*lpSrc; //目标图像中含有0和255外的其它灰度值 if(pixel != 255 && *lpSrc != 0) return FALSE; //如果是黑点,则在变换域的对应各点上加1 if(pixel == 0) { //注意步长是2度 for(iAngleNumber=0; iAngleNumber<iMaxAngleNumber; iAngleNumber++) { iDist = (int) fabs(i*cos(iAngleNumber*2*pi/180.0) + \ j*sin(iAngleNumber*2*pi/180.0)); //变换域的对应点上加1 *(lpTransArea+iDist*iMaxAngleNumber+iAngleNumber) = \ *(lpTransArea+iDist*iMaxAngleNumber+iAngleNumber) +1; } } } } //找到变换域中的两个最大值点 MaxValue1.Value=0; MaxValue2.Value=0; //找到第一个最大值点 for (iDist=0; iDist<iMaxDist;iDist++) { for(iAngleNumber=0; iAngleNumber<iMaxAngleNumber; iAngleNumber++) { if((int)*(lpTransArea+iDist*iMaxAngleNumber+iAngleNumber)>MaxValue1.Value) { MaxValue1.Value = (int)*(lpTransArea+iDist*iMaxAngleNumber+iAngleNumber); MaxValue1.Dist = iDist; MaxValue1.AngleNumber = iAngleNumber; } } } //将第一个最大值点附近清零 for (iDist = -9;iDist < 10;iDist++) { for(iAngleNumber=-1; iAngleNumber<2; iAngleNumber++) { if(iDist+MaxValue1.Dist>=0 && iDist+MaxValue1.Dist<iMaxDist \ && iAngleNumber+MaxValue1.AngleNumber>=0 && iAngleNumber+MaxValue1.AngleNumber<=iMaxAngleNumber) { *(lpTransArea+(iDist+MaxValue1.Dist)*iMaxAngleNumber+\ (iAngleNumber+MaxValue1.AngleNumber))=0; } } } //找到第二个最大值点 for (iDist=0; iDist<iMaxDist;iDist++) { for(iAngleNumber=0; iAngleNumber<iMaxAngleNumber; iAngleNumber++) { if((int)*(lpTransArea+iDist*iMaxAngleNumber+iAngleNumber)>MaxValue2.Value) { MaxValue2.Value = (int)*(lpTransArea+iDist*iMaxAngleNumber+iAngleNumber); MaxValue2.Dist = iDist; MaxValue2.AngleNumber = iAngleNumber; } } } //判断两直线是否平行 if(abs(MaxValue1.AngleNumber-MaxValue2.AngleNumber)<=2) { //两直线平行,在缓存图像中重绘这两条直线 for(j = 0; j <lHeight; j++) { for(i = 0;i <lWidth; i++) { // 指向缓存图像倒数第j行,第i个象素的指针 lpDst = (char *)lpNewDIBBits + lLineBytes * j + i; //如果该点在某一条平行直线上,则在缓存图像上将该点赋为黑 //在第一条直线上 iDist = (int) fabs(i*cos(MaxValue1.AngleNumber*2*pi/180.0) + \ j*sin(MaxValue1.AngleNumber*2*pi/180.0)); if (iDist == MaxValue1.Dist) *lpDst = (unsigned char)0; //在第二条直线上 iDist = (int) fabs(i*cos(MaxValue2.AngleNumber*2*pi/180.0) + \ j*sin(MaxValue2.AngleNumber*2*pi/180.0)); if (iDist == MaxValue2.Dist) *lpDst = (unsigned char)0; } } } // 复制腐蚀后的图像 memcpy(lpDIBBits, lpNewDIBBits, lWidth * lHeight); // 释放内存 LocalUnlock(hNewDIBBits); LocalFree(hNewDIBBits); // 释放内存 LocalUnlock(hTransArea); LocalFree(hTransArea);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -