8.霍夫变换:线条——动手编码、霍夫演示_4
目录
动手编码
霍夫演示
动手编码
我们将在这里花一分钟来演示一下,如何使用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相关推荐
- 8.霍夫变换:线条——基本的霍夫变换算法、霍夫变换的复杂性、霍夫例子_3
目录 基本的霍夫变换算法 霍夫变换的复杂性 霍夫例子 基本的霍夫变换算法 说到算法,我们来看一下: 我们将使用直线的极坐标参数化,极坐标表示. 还有一种叫Hough累加器(数组)的东西,它只是用来表示 ...
- c语言 霍夫变换检测直线,C++ 霍夫直线检测
霍夫变换原理参考:http://blog.csdn.net/jia20003/article/details/7724530 位图文件格式参考:http://www.cnblogs.com/kingm ...
- labview霍夫曼编码_香农编码与霍夫曼编码
一.香农-范诺编码 香农-范诺(Shannon-Fano)编码的目的是产生具有最小冗余的码词(code word).其基本思想是产生编码长度可变的码词.码词长度可变指的是,被编码的一些消息的符号可以用 ...
- 哈夫曼编码压缩率计算_程序员的算法课(8)-贪心算法:理解霍夫曼编码
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/m0_37609579/article/ ...
- 霍夫码编码(一种不等长,非前缀编码方式)
霍夫曼编码是一种不等长非前缀编码方式,于1951年由MIT的霍夫曼提出. 用于对一串数字/符号编码获取最短的结果,获取最大的压缩效率. 特点:不等长.非前缀 等长式编码 等长编码,意思是对出现的元素采 ...
- 贪心算法(Greedy Algorithm)之霍夫曼编码
文章目录 1. 贪心算法 2. 应用 2.1 找零钱 2.2 区间覆盖 2.3 霍夫曼编码 霍夫曼编码完整代码 1. 贪心算法 我们希望在一定的限制条件下,获得一个最优解 每次都在当前的标准下做出当下 ...
- 程序员的算法课(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的实现 ...
- [多媒体]霍夫曼编码详解
霍夫曼编码(Huffman Coding)_summer-CSDN博客_霍夫曼编码霍夫曼编码(Huffman Coding)是一种编码方法,霍夫曼编码是可变字长编码(VLC)的一种.霍夫曼编码使用变长 ...
最新文章
- C#:Guid.NewGuid()和DateTime.Now该选择哪个???
- 【Java 虚拟机原理】Dalvik 虚拟机 ( 打包 Jar 文件和 Dex 文件 | 反编译 Dex 文件 | 分析 Dex 文件反编译结果 )
- 【Matlab 控制】多智能体一致性收敛仿真
- py-faster-rcnn源码解读系列
- ASP中利用OWC控件实现图表功能详解[zz]
- Linux系统重新对时,Linux系统时区不对怎么办?
- 技术玩法大升级,网易MCtalk揭秘社交产品背后的秘密
- 我如何将Google I / O 2018的兴奋带给尼日利亚沃里的115个人
- php更多式样,php_1
- 算法:特殊二维数组查询key值是否存在
- 复制百度文库文字最简单的方法
- srvany把程序作为Windows服务运行
- 将背景为白色图片转为png格式的透明图片
- centos、Windows双系统安装及修复引导启动项
- 计算机导航窗格里没有桌面,今天解决win10 导航窗格怎么添加桌面的解决环节
- 极智装修知识|如何将效果图转化为实景的家? - 分享3
- 为App界面添加蒙层效果
- easyUI折叠表格-默认展开操作-去除扩展符号(+)-清除滚轮--实例加效果图
- JavaSE-part2
- 在S3C6410开发板上的LED驱动程序
热门文章
- #华为云·寻找黑马程序员#【代码重构之路】使用Pattern的正确姿势
- mysql 数据目录更换_更改Mysql数据目录,这个坑你可能也趟过~
- 火狐浏览器表单不跳转_坑爹火狐浏览器会记录表单数据,导致服务器控件点击事件出bug...
- 设计模式笔记二十二:空对象模式
- java.util.PropertyPermission“ “org.graalvm.nativeimage.imagecode“ “read“
- GoogLenet网络解读及代码实现(Pytorch)
- 计算机专业汇报与接口,计算机接口设计实验总结.doc
- 创建选修专业表oracle,数据库及数据表的创建与删除 (Oracle实验)
- 启动zookeeper时IDEA启动项目时提示8080端口被占用
- 塑源码是什么_注塑机源代码