目录

动手编码

霍夫演示


动手编码

我们将在这里花一分钟来演示一下,如何使用Matlab构建霍夫变换。

我再重复一遍,在你们的习题集上,你们要做一些Hough代码。

你不能使用已经存在的Hough实现,也不能使用其他任何人的Hough实现。

因为事实证明,当你去写你的Hough实现的时候某些东西会失效。

在这种经历中,你会了解到它的重要元素是什么。

赶快自己编写一个吧。

代码如下:

>>
function [ Hough, theta_range, rho_range ] = naiveHough(I)
% NAIVEHOUGH Peforms the Hough transform in a straightforward way.
[rows, cols] = size(I);theta_maximum = 180;
rho_maximum = floor(sqrt(rows^2 + cols^2)) - 1;
theta_range = -theta_maximum:theta_maximum - 1;
rho_range = -rho_maximum:rho_maximum;Hough = zeros(length(rho_range), length(theta_range));
for row = 1:rowsfor col = 1:colsif I(row, col) > 0 %only find: pixel > 0x = col - 1;y = row - 1;for theta = theta_rangerho = round((x * cosd(theta)) + (y * sind(theta)));  %approximaterho_index = rho + rho_maximum + 1;theta_index = theta + theta_maximum + 1;Hough(rho_index, theta_index) = Hough(rho_index, theta_index) + 1;endendend
end

霍夫演示

为了检测图像中的线条,我们首先需要找到边缘像素。

让我们加载一个图像,把它转换成灰度,然后使用Canny运算找到边缘像素。

>> %% Load image, convert to grayscale and apply Canny operator to find edge pixels
>> img = imread('shapes.png');
>> grays = rgb2gray(img);
>> edge = edge(grays, 'canny');
>>
>> figure , imshow(img), title('original image');
>> figure , imshow(grays), title('Grayscale');
>> figure , imshow(edge), title('Edge pixels');

让我们看看这些是什么样子。

这是原始图像:

如你所见,它有一些线条。

灰度版本:

边缘像素:

现在我们将使用霍夫变换方法来找到直线。为此,我们将使用Matlab中的霍夫函数。

>> %% Apply Hough transform to find candidate lines
>> [accum theta rho] = hough(edges); % Matlab

Matlab文档中可以找到关于这个函数的更多信息:

Octave中的houghtf函数也是同等作用:

第一个返回的值是累加器数组。(一般我们命名为:accum)

第二个是值或角度的向量。(一般我们命名为:theta)

第三个是半径的向量。(一般我们命名为:rho)

我们看看这是什么样子。

>> figure, imagesc(accum, 'XDdata', theta, 'YDdata', rho), title('Hough accumulator');

我们通过 theta 和 rho 值来正确标记每个轴,rho或从原点的距离是沿着Y轴:

角度在x轴上,从 -90° 到 +90°:

好了,我们来找出这个累加器数组中的最大值,我们通过100作为我们感兴趣的最大值:

>> %% Find peaks in the Hough accumulator matrix
>> peaks = houghpeaks(accum, 100); % Matlab

注意,在Octave中需要使用immaximize函数。

让我们在霍夫累加器数组上,画出这些最大值:

>> hold on; plot(theta(peaks(:, 2)), rho(peaks(: ,1)), 'rs'); hold off;

请注意,我们需要使用  和 ρ 值来正确地绘制最大值:

最大值由红色小框标记。最大值向量的大小是13 * 2:

>> size(peaks);

运行结果:13        2

发现了13个最大值,每行包含一个最大值的位置。

第一列具有行值或 y 值,第二列具有 x 值。

使用这些最大值,我们可以找到线段,在Matlab中使用Hough线函数:

>> %% Find lines (segments) in the image.
>> line_segs = houghlines(edges, theta, rho, peaks); % Matlab
>> lin_segs;

代码运行,结果如下:

看起来发现了28条线段。

LangySeg中的每个元素是一个结构,其中两个端点  和 ρ 值。让我们画出这些线段:

>>
figure, imshow(img), title('Line segments');
hold on;
for k = 1:length(line_segs)endpoints = [line_segs(k).point; line_segs(k).point2];plot(endpoints(:, 1), endpoints(:, 2), 'LineWidth', 2, 'Color', 'green');
end
hold off;

