http://blog.csdn.net/cay22/
在對圖像進行邊緣檢測處理時,得到的結果並不是理想的邊緣,
Sobel邊緣細化的原理
圖像的邊緣檢測處理可以簡單理解為提取圖像中區域的輪廓。
圖像邊緣檢測的結果直觀地看類似圖像的骨架,對圖像邊緣檢測結果
圖11-27 圖像的邊緣檢測示例
從圖11-27中可以看出,Sobel邊緣檢測的結果能用線條較
換一種思路,如果把Sobel邊緣檢測結果中的輪廓線條看作一個
圖11-28 圖像的邊緣檢測和減法細化
從圖中不難看出,
圖像的細化同樣可以利用鄰域分析的方法來完成,考慮在圖像的3×
圖11-29 圖像鄰域像素情況
在圖像細化中,如果能夠根據鄰域內像素灰度情況,
不妨借助統計排序濾波器的思想,在決定中心像素是否保留的時候,
圖11-30 利用鄰域分析對圖像進行細化
經過邊緣細化的圖像常常存在低灰度的雜點干擾,同時,
11.6.2 Sobel邊緣細化的編程實現
有關圖像的邊緣檢測算法實現將在本書第13章中給出,
1.利用減法實現圖像的細化
由於圖像細化中的各方法可以自由組合,這裡只給出各方法的實現,
/*****************************
* 把線性存儲的像素轉化為二維數組形式
* 參數: image為線性存儲的像素,width、height為圖像的
* 方法實現見11.1.3小節
******************************
BYTE** CreatImage(BYTE* image, unsigned int width, unsigned int height, int bt=4);
/*****************************
* 功能: 獲得圖像灰度,采用直接對RGB求平均值的方法
* 參數: imageBuf為目標圖像,x、y為要取得像素的坐標
* 方法實現見11.1.1小節
******************************
BYTE GetAsh(BYTE** imageBuf0, int x, int y);
/*****************************
* 功能: 設定指定位置的像素灰度
* 參數: imageBuf為目標圖像,x、y為要設定像素的坐標
* 方法實現見11.1.3小節
******************************
void SetPixelXY(BYTE** imageBuf1, int x, int y, int a);
/*****************************
* 功能: Sobel邊緣檢測
* 參數: image0為原圖形,image1為要減去的圖像
* w、h為圖像的寬和高
* 當type為true時,
* 否則取平均值(方法實現見本書第13章)
******************************
void SideSobel(BYTE* image0, BYTE* image1,
unsigned int w, unsigned int h, bool type);
/*****************************
* 功能: 對圖像進行二值化處理
* 參數: image0為原圖形,image1為處理的結果圖像
* w、h為圖像的寬和高
* K為閾值
******************************
void ToTwoValue(BYTE* image0, BYTE* image1, unsigned int w, unsigned int h,
int K)
{
//將圖像轉化為矩陣形式
BYTE** imageBuf0 = CreatImage(image0, w, h);
BYTE** imageBuf1 = CreatImage(image1, w, h);
int x,y;
//依次對源圖像的每個像素進行處理
for(y=0; y<h; y++)
for(x=0; x<w; x++)
{
//如果當前點已經為單點,則在結果圖中用黑色標記
if( GetAsh(imageBuf0,x,y) >=K )
{
SetPixelXY (imageBuf1,x,y,255 );
}
//如果當前點不是單點,則在結果圖中用白色標記
else
{
SetPixelXY(imageBuf1,x,y,0);
}
}
//清理內存
free(imageBuf0);
free(imageBuf1);
}
/*****************************
* 功能: 對兩幅圖像進行減法運算
* 參數: image0為原圖形,image1為要減去的圖像
* w、h為圖像的寬和高
******************************
void Subtract(BYTE* image0, BYTE* image1, unsigned int w, unsigned int h)
{
//將圖像轉化為矩陣形式
BYTE** imageBuf0 = CreatImage(image0, w, h);
BYTE** imageBuf1 = CreatImage(image1, w, h);
int x,y;
int a;
//依次對源圖像的每個像素進行處理
for(y=0; y<h; y++)
for(x=0; x<w; x++)
{
//取得源圖像灰度
a=GetAsh(imageBuf0,x,y);
//進行減法運算
a=a-GetAsh(imageBuf1,x,y);
//過限處理
a = a>255?255:a;
a = a<0?0:a;
SetPixelXY(imageBuf1,x,y,a);
}
//清理內存
free(imageBuf0);
free(imageBuf1);
}
/*****************************
* 功能: 對兩幅圖像進行加法運算
* 參數: image0為原圖形,image1為要減去的圖像
* w、h為圖像的寬和高
******************************
void AshAdd(BYTE* image0, BYTE* image1, unsigned int w, unsigned int h)
{
//將圖像轉化為矩陣形式
BYTE** imageBuf0 = CreatImage(image0, w, h);
BYTE** imageBuf1 = CreatImage(image1, w, h);
int x,y,c;
int a;
//依次對源圖像的每個像素進行處理
for(y=0; y<h; y++)
for(x=0; x<w; x++)
{
//取得源圖像灰度
a=GetAsh(imageBuf0,x,y);
//進行減法運算
a=a+GetAsh(imageBuf1,x,y);
//過限處理
a = a>255?255:a;
a = a<0?0:a;
SetPixelXY(imageBuf1,x,y,a);
}
//清理內存
free(imageBuf0);
free(imageBuf1);
}
2.利用鄰域分析實現圖像的細化
/*****************************
* 把線性存儲的像素轉化為二維數組形式
* 參數: image為線性存儲的像素,width、height為圖像的
* 方法實現見11.1.3小節
******************************
BYTE** CreatImage(BYTE* image, unsigned int width, unsigned int height, int bt=4);
/*****************************
* 功能: 獲得圖像灰度,采用直接對RGB求平均值的方法
* 參數: imageBuf為目標圖像,x、y為要取得像素的坐標
* 方法實現見11.1.1小節
******************************
BYTE GetAsh(BYTE** imageBuf0, int x, int y);
/*****************************
* 功能: 設定指定位置的像素灰度
* 參數: imageBuf為目標圖像,x、y為要設定像素的坐標
* 方法實現見11.1.3小節
******************************
void SetPixelXY(BYTE** imageBuf1, int x, int y, int a);
/*****************************
* 功能: 對圖像進行二值化處理
* 參數: image0為原圖形,image1為處理的結果圖像
* w、h為圖像的寬和高
* K為閾值
* 方法實現見「利用減法實現圖像的細化」一節
******************************
void ToTwoValue(BYTE* image0, BYTE* image1, unsigned int w, unsigned int h,
int K)
/*****************************
* 功能: 判斷當前鄰域的中心像素是否該保留
* 參數: imageBuf為目標圖像,w、h為圖像大小
* x、y為當前采樣窗口中心像素的坐標
* K為閾值
******************************
bool IsOnePoint(BYTE** imageBuf0, int w, int h, int x, int y, int K)
{
int i,j,k;
int px,py;
int a; //用來保存中心像素灰度
a=GetAsh(imageBuf0,x,y);
k=0; //計數器
//從采樣窗口中依次取得每個像素的灰度
for(i=0; i<3; i++)
for(j=0; j<3; j++)
{
py=y-1+i;
px=x-1+j;
//如果該像素灰度大於中心像素則計數器加1
if(GetAsh(imageBuf0,px,py)>a)
{
k++;
}
}
//如果中心像素灰度值處於鄰域內前三位,
if(k<K)
return true;
else
return false;
}
/*****************************
* 功能: 對圖像進行單點化處理
* 參數: image0為原圖形,image1為處理的結果圖像
* w、h為圖像的寬和高
* K為閾值
******************************
void ToOnePointWide(BYTE* image0, BYTE* image1,
unsigned int w, unsigned int h, int K)
{
//將圖像轉化為矩陣形式
BYTE** imageBuf0 = CreatImage(image0, w, h);
BYTE** imageBuf1 = CreatImage(image1, w, h);
int x,y,c;
int a;
//依次對源圖像的每個像素進行處理
for(y=1; y<h-1; y++)
for(x=1; x<w-1; x++)
{
//如果當前點已經為單點 則在結果圖中用黑色標記
if( IsOnePoint(imageBuf0,w,h,x,y,
{
SetPixelXY(imageBuf1,x,y,
}
//如果當前點不是單點 則在結果圖中用白色標記
else
{
SetPixelXY(imageBuf1,x,y,0);
}
}
//清理內存
free(imageBuf0);
free(imageBuf1);
}
圖11-31為經過二值化處理的圖像邊緣細化結果,其中a為源圖
圖11-31 二值化處理後的圖像邊緣細化結果
本節通過Sobel邊緣細化介紹了兩種全新的圖像增強處理思路,