点、线和边缘检测
霍夫变换
考虑直线的法线表示 x c o s θ + y s i n θ = ρ xcos\theta+ysin\theta=\rho xcosθ+ysinθ=ρ,及其参数空间 ( ρ , θ ) (\rho, \theta) (ρ,θ). 其中 − 9 0 o ≤ θ ≤ 9 0 o -90^o\leq \theta\leq 90^o −90o≤θ≤90o, − D ≤ ρ ≤ D -D\leq \rho\leq D −D≤ρ≤D, D D D是图像对角最大距离。
-
算法步骤
-
- 将参数空间 ( ρ , θ ) (\rho, \theta) (ρ,θ)划分为有限数量的累加器,累加器的值初始化为0.
-
- 对于 x y xy xy空间的每个非背景点,令 θ \theta θ等于 θ \theta θ轴上每个允许的值,利用公式 ρ = x c o s θ + y s i n θ \rho=xcos\theta+ysin\theta ρ=xcosθ+ysinθ解出round( ρ \rho ρ)
-
- 将得到的 ( ρ , θ ) (\rho, \theta) (ρ,θ)对应的adder+=1
最终,累加器 ( ρ , θ ) (\rho, \theta) (ρ,θ)的值等价于 x y xy xy空间中位于该直线上点的数量。算法复杂度 O ( n ) O(n) O(n).
-
Matlab实现的注意点
-
- 需要先对图像做阈值处理化为0-1图像
-
- 初始化参数空间
(
ρ
,
θ
)
(\rho, \theta)
(ρ,θ)时,注意矩阵大小应为
img_hough = zeros(2*(D/dD)+1, 2*(90/dtheta)+1)
如下图所示
- 初始化参数空间
(
ρ
,
θ
)
(\rho, \theta)
(ρ,θ)时,注意矩阵大小应为
-
- 提取直线参数做下游任务时,注意取出二维矩阵最大元素索引的方法为
[val, idx] = max(img_hough);
[val2, idx_col] = max(val);
idx_row = idx(idx_col);
idx_col = idx_col;
霍夫变换代码
close all;clear;clc;
img = imread('./images/tilted.PNG');
imshow(img,[]);
[m, n, c] = size(img);
% thresholding
img_binary = zeros(m,n);
for i = 1:m
for j = 1:n
if img(i,j)<250
img_binary(i,j)=1;
else
img_binary(i,j)=0;
end
end
end
imshow(uint8(img_binary),[]);
% hough
D = m+n;
dD = 1;
dtheta = 1;
img_hough = zeros(2*(D/dD)+1, 2*(90/dtheta)+1);
for i=1:m
for j=1:n
if img_binary(i,j)>0.5
for theta = -90:90
theta_rad = theta/180*pi;
rho = i*cos(theta_rad)+j*sin(theta_rad);
rho = round(rho);
index1 = rho+D+1;
index2 = theta+90+1;
img_hough(index1, index2)=img_hough(index1, index2)+1;
end
end
end
end
imshow(img_hough,[]);
% argmax and its index
[val, idx] = max(img_hough);
[val2, idx_col] = max(val);
idx_row = idx(idx_col);
% rotated angle
angle = idx_col-90-1;
img_final = imrotate(img, -angle, 'bilinear');
imshow(img_final, []);