边缘链接 matlab,图像分割——边缘检测——边缘连接的全局处理——霍夫变换(Matlab)...
clc;
clear all;
close all;
%邊緣連接測試圖像
I=im2double(imread('D:\Gray Files\10-34.tif'));
[M,N]=size(I);
n=13;
%尋找圖像的邊緣
sigma=2;
H=0.15;
L=0.05;
g_c=CannyEdgeDetector(n,sigma,H,L,I);
%找出所有的邊線點
[rows,cols]=find(g_c);
points=cat(2,rows,cols);
%進行霍夫變換,Hough Transform
theta_max=90;
theta_range=-theta_max:theta_max;
n=length(theta_range);
rho_max=floor(sqrt(M^2+N^2));
rho_range=-rho_max:rho_max;
m=length(rho_range);
Hough=zeros(m,n);
%霍夫變換后的矩陣,行與上述邊界點集相對應,列為每一個點的霍夫轉換
while ~isempty(points)
%取出堆棧頂上的點
p=points(1,:);
%霍夫變換
for k=-90:1:90
j=k+theta_max+1;
%四舍五入
i=round(cosd(k)*p(1,1)+sind(k)*p(1,2))+rho_max+1;
Hough(i,j)=Hough(i,j)+1;
end
%刪除該點
points(1,:)=[];
end
Hou=Hough/max(Hough(:));
for i=1:m
for j=1:n
if Hou(i,j)>0
Hou(i,j)=Hou(i,j)+0.5;
end
end
end
%顯示邊界線的霍夫空間圖像
% imshow(Hou)
%尋找最大值及其在霍夫空間的坐標
%霍夫空間門限
th=200;
T=max(Hough(:));
[rows,cols]=find(Hough==T)
inds=cat(2,rows,cols);
%求解笛卡爾坐標中的線
ps=[];
while ~isempty(inds)
%取出極坐標值
ind=inds(1,:);
rho=ind(1,1);
theta=ind(1,2);
%還原角度和極坐標值
rho=rho-rho_max-1;
theta=theta-theta_max-1;
%定義一條線
g_l=zeros(M,N);
%判斷theta的角度
if theta==0
%取出邊緣圖像中第rho行為1的點
ind=find(g_c(rho,:)==1);
%取出最小下標和最大下標
ind_y_min=ind(1);
ind_y_max=ind(end);
g_l(rho,ind_y_min:ind_y_max)=1;
%與邊緣圖像交集
g_c=g_c+g_l;
else
for i=1:M
j=round((rho-i*cosd(theta))/sind(theta));
if j>0 && j<=N
g_l(i,j)=1;
end
end
g_l_c=and(g_l,g_c);
[rows,cols]=find(g_l_c==1);
ps=cat(2,rows,cols);
ps=sortrows(ps,1);
rows=sort(rows);
ind_x_min=rows(1,1);
ind_x_max=rows(end);
if ind_x_min>1
g_l(1:ind_x_min-1,:)=0;
end
if ind_x_max
g_l(ind_x_max+1:M,:)=0;
end
g_c=g_c+g_l;
end
inds(1,:)=[];
end
imshow(g_c)
hold on
plot(ps(:,2),ps(:,1),'red','LineWidth',2)
hold off
Canny算子,CannyEdgeDetector如下:
%canny邊界檢測器
% n 高斯低通濾波器的大小
% sigma 高斯濾波器參數
% H 高門限
% L 低門限
function [g]=CannyEdgeDetector(n,sigma,H,L,I)
[M,N]=size(I);
%%
%=============================邊緣檢測(五)=================================
% Canny Edge Detector
%-------------------------用高斯低通濾波器平滑圖像-------------------------
%建筑圖像所設參數
% n=25;
% sigma=4;
%頭顱掃描圖像所設參數
% n=13;
% sigma=2;
%lena測試圖像所設參數
% n=5;
% sigma=1;
type='symmetric';
f_s=GaussianBlur(n,I,sigma,type);
% imshow(f_s)
% imwrite(f_s,'D:\Gray Files\lena-test.jpg','jpg');
%-----------------------計算平滑后的圖像梯度和角度-------------------------
n_l=1;
%Sobel算子
s_y=[-1 -2 -1;
0 0 0;
1 2 1];
s_x=[-1 0 1;
-2 0 2;
-1 0 1];
%定義梯度和角度
gx=zeros(M,N);
gy=zeros(M,N);
f_s_pad=padarray(f_s,[n_l,n_l],'replicate');
for i=1:M
for j=1:N
Block=f_s_pad(i:i+2*n_l,j:j+2*n_l);
gx(i,j)=sum(sum(Block.*s_x));
gy(i,j)=sum(sum(Block.*s_y));
end
end
type='replicate';
gx=GaussianBlur(n,gx,sigma,type);
gy=GaussianBlur(n,gy,sigma,type);
M_s=sqrt(gx.^2+gy.^2);
M_s=M_s/max(M_s(:));
a_s=atan2(gy,gx)*180/pi;
%--------------------對梯度圖像進行差值非極大值抑制------------------------
n_l=1;
%定義非極大值抑制圖像
g_N=M_s;
M_s_pad=padarray(M_s,[n_l,n_l],'replicate');
for i=1:M
for j=1:N
%取出中心點的梯度值
K=M_s_pad(i+1,j+1);
theta=a_s(i,j);
if (theta>=0 && theta<=45) ||...
(theta=-180)
yBot=[M_s_pad(i+1,j+2) M_s_pad(i+2,j+2)];
yTop=[M_s_pad(i+1,j) M_s_pad(i,j)];
k=abs(gy(i,j)/M_s_pad(i+1,j+1));
K1=(yBot(2)-yBot(1))*k+yBot(1);
K2=(yTop(2)-yTop(1))*k+yTop(1);
end
if (theta>45 && theta<=90) ||...
(theta=-135)
yBot=[M_s_pad(i+2,j+1) M_s_pad(i+2,j+2)];
yTop=[M_s_pad(i,j+1) M_s_pad(i,j)];
k=abs(gx(i,j)/M_s_pad(i+1,j+1));
K1=(yBot(2)-yBot(1))*k+yBot(1);
K2=(yTop(2)-yTop(1))*k+yTop(1);
end
if (theta>90 && theta<=135) ||...
(theta=-90)
yBot=[M_s_pad(i+2,j+1) M_s_pad(i+2,j)];
yTop=[M_s_pad(i,j+1) M_s_pad(i,j+2)];
k=abs(gx(i,j)/M_s_pad(i+1,j+1));
K1=(yBot(2)-yBot(1))*k+yBot(1);
K2=(yTop(2)-yTop(1))*k+yTop(1);
end
if (theta>135 && theta<=180) ||...
(theta<0&& theta>=-45)
yBot=[M_s_pad(i+1,j) M_s_pad(i+2,j)];
yTop=[M_s_pad(i+1,j+2) M_s_pad(i,j+2)];
k=abs(gy(i,j)/M_s_pad(i+1,j+1));
K1=(yBot(2)-yBot(1))*k+yBot(1);
K2=(yTop(2)-yTop(1))*k+yTop(1);
end
if K
g_N(i,j)=0;
end
end
end
g_N=g_N/max(g_N(:));
imshow(g_N)
%-------------------------------設置雙門限---------------------------------
%對非極大值抑制圖像進行擴展(0),方便后續的邊界處理
n_l=1;
g_N_pad=padarray(g_N,[n_l,n_l],'replicate');
T_max=max(g_N_pad(:));
%lena圖像所設參數
% T_max=max(g_N_pad(:));
% H=0.275;
% L=0.25;
%高門限
% T_H=T_max*H;
%低門限
% T_L=T_H*L;
%頭顱圖像所設參數
% T_H=0.15;
% T_L=0.05;
T_H=H;
T_L=L;
%建筑圖像所設參數
% H=0.1;
% L=0.04;
%高門限
% T_H=T_max*H;
% %低門限
% T_L=T_H*L;
%尋找大于高門限點
ind_H=find(g_N_pad>T_H);
g_N_pad(ind_H)=1;
ind_Zeros=find(g_N_pad
g_N_pad(ind_Zeros)=0;
% imshow(g_N_pad)
%--------------------------消除未連通的邊界點------------------------------
M_temp=M+2;
g_N_copy=g_N_pad;
g_N_copy(ind_H)=0;
ind_L=find(g_N_copy~=0);
g_N_pad(ind_L)=1;
while ~isempty(ind_H)
%取出第一個點
p=ind_H(1,1);
%初始化連通點集
Conn=[];
%查找p點是否有連通點,即在ind_L中是否有值
[ind_L,Conn]=FindConnected_8(p,ind_L,Conn,M_temp);
%向下查找所有與p點連通的點
while ~isempty(Conn)
%從連通集中取出第一個點,而后刪除該點
p1=Conn(1,:);
Conn(1,:)=[];
[ind_L,Conn]=FindConnected_8(p1,ind_L,Conn,M_temp);
end
%標記p點已訪問,即從ind_H中刪除
ind_H(1,:)=[];
end
%將ind_L中未與ind_H連通的點,在圖像中置零
g_N_pad(ind_L)=0;
g_N=g_N_pad(2:M+1,2:N+1);
%-----------------------------圖像細化處理-----------------------------
[g]=ImageThinning(g_N);
% imshow(g)
end
Canny算子中的其他函數,如GaussianBlur、FindConnected_8、ImageThinning參見上一篇博文,這里就不在重復粘貼了
標簽:yTop,max,yBot,霍夫,pad,Matlab,theta,ind,邊緣連接
來源: https://blog.csdn.net/lengo/article/details/100586228
總結
以上是生活随笔為你收集整理的边缘链接 matlab,图像分割——边缘检测——边缘连接的全局处理——霍夫变换(Matlab)...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Kafka 压缩、限流和 SASL_PL
- 下一篇: Coffice协同办公管理系统(C#)(