帮助了解霍夫变换


19

我正在尝试让霍夫(Hough)变换在MATLAB中工作,但出现了问题。我有一个非常糟糕的方法来检测需要修复的峰,但是在此之前,我需要能够反转霍夫变换以再次正确地创建线条。这是我现在得到的东西类型:

在此处输入图片说明

看起来好像旋转了90度,但我不确定为什么。我不确定是因为我在霍夫(Hough)空间错了,还是因为我取消了霍夫(Hough)并划清界限的方式。还可以有人帮助改善我的峰值检测吗?代码中使用的图像在这里

%% load a sample image; convert to grayscale; convert to binary

%create 'x' image (works well)
a = eye(255);
b = flipud(eye(255));
x = a + b;
x(128,128) = 1;

%image = rgb2gray(imread('up.png')) < 255;
%image = rgb2gray(imread('hexagon.png')) < 255;
%image = rgb2gray(imread('traingle.png')) < 255;
%%% these work
%image = x;
%image = a;
image = b;    

%% set up variables for hough transform
theta_sample_frequency = 0.01;                                             
[x, y] = size(image);
rho_limit = norm([x y]);                                                
rho = (-rho_limit:1:rho_limit);
theta = (0:theta_sample_frequency:pi);
num_thetas = numel(theta);
num_rhos = numel(rho);
hough_space = zeros(num_rhos, num_thetas);

%% perform hough transform
for xi = 1:x
    for yj = 1:y
        if image(xi, yj) == 1 
            for theta_index = 1:num_thetas
                th = theta(theta_index);
                r  = xi * cos(th) + yj * sin(th);
                rho_index = round(r + num_rhos/2);                      
                hough_space(rho_index, theta_index) = ...
                     hough_space(rho_index, theta_index) + 1;
            end
        end
    end
end  

%% show hough transform
subplot(1,2,1);
imagesc(theta, rho, hough_space);
title('Hough Transform');
xlabel('Theta (radians)');
ylabel('Rho (pixels)');
colormap('gray');

%% detect peaks in hough transform
r = [];
c = [];
[max_in_col, row_number] = max(hough_space);
[rows, cols] = size(image);
difference = 25;
thresh = max(max(hough_space)) - difference;
for i = 1:size(max_in_col, 2)
   if max_in_col(i) > thresh
       c(end + 1) = i;
       r(end + 1) = row_number(i);
   end
end

%% plot all the detected peaks on hough transform image
hold on;
plot(theta(c), rho(r),'rx');
hold off;


%% plot the detected line superimposed on the original image
subplot(1,2,2)
imagesc(image);
colormap(gray);
hold on;

for i = 1:size(c,2)
    th = theta(c(i));
    rh = rho(r(i));
    m = -(cos(th)/sin(th));
    b = rh/sin(th);
    x = 1:cols;
    plot(x, m*x+b);
    hold on;
end

链接: 如何对霍夫变换图像进行去霍夫处理?


您设法解决问题了吗?我正面临类似的问题。感谢
Erez Posner 2015年

转换hough sous matlab倒détecterplusieurs椭圆

Answers:


11

首先,Matlab具有内置的Hough变换:无需重新发明轮子。

[H,T,R] = hough(BW,'RhoResolution',0.5,'Theta',-90:0.5:89.5);

尽管您的图像不一定需要边缘检测,但是您可以改善使用该算法的处理时间和算法的有效性。您的三角形有白色和黑色的胖区域。理想情况下,三角形的厚度应为1px,标记三角形的边缘。使用Canny Edge Detection

BW = edge(Image,'canny');

结果是\ theta在度范围内,而绘图为(或),则减去度()。-90<θ<900<θ<1800<θ<π90π/2

您有可能选择错误的峰,因为在累加器矩阵中可能存在较大的相邻峰。尽管这里有很多算法,但我过去曾在Hough变换中看到过这种算法:

1) Define a region shape (typically its square) 
2) Define an accumulator threshold  
3) Select one pixel in the accumulator matrix
4) If it is a peak (i.e., larger than neighboring values above a threshold)
       a) look at the points within the region shape.
       b) If there is a larger value
              this is not a peak
          Else
              this is a peak
 5) Move to next pixel in accumulator matrix.

查看用于显示霍夫变换线的HoughLines,结果:

http://www.mathworks.com/help/toolbox/images/ref/houghlines.html

使用Canny Edge检测器的效果

边缘检测可能会将三角形的每一边变成两条线。

Canny边缘检测的目标是通过使用非最大抑制来产生最大的窄/窄边缘

壳中的Canny边缘检测(来源:Digital Image Processing,Gonazalez)

1) Smooth input Image using a Gaussian Filter
2) Compute the Gradient magnitude and angle (Sobel, Perwitt or robert cross filters)
3) Apply Nonmaxima suppression (this is where the thinning happens) 
   a) Figure out which direction the edge is
   b) If the edge's magnitude is smaller than one of its two neighbors in the direction of the edge
          set the edge point to zero
      Else
          leave it alone
4) Use double thresholding and connectivity analysis to detect and link edges

谢谢回复。我正在从头开始以更好地理解它。canny边缘检测仍然给出2个三角形。一个用于内边缘,一个用于外边缘。我从维基百科学到了理论,该理论指出theta为0:pi。我知道内置函数使用-pi / 2:pi / 2,但是应该没有真正的区别吗?
waspinator 2012年

马上,范围就不会有所作为。(您能分辨出已旋转180度的直线之间的差异吗?)但是,如果您将霍夫变换用于图像校正算法,则确实会有所不同。(这意味着右侧图像和上下图像之间的差异)
Cyber​​Men 2012年

边缘检测不会在只想找到1条的地方产生2条线吗?找到粗线中心的方法会更好。
endolith'4

@endolith在原始帖子中包含了一些有关边缘检测的讨论
Cyber​​Men 2012年

“不需要重新发明轮子”吗?告诉我的教练;-)
内森·史威文2012年

3
    if image(xi, yj) == 1 

需要更改为

    if image(yj, xi) == 1 

让线路在dehough中工作


1

使用3个循环的答案不及最优,可以改善,这里更多是一种直观的方法/观点:

每对有效点都设置一个唯一的y = ax + b。一条线将有许多对,且具有相同的a和b值,因此长线将作为一个峰出现。对于极坐标r&teta坐标也是如此。

不要将每个点分开对待,而应使用成对的点。如果可以将所有(通常是稀疏的)点存储在单独的列表中,则更好,但这不是必须的。

  1. 取每对并计算其a和b。(四舍五入为离散值)
  2. 转到数组中的特定位置并添加1。

长线->很多成对的a,b。
零星的点->在特定单元格中少量计数->更像混乱。


另一种看待它的方法是从Radon /投影角度。

  • 一条线会强烈地投射到垂直的“收集线”,因此得分很高。
  • 如果线与“收集线”之间的角度不是90度,或者收集线未收集投影到该“收集线”中的所有线点,则得分会更低。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.