我可沒直接呼叫系統函式,要是那樣就太水了。其實我的matlab**很容易就能翻譯成c/c++的。
canny邊緣檢測一共四個部分:
1.對原影象高斯平滑
2.對高斯平滑後的影象進行sobel邊緣檢測。這裡需要求橫的和豎的還有聯合的,所以一共三個需要sobel邊緣檢測影象。
3.對聯合的sobel檢測影象進行非極大抑制
4.連線邊緣點並進行滯後閾值處理。
下面是**:
%%canny邊緣檢測的前兩步相對不複雜,所以我就直接呼叫系統函式了
%%高斯濾波
w=fspecial('gaussian',[5 5]);
img=imfilter(img,w,'replicate');
figure;
imshow(uint8(img))
%%sobel邊緣檢測
w=fspecial('sobel');
img_w=imfilter(img,w,'replicate'); %求橫邊緣
w=w';
img_h=imfilter(img,w,'replicate'); %求豎邊緣
img=sqrt(img_w.^2+img_h.^2); %注意這裡不是簡單的求平均,而是平方和在開方。我曾經好長一段時間都搞錯了
figure;
imshow(uint8(img))
%%下面是非極大抑制
new_edge=zeros(m,n);
for i=2:m-1
for j=2:n-1
mx=img_w(i,j);
my=img_h(i,j);
if my~=0
o=atan(mx/my); %邊緣的法線弧度
elseif my==0 && mx>0
o=pi/2;
else
o=-pi/2;
end%mx處用my和img進行插值
adds=get_coords(o); %邊緣畫素法線一側求得的兩點座標,插值需要
m1=my*img(i+adds(2),j+adds(1))+(mx-my)*img(i+adds(4),j+adds(3)); %插值後得到的畫素,用此畫素和當前畫素比較
adds=get_coords(o+pi); %邊緣法線另一側求得的兩點座標,插值需要
m2=my*img(i+adds(2),j+adds(1))+(mx-my)*img(i+adds(4),j+adds(3)); %另一側插值得到的畫素,同樣和當前畫素比較
isbigger=(mx*img(i,j)>m1)*(mx*img(i,j)>=m2)+(mx*img(i,j)up &&new_edge(i,j)~=255 %判斷上閾值
new_edge(i,j)=255;
new_edge=connect(new_edge,i,j,low);
endend
endfigure;
imshow(new_edge==255)
get_coords.m
function re=get_coords(angle) %angle是邊緣法線角度,返回法線前後兩點connect.msigma=0.000000001;
x1=ceil(cos(angle+pi/8)*sqrt(2)-0.5-sigma);
y1=ceil(-sin(angle-pi/8)*sqrt(2)-0.5-sigma);
x2=ceil(cos(angle-pi/8)*sqrt(2)-0.5-sigma);
y2=ceil(-sin(angle-pi/8)*sqrt(2)-0.5-sigma);
re=[x1 y1 x2 y2];
end
function nedge=connect(nedge,y,x,low) %種子定位後的連通分析每步執行效果:neighbour=[-1 -1;-1 0;-1 1;0 -1;0 1;1 -1;1 0;1 1]; %八連通搜尋
[m n]=size(nedge);
for k=1:8
yy=y+neighbour(k,1);
xx=x+neighbour(k,2);
if yy>=1 &&yy<=m &&xx>=1 && xx<=n
if nedge(yy,xx)>=low && nedge(yy,xx)~=255 %判斷下閾值
nedge(yy,xx)=255;
nedge=connect(nedge,yy,xx,low);
endend
end
end
其實應該還有乙個sigma變數,這個是控制高斯模板用的,如果自己做模板當然需要sigma了,這裡就不需要了。至於如何做高斯模板,看這裡。
我主要參考了《特徵提取與影象處理》這本書。
matlab練習程式(Canny邊緣檢測)
matlab練習程式 canny邊緣檢測 我可沒直接呼叫系統函式,要是那樣就太水了。其實我的matlab 很容易就能翻譯成c c 的。canny邊緣檢測一共四個部分 1.對原影象高斯平滑 2.對高斯平滑後的影象進行sobel邊緣檢測。這裡需要求橫的和豎的還有聯合的,所以一共三個需要sobel邊緣檢測...
matlab練習程式(DBSCAN)
和kmeans相比,不需要事先知道資料的類數。以程式設計的角度來考慮,具體演算法流程如下 1.首先選擇乙個待處理資料。2.尋找和待處理資料距離在設定半徑內的資料。3.將找到的半徑內的資料放到乙個佇列中。4.拿佇列頭資料作為當前待處理資料並不斷執行第2步。5.直到遍歷完佇列中所有資料,將這些資料記為一...
matlab練習程式(c c 呼叫matlab)
就我目前了解的c 呼叫matlab有兩種方法。第一種是通過matlab引擎呼叫,也就是這裡用到的方法。第二種是用matlab將m檔案編譯為相應的h lib dll檔案再加以呼叫。使用engine所用到的h和lib檔案基本在d program files matlab r2010b extern裡面,...