2012-03-28 58 views
5

我发现了霍夫变换在MATLAB中的实现Rosetta Code,但我无法理解它。另外我想修改它以显示原始图像和重建线(去Houghing)。霍夫变换在MATLAB中不使用霍夫函数

任何帮助理解它和de-Houghing是赞赏。谢谢

  1. 为什么图像翻转?

    theImage = flipud(theImage);

  2. 我不能换我的头周围的规范功能。它的目的是什么,可以避免吗?

编辑:规范仅仅是欧几里得距离的同义词:SQRT(宽度^ 2 +高度^ 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. 我该如何解开Hough空间来重新创建线条?

使用对角线的10×10图像调用函数使用标识(眼)函数

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 
+0

对[DSP.SE](http://dsp.stackexchange.com/)更好的问题。 – Phonon 2012-03-29 01:33:33

+1

@Phonon为什么?这是一个关于特定算法实现细节的问题。 – 2012-03-29 04:50:49

回答

5

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

我们离散参数空间,并允许每个图像点建议参数,这些参数将与点通过的线相容。您的每个问题都可以通过代码中参数空间的处理方式来解决。 Wikipedia有一个很好的文章与工作的例子,可能会澄清事情(如果你有任何概念上的麻烦)。

为了您的具体问题:

  1. 图片翻转,使得原产地是右下角。据我所知,这一步在技术上并非必要。由于离散化问题,它的确会改变结果。 Rosetta Code上的其他实现不会翻转图像。
  2. rhoLimit在极坐标中保留图像点的最大半径(回想一下矢量的范数就是它的大小)。
  3. rhotheta是根据采样率的极坐标平面的离散化。houghSpace为离散ρ/θ值的每种可能组合创建一个元素矩阵。
  4. 霍夫变换没有指定的推定的行中的长度;投票空间中的峰值仅指定该线的法向矢量的极坐标。您可以通过选择峰值并绘制相应的线条,或者通过绘制每条可能的线条并使用投票数量作为灰度权重来“解开霍夫”。从Hough变换中重新创建原始图像是不可能的,只需通过变换(以及您的投票的阈值方案)确定的线条即可。

在从问题的示例产生下面的曲线图。网格线和数据提示光标的放置可能有点误导(尽管'提示中的变量值是正确的)。由于这是参数空间,而不是图像空间我们选择了采样速率是确定在每个可变区间的数目的图像。在这个采样率下,图像点与多个可能的线条兼容;换句话说,我们的线具有亚像素分辨率,因为它们不能在10x10图像中不重叠地绘制。

一旦我们已经选择了一个峰,例如对应于线与正常(rho,theta) = (6.858,0.9),我们可以得出该行的图像中但是我们选择。自动化高峰采摘,即阈值找到高度上投系,是自己的问题 - 你可以询问有关议题的另一个问题在DSP或有关特定算法在这里。

例如方法参见MATLAB的houghpeakshoughlines函数的代码和documentation

enter image description here

+0

谢谢。我们为什么要让原点位于右下角?我怎么读这个[输出](http://i.imgur.com/LuVLI.png)。 Theta会是1还是1.5? Rho会是6.858还是上面那个?还是这些值的平均值?寻找霍夫变换中所有'热点'的好方法是什么?绘制线条的最佳方式是什么?从wikipeida我可以看到表达式y = mx + b,其中M = - (COS(THETA)/ SIN(THETA))和b = R/SIN(THETA)。我会根据这些参数绘制一条线吗?谢谢 – waspinator 2012-03-29 02:57:08

+0

它看起来像matlabs实现可以检测行的开始和结束。我的目的不是必需的,但很有趣。我只需要基础知识。在我明白这一点之前,我还有很多事情要做,但是你已经帮了很大的忙。谢谢。在我离开这个问题之前,你能否澄清为什么我们希望原点位于右下角而不是左侧? – waspinator 2012-03-29 14:33:38

+0

要猜测线段的端点,您必须使用图像中的其他信息。 MATLAB似乎找到了最有意思的像素对,它们对像素有贡献,并将它们视为终点。 – 2012-03-29 20:38:26