在不使用hough函数的情况下在MATLAB中进行Hough变换

时间:2012-03-28 21:57:12

标签: matlab hough-transform

我在Rosetta Code的MATLAB中找到了Hough变换的实现,但是我无法理解它。另外我想修改它以显示原始图像和重建线(de-Houghing)。

理解它和de-Houghing的任何帮助表示赞赏。感谢

  1. 为什么图像会翻转?

    theImage = flipud(theImage);

  2. 我无法绕过规范函数。它的目的是什么,可以避免吗?

  3. 编辑: norm只是欧几里德距离的同义词:sqrt(width ^ 2 + height ^ 2)

    rhoLimit = norm([width height]);

    1. 有人可以解释rho,theta和houghSpace的计算方法/原因吗?

      rho = (-rhoLimit:1:rhoLimit);          
      theta = (0:thetaSampleFrequency:pi);
      
      numThetas = numel(theta);
      houghSpace = zeros(numel(rho),numThetas);
      
    2. 我如何去除霍夫空间以重建线条?

    3. 使用身份(眼睛)功能

      创建的对角线的10x10图像调用该功能
      theImage = eye(10)
      thetaSampleFrequency = 0.1
      [rho,theta,houghSpace] = houghTransform(theImage,thetaSampleFrequency)
      

      实际功能

      function [rho,theta,houghSpace] = houghTransform(theImage,thetaSampleFrequency)
      
          %Define the hough space
          theImage = flipud(theImage);
          [width,height] = size(theImage);
      
          rhoLimit = norm([width height]);
          rho = (-rhoLimit:1:rhoLimit);          
          theta = (0:thetaSampleFrequency:pi);
      
          numThetas = numel(theta);
          houghSpace = zeros(numel(rho),numThetas);
      
          %Find the "edge" pixels
          [xIndicies,yIndicies] = find(theImage);
      
          %Preallocate space for the accumulator array
          numEdgePixels = numel(xIndicies);
          accumulator = zeros(numEdgePixels,numThetas);
      
          %Preallocate cosine and sine calculations to increase speed. In
          %addition to precallculating sine and cosine we are also multiplying
          %them by the proper pixel weights such that the rows will be indexed by 
          %the pixel number and the columns will be indexed by the thetas.
          %Example: cosine(3,:) is 2*cosine(0 to pi)
          %         cosine(:,1) is (0 to width of image)*cosine(0)
          cosine = (0:width-1)'*cos(theta); %Matrix Outerproduct  
          sine = (0:height-1)'*sin(theta); %Matrix Outerproduct
      
          accumulator((1:numEdgePixels),:) = cosine(xIndicies,:) + sine(yIndicies,:);
      
          %Scan over the thetas and bin the rhos 
          for i = (1:numThetas)
              houghSpace(:,i) = hist(accumulator(:,i),rho);
          end
      
          pcolor(theta,rho,houghSpace);
          shading flat;
          title('Hough Transform');
          xlabel('Theta (radians)');
          ylabel('Rho (pixels)');
          colormap('gray');
      
      end
      

1 个答案:

答案 0 :(得分:5)

霍夫变换是一种“投票”方法,其中每个图像点对图像中某一行(一行)的存在进行投票。投票在一行的参数空间中进行:法向量的极坐标表示。

我们对参数空间进行离散化,并允许每个图像点建议与通过该点的直线兼容的参数。您可以根据代码中如何处理参数空间来解决您的每个问题。 Wikipedia有一篇很好的文章,其中包含可能澄清事物的工作示例(如果您遇到任何概念上的麻烦)。

针对您的具体问题:

  1. 图像被翻转,原点是右下角。据我所知,这一步在技术上是不必要的。由于离散化问题,它确实会在某种程度上改变结果。 Rosetta Code上的其他实现不会翻转图像。
  2. rhoLimit保持极坐标中图像点的最大半径(回想一下矢量的范数是它的大小)。
  3. rhotheta根据采样率是极坐标平面的离散化。 houghSpace创建一个矩阵,其中包含每个可能的离散rho / theta值组合的元素。
  4. Hough变换没有指定假定行的长度;投票空间中的峰值仅指定线的法线向量的极坐标。您可以通过选择峰值并绘制相应的线来“去霍夫”,或者可以通过绘制每条可能的线并使用投票数作为灰度权重。无法从Hough变换重新创建原始图像,只能通过变换识别的线条(以及您对投票的阈值方案)。
  5. 按照问题中的示例生成以下图表。网格线和数据提示光标的放置可能有点误导(尽管'提示中的变量值是正确的)。由于这是参数空间的图像而不是图像空间,因此我们选择的采样率决定了每个变量中的区间数。在此采样率下,图像点与多个可能的线兼容;换句话说,我们的线条具有亚像素分辨率,因为它们无法在10x10图像中无重叠地绘制。

    一旦我们选择了一个峰值,例如对应于具有正常(rho,theta) = (6.858,0.9)的线的峰值,我们可以在图像中绘制该线但是我们选择。自动峰值拣选,即找到高投票线的阈值,是它自己的问题 - 您可以在DSP或此处询问有关该主题的另一个问题。

    例如,方法参见MATLAB的documentationhoughpeaks函数的代码和houghlines

    enter image description here