matlab-霍夫变换详解(判断正方形长方形)
霍夫变换
霍夫变换是1972年提出来的,最开始就是用来在图像中过检测直线,后来扩展能检测圆、曲线等。
直线的霍夫变换就是 把xy空间的直线 换成成 另一空间的点。就是直线和点的互换。
我们在初中数学中了解到,一条直线可以用如下的方程来表示:y=kx+b,k是直线的斜率,b是截距。
我们转换下变成:b=-kx+y。我们是不是也可以把(k,b)看作另外一个空间中的点?这就是k-b参数空间。 这样,我们就把一条x-y直线用一个(k,b)的点表示出来了。
我们看到,在x-y图像空间中的一个点,变成了k-b参数空间中的一条直线,而x-y图像空间中的2点连成的直线,变成了k-b参数空间中的一个交点。
如果x-y图像空间中有很多点在k-b空间中相交于一点,那么这个交点就是我们要检测的直线。这就是霍夫变换检测直线的基本原理。
当然,有一个问题需要注意,图像空间中如果一条直线是垂直的,那么斜率k是没有定义的(或者说无穷大)。为了避免这个问题,霍夫变换采用了另一个参数空间:距离-角度参数空间。也就是极坐标。
我们在中学中学过,平面上的一个点也可以用距离-角度来定义,也就是极坐标。那么在图像中,每一个点都可以用距离和角度来表达:
但是,使用距离-角度后,点(x,y)与距离,角度的关系变成了:
ρ=xcosθ+ysinθ
于是,在新的距离-角度参数空间中,图像中的一个点变成了一个正弦曲线,而不是k-b参数空间中的直线了。这些正弦曲线的交点就是图像空间中我们要检测的直线了。
Matlab霍夫变换的函数详解
[H, theta, rho] = hough(BW,ParameterName, ParameterValue)
BW:二值图
ParameterName:'RhoResolution'或'Theta'
RhoResolution-指定在累计数组中(检测极值)的检测间隔?默认为1
Theta-指定检测的角度范围(不超过-90~90度)以及间隔,例如-90:0.5:89.5,默认-90:1:89
H:累计数组
Theta:H对应的θ,实际上H的大小就是Rho×Theta
Rho:H对应的ρ
这两个参数值的注意,RhoResolution太大覆盖不到极值点,检测到一些不对应直线的次极值,
峰值提取
peaks = houghpeaks(H,numpeaks)
peaks = houghpeaks(...,param1, val1, param2, val2)
H:累计数组;
Numpeaks:指定需要检测的峰值个数;
Param1:可以是'Threshold'或'NHoodSize'
'Threshold'-指定峰值的域值,默认是0.5*max(H(:))
'NHoodSize'-是个二维向量[m,n],检测到一个峰值后,将峰值周围[m,n]内元素置零。
画直线段
lines = houghlines(BW,theta, rho, peaks)
lines = houghlines(...,param1, val1, param2, val2)
BW:二值图
Theta、rho、peaks:分别来自函数hough和houghpeaks
Lines:结构数组,大小等于检测到的直线段数,每个单元包含
Point1、point2:线段的端点
Theta、rho:线段的theta和rho
下面实例演示
用霍夫变换判断矩形
所用图形是我用画图工具制作的,图片很干净,所以不需要滤波等措施。以下是图案。
img = imread('a.png');
img_gray = rgb2gray(img); %背景是黑的!!!
threshold =graythresh(img_gray);%取阈值
bw=im2bw(img_gray,threshold);
if length(bw(bw==1))>length(bw(bw==0))
bw=~bw;
end
%填充
bw = imfill(bw,'holes'); figure(), imshow(img_gray), title('image'); [B,L] = bwboundaries(bw,'noholes');
stats = regionprops(L,'Area','Centroid','image');
boundary = B{1};
delta_sq = diff(boundary).^2;
perimeter = sum(sqrt(sum(delta_sq,2)));
% obtain the area calculation corresponding
area = stats(1).Area;
% compute the roundness metric
metric = 4*pi*area/perimeter^2;
if metric>0.9
disp('yuan')
else % the canny edge of image
BW = edge(bw,'canny');
% Iedge=edge(Ihsv,'sobel'); %边沿检测
%BW = imdilate(BW,ones(3));%图像膨胀
figure(), imshow(BW), title('image edge');
% the theta and rho of transformed space
[H,Theta,Rho] = hough(BW,'RhoResolution',1.2);
figure(), imshow(H,[],'XData',Theta,'YData',Rho,'InitialMagnification','fit'),...
title('rho\_theta space and peaks');
xlabel('\theta'), ylabel('\rho');
axis on, axis normal, hold on;
% label the top 5 intersections
P = houghpeaks(H,4,'threshold',ceil(0.1*max(H(:))),'NHoodSize',[35,11]);
x = Theta(P(:,2));
y = Rho(P(:,1));
plot(x,y,'*','color','r'); % find lines and plot them
lines = houghlines(BW,Theta,Rho,P);
figure(), imshow(img),title('final image');
hold on
b_len = ones(1,length(lines));
for k = 1:length(lines)
xy = [lines(k).point1; lines(k).point2];
b_len(1,k)=sqrt((xy(1,1)-xy(2,1))^2+(xy(1,2)-xy(2,2))^2);
plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','r');
hold on
end
if var(b_len)<10
disp('正方形')
else
disp('长方形')
end
end
然后得到结果
变换参数域图像(很完美,4个点)
结果图像
基本包含在原图形上,测试成功!
参考文献:
[1] http://blog.sina.com.cn/s/blog_ac7218750101giyf.html
[2] https://blog.csdn.net/saltriver/article/details/80547245
[3] https://ww2.mathworks.cn/help/images/ref/hough.html
盘外篇
自己写个Hough变换? hough的原理很简单,可以自己尝试以下。
那么我们检测一下 直线的斜率。
下面上代码
clear all; img = imread('demo1.png');
img_gray = rgb2gray(img); %二值化
threshold =graythresh(img_gray);%取阈值
bw=im2bw(img_gray,threshold);
if length(bw(bw==1))>length(bw(bw==0))
bw=~bw;
end figure(), imshow(bw), title('image');
% %填充
% bw = imfill(bw,'holes');
% %边沿检测
%the canny edge of image
%bw = edge(bw,'canny'); bw = imdilate(bw,ones(8)); %图像膨胀(因为直线太细会使误差增大)
%figure(), imshow(bw), title('image ');
%the theta and rho of transformed space
[H,Theta,Rho] = hough1(bw);
figure(), imshow(H,[],'XData',Theta,'YData',Rho,'InitialMagnification','fit'),...
title('rho\_theta space and peaks');
xlabel('\theta'), ylabel('\rho');
axis on, axis normal, hold on;
%label the top 1 intersections
%P = houghpeaks(H,1);
[xx,yy]=find(H==max(max(H)),1);
P=[xx,yy];
x = Theta(P(:,2));
y = Rho(P(:,1));
plot(x,y,'*','color','r'); [m,n]=size(bw);
label=zeros(m,n);
xy=[];
for ii=1:length(bw)
jj=ceil((y-ii*cos(x/180*pi))/sin(x/180*pi));
if jj>=1&& jj<=n
label(ii,jj)=1;
if bw(ii,jj)==1
xy=[xy;jj,ii]; %因为plot和imshow的xy轴是镜像关系!
end
end
end %find lines and plot them
%lines = houghlines(bw,Theta,Rho,P);
figure(), imshow(img),title('final image');
hold on
plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','r'); k=-sin(x/180*pi)/cos(x/180*pi);
b=y/cos(x/180*pi);
disp(['斜率是',num2str(k)])
disp(['y轴截距是',num2str(b)]) %ezplot('x*cos(-72/180*pi)+y*sin(-72/180*pi)=-31',[0,256])
下面就是自己写的hough变换函数了
function [h, theta, rho] = hough1(f, dtheta, drho) if nargin < 3
drho = 1;
end
if nargin < 2
dtheta = 1;
end f = double(f);
[M,N] = size(f);
theta = linspace(-90, 0, ceil(90/dtheta) + 1);
theta = [theta -fliplr(theta(2:end - 1))];
ntheta = length(theta); D = sqrt((M - 1)^2 + (N - 1)^2);
q = ceil(D/drho);
nrho = 2*q - 1;
rho = linspace(-q*drho, q*drho, nrho); [x, y, val] = find(f);
x = x - 1; y = y - 1; h = zeros(nrho, length(theta)); for k = 1:ceil(length(val)/1000)
first = (k - 1)*1000 + 1;
last = min(first+999, length(x)); x_matrix = repmat(x(first:last), 1, ntheta);
y_matrix = repmat(y(first:last), 1, ntheta);
val_matrix = repmat(val(first:last), 1, ntheta);
theta_matrix = repmat(theta, size(x_matrix, 1), 1)*pi/180; rho_matrix = x_matrix.*cos(theta_matrix) + ...
y_matrix.*sin(theta_matrix);
slope = (nrho - 1)/(rho(end) - rho(1));
rho_bin_index = round(slope*(rho_matrix - rho(1)) + 1); theta_bin_index = repmat(1:ntheta, size(x_matrix, 1), 1); h = h + full(sparse(rho_bin_index(:), theta_bin_index(:), ...
val_matrix(:), nrho, ntheta));
end
结果还不错
matlab-霍夫变换详解(判断正方形长方形)的更多相关文章
- 【转】小波与小波包、小波包分解与信号重构、小波包能量特征提取 暨 小波包分解后实现按频率大小分布重新排列(Matlab 程序详解)
转:https://blog.csdn.net/cqfdcw/article/details/84995904 小波与小波包.小波包分解与信号重构.小波包能量特征提取 (Matlab 程序详解) ...
- Matlab绘图详解
Matlab绘图 强大的绘图功能是Matlab的特点之一,Matlab提供了一系列的绘图函数,用户不需要过多的考虑绘图的细节,只需要给出一些基本参数就能得到所需图形,这类函数称为高层绘图函数.此外,M ...
- SVM matlab 代码详解说明
x=[0 1 0 1 2 -1];y=[0 0 1 1 2 -1];z=[-1 1 1 -1 1 1]; %其中,(x,y)代表二维的数据点,z 表示相应点的类型属性. data=[1,0;0,1;2 ...
- 混淆矩阵-MATLAB代码详解
一.混淆矩阵 (一).简介 在人工智能中,混淆矩阵(confusion matrix)是可视化工具,特别用于监督学习,在无监督学习一般叫做匹配矩阵.在图像精度评价中,主要用于比较分类结果和实际测得值, ...
- VC 与Matlab混合编程之引擎操作详解
Visual C++ 是当前主流的应用程序开发环境之一,开发环境强大,开发的程序执行速度快.但在科学计算方面函数库显得不够丰富.读取.显示数据图形不方便. Matlab 是一款将数值分析.矩阵计算.信 ...
- Swift流程控制之循环语句和判断语句详解
Swift提供了所有c类语言的控制流结构.包括for和while循环来执行一个任务多次:if和switch语句来执行确定的条件下不同的分支的代码:break和continue关键字能将运行流程转到你代 ...
- 算法进阶面试题01——KMP算法详解、输出含两次原子串的最短串、判断T1是否包含T2子树、Manacher算法详解、使字符串成为最短回文串
1.KMP算法详解与应用 子序列:可以连续可以不连续. 子数组/串:要连续 暴力方法:逐个位置比对. KMP:让前面的,指导后面. 概念建设: d的最长前缀与最长后缀的匹配长度为3.(前缀不能到最后一 ...
- PCA (主成分分析)详解 (写给初学者) 结合matlab(转载)
一.简介 PCA(Principal Components Analysis)即主成分分析,是图像处理中经常用到的降维方法,大家知道,我们在处理有关数字图像处理方面的问题时,比如经常用的图像的查询问题 ...
- Jquery 选择器 详解 js 判断字符串是否包含另外一个字符串
Jquery 选择器 详解 在线文档地址:http://tool.oschina.net/apidocs/apidoc?api=jquery 各种在线工具地址:http://www.ostools ...
随机推荐
- JavaScript基础之对象属性的检测和枚举
属性检测 对象作为属性的集合,属性又包括自有属性和继承属性: 检测方法: \__ in运算符: \__ var obj = { x:1 } console.log( 'toString' in o ...
- ubuntu18安装navicat
1.登陆 http://www.navicat.com.cn/download/navicat-for-mysql 页面下载navicat安装包,务必选位置1-64bit ps: 中文版乱码问题严重, ...
- 解题报告 『机器翻译(vector)』
原题地址 本想练习一下模拟,不过用vector貌似可以轻松水过?(虽然还是模拟) 但突然发现貌似我并不会判断单词是否在内存中出现过? 最后还是靠度娘解决了. 代码如下: #include <bi ...
- django之Form组件补充
自定义验证规则 方法一: from django.forms import Form from django.forms import widgets from django.forms import ...
- RABBITMQ too many heartbeats missed
执行rabbitmqctl status | grep -A 4 file_descriptors 显示socket_used 达到 socket_limited 的值 增加socket_limi ...
- C++ Object实体类
*暂未完成,因为无尽BUG滚滚来. 好长时间没写完,一是能力不够,二是我还得给老板写WEB的代码.可是我不会WEB!js和PHP简直就是世界上最好的语言,因为它们能够让人更快地进入极乐世界. 让我写一 ...
- layui select配合input实现动态模糊搜索
功能需求:select框可以自己输入,就是在下拉列表里找不到自己想要的选项就可以自己输入,同时还要支持模糊匹配功能 html代码: 样式: <style> .select-search-i ...
- Linux printf命令详解
Linux printf命令 printf命令模仿了C语言中的printf()函数.主要作用是输出文本,按照我们指定的格式输出文本.还有一个输出文本的命令echo,在输出文本时,echo会换行.pri ...
- 关于mysql自增主键
对于mysql表(其他数据库没测试过) 如果定义了自增主键,并且手动设置了主键的值,那么当再次自增创建数据的时候,回在设置的主键值的基础上进行自增. 如(id是主键): 起始插入(3,1),而后手动插 ...
- django部署笔记
在开发机上的准备工作: 确认项目没有bug. 用pip freeze > requirements.txt将当前环境的包导出到requirements.txt文件中,方便在部署的时候安装. 将项 ...