标签(空格分隔): 数字图像处理 图像特征提取
本文同版本也发布在了cmd markdown小站(https://www.zybuluo.com/lutingting/note/554459),布局更漂亮些!
注意,本文在总结过程中,参考了许多其他绘图,每种情况下使用的符号不太一致,所以,每个小节使用的符号都仅以各小节图像为主,不要混淆!
极坐标系(polar coordinates)是指在平面内由极点O、极轴L和极径r组成的坐标系,下图就展示了一个极坐标系,图中两个红点是要利用极坐标表示的两个点,黑色点是极坐标系的极点
那么,极坐标系和直角坐标系之间什么关系呢?
在极坐标系下,应该如何表示直线方程呢?如上图所示,有一直线L,点P是直线L上任意一点,其对应的直角坐标为(x,y),该点的极坐标为 (φ,r) ,该直线距 离原点距离为ρ:
即直线的极坐标方程! 也就是说,每一组参数 ρ (坐标原点到直线的距离)和 θ (垂线 ρ 与x轴正方向的夹角 )将唯一确定了一条直线!并且,在极坐标系下,直线的方程就是一个点
下面的例子形象地展示了如何利用Hough变换进行直线检测的过程,这里应该注意,图像中的一条直线其实就仅仅对应于极坐标系下(参数空间)的一个点:
按照参数的取值范围,将参数分为 m×n 个网格,即将 θ∈[0,π] 分为m份,将 ρ∈[−2√N,2√N] 分为n份,然后,设定一个 m×n 的累加单元,用来存储图像中某一条直线出现的次数
接下来,对图像中原图像中每一个像素点(x,y),分别进行如下操作:
按照上面操作,得到了一个累加单元,统计每个累加单元的取值,大于某个事先设定好的阈值,就认为该组参数便是图像空间内的直线的参数
matlab自带了Hough变换的相关函数:
houghpeaks:在霍夫变换矩阵里找极值点
houghlines:从霍夫变换矩阵中提取线段
1. 读取图像并得到边缘图像
% 读取matlab自带的图像gantrycrane,并提取边缘
RGB = imread('gantrycrane.png');
I = rgb2gray(RGB);
BW = edge(I,'canny'); %提取边缘
subplot(1,2,1);imshow(RGB);title('原始图像');
subplot(1,2,2);imshow(BW);title('边缘图像');
2. 利用Hough函数对输入图像边缘进行hough变换
% 对原始图像边缘进行hough变换,指定参数的分别率(取样间隔),区间利用默认值
[H,T,R] = hough(BW,'RhoResolution',0.5,'ThetaResolution',0.5);
3.显示hough变换的结果,即显示矩阵H(即bins)
% 显示hough变换的结果
figure;
imshow(imadjust(mat2gray(H)),'XData',T,'YData',R,...
'InitialMagnification','fit');
title('Limited Theta Range Hough Transform of Gantrycrane Image');
xlabel('\theta'), ylabel('\rho');
axis on, axis normal;
colormap(hot)
这里应该注意,在进行hough变换时,并没有对参数区间进行限制,那么,如果按照下面方式对theta区间进行限制,会得到什么结果呢?
[H,T,R] = hough(BW, 'Theta', 44:0.5:46);
这里可以看到,由于hough变换时,限制了 θ 的范围,所以,得到的H矩阵只对应了[44:0.5:46]这个范围内的参数,具体地, θ 的取值为[44,44.5,45,45.5,46];
4.显示hough变换结果中的极值点
将hough变换矩阵中的前10个峰值提取出
% 显示霍夫变换矩阵中的极值点
P = houghpeaks(H,10,'threshold',ceil(0.3*max(H(:)))); % 从霍夫变换矩阵H中提取50个极值点
x = T(P(:,2));%极值点的theta值,即P的第二列存放的是极值点的theta值
y = R(P(:,1));%极值点的rho值,即P的第二列存放的是极值点的rho值
hold on;plot(x,y,'s','color','black');
其中的P的第一列存放的是提取到的极值点的rho的index,第二列存放的是提取到的极值点的theta的index
5.将提取得到的极值点变换回原图像,得到提取的直线
% 找原图中的直线
lines = houghlines(BW,T,R,P,'FillGap',18,'MinLength',80);
注意到,这里面涉及几个参数:
6.在原图像中绘制得到的直线
% 绘制提取得到的直线
figure, imshow(I), hold on
max_len = 0;
for k = 1:length(lines)
% 绘制第k条直线
xy = [lines(k).point1; lines(k).point2];
plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','green');
% 绘制第k条直线的起点(黄色)、终点(红色)
plot(xy(1,1),xy(1,2),'x','LineWidth',2,'Color','yellow');
plot(xy(2,1),xy(2,2),'x','LineWidth',2,'Color','red');
% 计算第k条直线的长度,保留最长直线的端点
len = norm(lines(k).point1 - lines(k).point2);
if ( len > max_len)
max_len = len;
xy_long = xy;
end
end
title('提取到的直线');
% 以红色线高亮显示最长的线
plot(xy_long(:,1),xy_long(:,2),'LineWidth',2,'Color','red');
优点:
缺点:
Hough变换利用的是一种投票思想
Reference