帮助理解霍夫变换

信息处理 matlab 霍夫变换
2022-01-08 01:17:53

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

在此处输入图像描述

看起来它旋转了 90 度,但我不知道为什么。我不确定是我的霍夫空间错了,还是我去霍夫和画线的方式。还有人可以帮助改善我的峰值检测吗?代码中使用的图片在这里

%% 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

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

3个回答

首先,Matlab 有一个内置的霍夫变换:无需重新发明轮子。

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

尽管您的图像不一定需要边缘检测,但您可以改进使用它的算法的处理时间和有效性。你的三角形有白色和黑色的脂肪区域。理想情况下,三角形将是 1px 厚,标记三角形的边缘。使用 Canny 边缘检测

BW = edge(Image,'canny');

结果是 \theta 在范围内90<θ<90度数,而你的情节是0<θ<180(要么0<θ<π) 所以减去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 边缘检测器的效果

边缘检测可以潜在地将三角形的每一边变成两条线。

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

简而言之 Canny 边缘检测(来源:数字图像处理,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
    if image(xi, yj) == 1 

需要改为

    if image(yj, xi) == 1 

让线条在 dehough 中发挥作用

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

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

不要单独处理每个点,而是使用成对的点。如果您可以将所有(通常是稀疏的)点存储在一个单独的列表中,那就更好了,但这不是必须的。

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

长线->很多对具有相同的a,b。
零星点->特定单元格中的小计数->更像是杂乱无章。


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

  • 一条线将强烈地投射到垂直的“收集线”,因此得分很高。
  • 如果线与“采集线”的夹角不是90度,或者采集线没有采集到投影到这条“采集线”的所有线点,则得分较低。