代码运行结果:

正如你所看到的,大多数较长的线段已经被检测到,但是很多杂散的线段也出现了。

那么,我们如何才能得到更好的结果呢?

让我们再看一下边缘像素:

我们注意到,在一些区域,在较长的线路上有中断:

还有一组密集的曲线可能会让霍夫探测器偏离轨道:

为了找到一组更清晰或更有意义的线条,我们可以做很多事情。

例如,我们可以增加霍夫最大值的阈值参数:

>> %% Alt.:More precise lines
>> peaks = houghpeaks(accum, 100, 'Threshold', cell(0.6*max(accum(:))), 'NHoodSize', [5,5]);
>> size(peaks);

为了理解这些参数的含义,让我们看一下这个函数的文档。

因此,阙值是累加器数组中的最小值,即支持一行的最小像素数,该行需要作为有效候选。

不考虑具有较少像素的任何可能的线。

这里我们将其设置为0.6乘以累加器数组中的最大值,默认值为0.5乘以最大值。

邻域大小定义了计算局部最大值的区域。('NHoodSize', [5,5])

注意,这不是图像中的区域。

我们在累加器阵列中计算局部最大值,因此在Rho和θ维中定义邻域的大小。

如果邻域大小为5度,则表示一条较强的线将会抑制其他相似但方向稍微偏离的线。

回想一下,我们在最后一次尝试中发现了13个最大值。

这次我们只有7个最大值。代码结果如下:

让我们看看这些峰值在哪里。

>> figure, imagesc(theta, rho, accum), title('Hough accumulator');
>> hold on; plot(theta(peaks(:,2)), rho(peaks(:, 1)), 'rs'); hold off;

代码运行结果:

看起来我们可能会有更干净的结果。

让我们将它与之前的累加器峰值进行比较:

我们看到以前在这一密集区域发现的许多最大值现在都消失了。

新的最大值聚集在三个主要的位置。

Okay,我们还能做什么?

>> line_segs = houghlines(edges, theta, rho, peaks, 'FillGap', 50, 'MinLength', 100);

我们可以利用houghlines的参数。

我们把填充间隙参数增加到50('FillGap', 50),看看怎么样?

这是两个段之间允许的最大像素数,如果它们位于同一条线上,则计为一个像素。

为了关注更长的线条,我们将最小长度增加到100像素。('MinLength', 100)

要更好地理解这些参数,请参阅houghlines的文档。

好,让我们看看新的片段是什么样的:

>>
figure, imshow(img), title('Line segments');
hold on;
for k = 1:length(line_segs)endpoints = [line_segs(k).point1; line_segs(k).point2];plot(endpoints(:, 1), endpoints(:, 2), 'LineWidth', 2, 'Color', 'green');
end
hold off;

代码运行,结果:

与之前的结果相比,我们发现杂散的已经基本被排除。(一些先前破碎的部分也被连接在一起。)

显然,你可以更好地处理参数,特别是在这里:

大家可以随意使用huff变换函数,调整到最好的结果。


——学会编写自己的代码,才能练出真功夫。

