【问题标题】:Hough transform in MATLAB without using hough functionMATLAB中的霍夫变换不使用霍夫函数
【发布时间】:2012-03-28 21:57:12
【问题描述】:

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

感谢您对理解它和去 Houghing 的任何帮助。谢谢

  1. 为什么图片会翻转?

    theImage = flipud(theImage);

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

编辑: 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. 如何去霍夫空间重新创建线条?

使用使用身份(眼睛)函数创建的对角线的 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

【问题讨论】:

  • DSP.SE 的更好问题。
  • @Phonon 为什么?这是一个关于特定算法的实现细节的问题。

标签: matlab hough-transform


【解决方案1】:

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

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

对于您的具体问题:

  1. 图像被翻转,因此原点位于右下角。据我所知,这一步在技术上不是必需的。由于离散化问题,它确实在一定程度上改变了结果。 Rosetta Code 上的其他实现不翻转图像。
  2. rhoLimit 保存极坐标中图像点的最大半径(回忆一下向量的范数就是它的大小)。
  3. rhotheta 是根据采样率对极坐标平面进行的离散化。 houghSpace 为离散 rho/theta 值的每个可能组合创建一个包含一个元素的矩阵。
  4. 霍夫变换没有指定假定线的长度;投票空间中的峰值仅指定线法向量的极坐标。您可以通过选择峰值并绘制相应的线来“去霍夫”,或者通过绘制每条可能的线并将投票数用作灰度权重。无法通过 Hough 变换重新创建原始图像,只能重新创建变换识别的线条(以及您的投票阈值方案)。

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

一旦我们选择了一个峰值,例如对应于正常(rho,theta) = (6.858,0.9) 的线的峰值,我们就可以在图像中画出我们选择的那条线。自动峰值选择,即阈值以找到高票数的行,是它自己的问题 - 您可以在 DSP 中询问有关该主题的另一个问题,或在此处询问特定算法。

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

【讨论】:

  • 谢谢。为什么我们希望原点位于右下角?我将如何阅读此 output 。 Theta 是 1 还是 1.5? Rho 会是 6.858 还是更高?还是这些值的平均值?在霍夫变换中搜索所有“热点”的好方法是什么?绘制找到的线条的最佳方法是什么?从维基百科我可以看到 y = mx + b 其中 m = -(cos(theta)/sin(theta)) 和 b = r/sin(theta)。我会根据这些参数画一条线吗?谢谢
  • 看起来matlabs实现可以检测行的开头和结尾。对我的目的来说不是必需的,但很有趣。我只需要基础知识。在我充分理解这一点之前,我还有很多工作要做,但你帮了很多忙。谢谢你。在我离开这个问题之前,您能否澄清一下为什么我们希望原点位于右下角而不是左下角?
  • 要猜测线段的端点,您必须使用图像中的其他信息。 MATLAB 似乎会找到对 bin 有贡献的最远像素对并将它们视为端点。
猜你喜欢
  • 1970-01-01
  • 2013-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多