文章目录

  • 前言
  • 一、代码实现结果图
  • 二、实现代码及其注释
  • 总结



前言

最近开始上计算机视觉的实验课,使用的软件是matlab。老师布置了一项给代码添加注释的作业,是有关于霍夫变换的。刚接触这个软件和它使用的语言,所以第一次花了一个下午才弄懂这些代码,觉得有纪念意义,所以就写了这篇文章。


一、代码实现结果图

Figure1

python霍夫变换删除直线 霍夫变换matlab代码_html


Figure2

python霍夫变换删除直线 霍夫变换matlab代码_霍夫变换_02

二、实现代码及其注释

代码及注释如下:

%%
% https://ww2.mathworks.cn/help/images/ref/houghlines.html(注释主要来自matlab帮助中心)
clc;    %清除命令行窗口的内容
clear;  %清除工作空间的内容
close all;  %关闭所有的Figure窗口

%% 将图像读入工作区
filename = 'circuit';   %导入实验所需图像
im = imread([filename,'.jpg']); %实验所需图像格式为jpg,进行类型转换

%% 
rotI = imrotate(im,33,'crop');  %图像im旋转33°,并对旋转后的图像进行裁剪,保持输出的
                                %图像rotI的尺寸和输入图像im的尺寸一样(参数‘crop’的作用)
BW = edge(rotI,'canny');    %使用 Canny 方法查找边缘,创建二值图像

%% 使用二值图像进行Hough变换
[H,T,R] = hough(BW);  
    %{
    计算Hough变换
    R(沿垂于线条的向量从原点到线条的距离)
    T(x轴与该向量之间的角度,以°为单位)
    H(参数空间矩阵,其行和列分别对应于R和T的值)
    其中R = x*cos(T) + y*sin(T)    
    %}
imshow(H,[],'Xdata',T,'Ydata',R,'InitialMagnification','fit');  
    %{
    显示Hough矩阵
    使用 'InitialMagnification' 名称-值对组参数以‘fit’率显示图像
    ‘fit’以适应窗口显示
    %}
xlabel('\theta'),ylabel('\rho');    %为横纵坐标加上标签,‘\  ’为希腊字母
axis on,axis normal,hold on;    
    %{
    axis on 绘制曲面同时显示坐标区的线条和背景
    axis normal 将图框纵横比模式和数据纵横比模式的属性设置为自动
    hold on 保留当前坐标区中的绘图,从而使新添加到坐标区中的绘图不会删除现有绘图
    %}
%% 查找图像的Hough变换中的峰值
P = houghpeaks(H,5,'threshold',ceil(0.3*max(H(:))));   
    %{
    在霍夫矩阵H中找到5个极值点,阈值为H中最大值乘以0.3
    只有超过该阈值才会被认定为一条符合条件的直线,在图像中表现为一个点。
    对于极值点的理解,肉眼上越亮的点其值越大(不一定完全准确)。
    这些点亮的原因在于:二维坐标点转换为这种类似于极坐标系后通过该点的曲线数目更多
    参考资料来源:https://blog.csdn.net/YuYunTan/article/details/80141392
    P为这些符合条件的坐标的集合,但P的形式为矩阵
    %}
x = T(P(:,2)); y = R(P(:,1));   
    %{
    x为矩阵P第二列全部坐标的角度值,y为矩阵P的第一列全部坐标的距离值。
    我的理解:P和R类似于其他语言中的强制类型转换。(这个比喻其实不恰当,但是一时半会不知道怎么解释)
    参考资料来源:https://zhidao.baidu.com/question/314711017.html
    %}
plot(x,y,'s','color','white');  %绘制二维线图,坐标点形状为方形(‘s’),颜色为白色
%% 查找线条并对其绘画
lines = houghlines(BW,T,R,P,'FillGap',5,'MinLength',7); 
    %{
    houghlines函数可以找出标准霍夫变换的二值图像线条,其基于霍夫变换
    BW是8位的单通道二进制图像
    'FillGap'是一个正实数,表示同一图像中两条线段的距离。当两条线的距离小于指定值时,houghlines函数就会将这两条线合并为一条线。(这里FillGap的值为5)
    'MinLength'是一个正实数,用来确定是否保存线条的长度小于这个值,线条就会被擦除,否则会保存。(这里MinLength的值为7)
    参看资料来源:https://zhidao.baidu.com/question/537268196.html
    返回值lines是被提取出来的线段
    %}
figure, imshow(rotI), hold on;   %figure创建一个新的图窗窗口
max_len = 0;    %初始化max_len
for k = 1:length(lines) %遍历lines
    xy = [lines(k).point1;lines(k).point2]; 
        %{ 
        .point1和.point2是直线的两个端点
        [a;b]形式是指把矩阵b放到矩阵a之后,最后得到一个新的矩阵
        lines(k).point1=[起点的x,起点的y] , links(k).point2=[终点的x,终点的y]
        xy = [ 起点的x,起点的y
               终点的x,重点的y]  这个样子的矩阵
        资料来源:https://www.ilovematlab.cn/thread-539681-1-1.html
        https://zhidao.baidu.com/question/417767976.html
        %}
    plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','green');    %画线段,宽为2,绿色
    plot(xy(1,1),xy(1,2),'x','LineWidth',2,'Color','yellow');   %线段起点,形状叉号,线宽为2,颜色为黄
    plot(xy(2,1),xy(2,2),'x','LineWidth',2,'Color','red');  %线段终点,形状叉号,线宽为2,颜色为红
    % 可以注意一下线段和点的不同表示方式
    len = norm(lines(k).point1 - lines(k).point2);  %选出最长的线段
    if(len > max_len)
        max_len = len;
        xy_long = xy;
    end
end

%% 将最长线段设为青色以突出显示
plot(xy_long(:,1),xy_long(:,2),'LineWidth',2,'Color','cyan');