8.霍夫变换:线条——动手编码、霍夫演示_4相关推荐

  1. 8.霍夫变换:线条——基本的霍夫变换算法、霍夫变换的复杂性、霍夫例子_3

    目录 基本的霍夫变换算法 霍夫变换的复杂性 霍夫例子 基本的霍夫变换算法 说到算法,我们来看一下: 我们将使用直线的极坐标参数化,极坐标表示. 还有一种叫Hough累加器(数组)的东西,它只是用来表示 ...

  2. c语言 霍夫变换检测直线,C++ 霍夫直线检测

    霍夫变换原理参考:http://blog.csdn.net/jia20003/article/details/7724530 位图文件格式参考:http://www.cnblogs.com/kingm ...

  3. labview霍夫曼编码_香农编码与霍夫曼编码

    一.香农-范诺编码 香农-范诺(Shannon-Fano)编码的目的是产生具有最小冗余的码词(code word).其基本思想是产生编码长度可变的码词.码词长度可变指的是,被编码的一些消息的符号可以用 ...

  4. 哈夫曼编码压缩率计算_程序员的算法课(8)-贪心算法:理解霍夫曼编码

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/m0_37609579/article/ ...

  5. 霍夫码编码(一种不等长,非前缀编码方式)

    霍夫曼编码是一种不等长非前缀编码方式,于1951年由MIT的霍夫曼提出. 用于对一串数字/符号编码获取最短的结果,获取最大的压缩效率. 特点:不等长.非前缀 等长式编码 等长编码,意思是对出现的元素采 ...

  6. 贪心算法(Greedy Algorithm)之霍夫曼编码

    文章目录 1. 贪心算法 2. 应用 2.1 找零钱 2.2 区间覆盖 2.3 霍夫曼编码 霍夫曼编码完整代码 1. 贪心算法 我们希望在一定的限制条件下,获得一个最优解 每次都在当前的标准下做出当下 ...

  7. 程序员的算法课(8)-贪心算法:理解霍夫曼编码

    一.一种很贪婪的算法定义 贪心是人类自带的能力,贪心算法是在贪心决策上进行统筹规划的统称. [百度百科]贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体 ...

  8. Zlib压缩算法:LZ77、LZ78、霍夫曼编码、滑动窗口、Rabin-Karp算法、哈希链、I/O缓冲区

    Table of Contents 1.简介 1.1 什么是zlib 2.压缩算法 2.1 放气 2.2 LZ77 2.2.1 滑动窗口 2.2.2 长距离对 2.3 霍夫曼编码 3. zlib的实现 ...

  9. [多媒体]霍夫曼编码详解

    霍夫曼编码(Huffman Coding)_summer-CSDN博客_霍夫曼编码霍夫曼编码(Huffman Coding)是一种编码方法,霍夫曼编码是可变字长编码(VLC)的一种.霍夫曼编码使用变长 ...

最新文章

  1. C#:Guid.NewGuid()和DateTime.Now该选择哪个???
  2. 【Java 虚拟机原理】Dalvik 虚拟机 ( 打包 Jar 文件和 Dex 文件 | 反编译 Dex 文件 | 分析 Dex 文件反编译结果 )
  3. 【Matlab 控制】多智能体一致性收敛仿真
  4. py-faster-rcnn源码解读系列
  5. ASP中利用OWC控件实现图表功能详解[zz]
  6. Linux系统重新对时,Linux系统时区不对怎么办?
  7. 技术玩法大升级,网易MCtalk揭秘社交产品背后的秘密
  8. 我如何将Google I / O 2018的兴奋带给尼日利亚沃里的115个人
  9. php更多式样,php_1
  10. 算法:特殊二维数组查询key值是否存在
  11. 复制百度文库文字最简单的方法
  12. srvany把程序作为Windows服务运行
  13. 将背景为白色图片转为png格式的透明图片
  14. centos、Windows双系统安装及修复引导启动项
  15. 计算机导航窗格里没有桌面,今天解决win10 导航窗格怎么添加桌面的解决环节
  16. 极智装修知识|如何将效果图转化为实景的家? - 分享3
  17. 为App界面添加蒙层效果
  18. easyUI折叠表格-默认展开操作-去除扩展符号(+)-清除滚轮--实例加效果图
  19. JavaSE-part2
  20. 在S3C6410开发板上的LED驱动程序

热门文章

  1. #华为云·寻找黑马程序员#【代码重构之路】使用Pattern的正确姿势
  2. mysql 数据目录更换_更改Mysql数据目录,这个坑你可能也趟过~
  3. 火狐浏览器表单不跳转_坑爹火狐浏览器会记录表单数据,导致服务器控件点击事件出bug...
  4. 设计模式笔记二十二:空对象模式
  5. java.util.PropertyPermission“ “org.graalvm.nativeimage.imagecode“ “read“
  6. GoogLenet网络解读及代码实现(Pytorch)
  7. 计算机专业汇报与接口,计算机接口设计实验总结.doc
  8. 创建选修专业表oracle,数据库及数据表的创建与删除 (Oracle实验)
  9. 启动zookeeper时IDEA启动项目时提示8080端口被占用
  10. 塑源码是什么_注塑机源代码