/***********************************************************************
* Sobel边缘检测 (scale=0.5)
* 参数: image0为原图形,image1为边缘检测结果,w、h为图像的宽和高
* 当type为true时,差分结果取水平和垂直方向差分中较大者,否则取平均值
************************************************************************/
void SideSobel(BYTE* image0, BYTE* image1, unsigned int w, unsigned int h, bool type)
{
int x, y, a, aHr, aHg, aHb, aVr, aVg, aVb, aH, aV;
long n;
double scale = 0.2; // 该值是动态的,
//依次处理每个像素
for(y = 1; y < h-1; y++)
for(x = 1; x < w-1; x++)
{
//计算像素的偏移位置
n = (y*w+x)*4;
//计算红色分量水平灰度差
aHr = abs( (image0[n-w*4-4]+image0[n-4]*2+image0[n+w*4-4])
- (image0[n-w*4+4]+image0[n+4]*2+image0[n+w*4+4]) );
//计算红色分量垂直灰度差
aVr = abs( (image0[n-w*4-4]+image0[n-w*4]*2+image0[n-w*4+4])
- (image0[n+w*4-4]+image0[n+w*4]*2+image0[n+w*4+4]) );
//计算绿色分量水平灰度差
aHg = abs( (image0[n-w*4-4+1]+image0[n-4+1]*2+image0[n+w*4-4+1])
- (image0[n-w*4+4+1]+image0[n+4+1]*2+image0[n+w*4+4+1]) );
//计算绿色分量垂直灰度差
aVg = abs( (image0[n-w*4-4+1]+image0[n-w*4+1]*2+image0[n-w*4+4+1])
- (image0[n+w*4-4+1]+image0[n+w*4+1]*2+image0[n+w*4+4+1]) );
//计算蓝色分量水平灰度差
aHb = abs( (image0[n-w*4-4+2]+image0[n-4+2]*2+image0[n+w*4-4+2])
- (image0[n-w*4+4+2]+image0[n+4+2]*2+image0[n+w*4+4+2]) );
//计算蓝色分量垂直灰度差
aVb = abs( (image0[n-w*4-4+2]+image0[n-w*4+2]*2+image0[n-w*4+4+2])
- (image0[n+w*4-4+2]+image0[n+w*4+2]*2+image0[n+w*4+4+2]) );
//计算水平综合灰度差
aH = aHr + aHg + aHb;
//计算垂直综合灰度差
aV = aVr + aVg + aVb;
if(type)
{
//取水平和垂直方向差分中较大者
if(aH > aV) a = aH;
else a = aV;
}
else
{
//取水平和垂直方向差分的平均值
a = (aH + aV)/2;
}
a = a *scale;
a = a>255?255:a;
//生成边缘扫描结果
SetPixel(image1,n,a);
}
}
注意 边缘细化与边缘检查是不同的, 一般直接对图片细化, 可能效果不是很好, 所以先进行边缘检测, 再进行细化效果会好一点。
A. 原图
B. 直接细化图
C. Sobel边缘检测图
D. 经过Sobel边缘检测后, 再细化的图