对于直角坐标系里的一条直线l,可用ρ,θ来表示该直线,相应的直线方程为 ρ = x c o s θ + y s i n θ ρ=xcosθ+ysinθ ρ=xcosθ+ysinθ,其中,ρ是原点到该直线的垂直距离,θ是垂线与x轴的夹角,这条直线是惟一的。
构造一个参数(ρ,θ)的平面,从而(ρ,θ)平面的一点,对应一条直线。
【结论】:ρ,θ坐标系中的一个点对应x,y坐标系中的一条直线。而x,y坐标系中的一个点对应ρ,θ坐标系中的一组点(一条曲线),x,y坐标系中直线上的所有点在ρ,θ坐标系中对应的所有曲线交汇到一个点上。
根据点-线对偶性把检测问题转换到参数空间,通过简单的累加统计完成检测任务。
1.在参数空间(ρ,θ)里建立一个2D累加数组A(ρ,θ),初始化为0;
2.对XY空间中的每一个给定点做Hough变换,让θ在[θmin,θmax]区间取所有可能的值,并求出ρ;
3.根据ρ,θ取整数值在A(ρ,θ)处累加A(ρ,θ)=A(ρ,θ)+1,A(ρ,θ)的值说明多少点是共线的,最大值所对应的(ρ,θ)的值也对应了直线方程的参数。
如:
上图中,0表示零条直线穿过,1表示一条直线穿过,2表示两条直线穿过,3表示三条直线穿过,4表示四条直线穿过。
而累加器A中就存储了这样的信息。
Hough变换
ρ = x ∗ c o s ( θ ) + y ∗ s i n ( θ ) ρ = x*cos(θ) + y*sin(θ) ρ=x∗cos(θ)+y∗sin(θ)
[H,theta,rho] = hough(BW,'RhoResolution',0.5,'ThetaResolution',0.5)
确定Hough变换中的峰值
P=houghpeaks(H,2,'Threshold',15);
基于Hough变换提取直线段
P=houghlines(BW,theta,rho,P,'FillGap',5,'MinLength',7);
Im=imread('1.jpg');
[m,n] = size(Im);
%执行Hough变换并显示Hough矩阵
BW = edge(Im,'canny');
[H,T,R] = hough(BW);
imshow(H,[ ],'XData',T,'YData',R,'InitialMagnification','fit');
xlabel('\theta');ylabel('\rho');
axis on, axis normal, hold on;
%在Hough矩阵中寻找前40个大于Hough矩阵中最大值0.24倍峰值
P=houghpeaks(H,40,'threshold',ceil(0.24*max(H(:))));
x = T(P(:,2));y = R(P(:,1));%由行、列索引转换成实际坐标
plot(x,y,'s','color','white');%在Hough矩阵图像标出峰值位置
%找到并绘制直线
lines=houghlines(BW,T,R,P,'FillGap',20,'Minlength',2);%合并距离小于20的线段,丢弃所有长度小于2的线段
figure(2),imshow(Im),hold on
max_len = 0;
for k = 1:length(lines)%依次标出各条直线段
xy = [lines(k).point1;lines(k).point2];
plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','black');
%确定最长线段的端点
len = norm(lines(k).point1 - lines(k).point2);%最长线段的长度
if ( len > max_len)
max_len = len;
xy_long = xy;
end
end
部分显示效果:
如果对你有所帮助,记得点个赞哟~