/***********************************************************************
* 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邊緣檢測後, 再細化的圖
沒有留言:
張貼留言