我正在尝试让霍夫(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



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

评论

您设法解决问题了吗?我正面临类似的问题。谢谢

hough转换matlab倒检测器plusieurs椭圆

#1 楼

首先,Matlab具有内置的Hough变换:无需重新发明轮子。以及算法的有效性。您的三角形有白色和黑色的胖区域。理想情况下,三角形的厚度应为1px,标记三角形的边缘。使用Canny Edge Detection

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


结果是\ theta在$ -90 <\ theta <90 $度的范围内,而您的绘图是$ 0 <\ theta <180 $(或$ 0 <\ theta <\ pi $),因此减去$ 90 $度($ \ pi / 2 $)。在累加器矩阵中可能更大。尽管这里有很多算法,但我过去曾在其中使用过一种算法:

BW = edge(Image,'canny');


查看HoughLines以显示hough变换线,结果:

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

使用Canny Edge Detector的效果

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

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

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

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.


评论


$ \ begingroup $
感谢您的答复。我正在从头开始以更好地理解它。坎尼边缘检测仍然给出2个三角形。一个用于内边缘,一个用于外边缘。我从维基百科学到了理论,该理论指出theta为0:pi。我知道内置函数使用-pi / 2:pi / 2,但是应该没有真正的区别吗?
$ \ endgroup $
– Waspinator
2012年4月10日在18:13

$ \ begingroup $
马上行动,射程不会有所作为。 (您能分辨出已旋转180度的线之间的差异吗?)但是,如果您将霍夫变换用于图像校正算法,则确实会有所不同。 (这意味着右侧图像和上下图像之间的差异)
$ \ endgroup $
–Cyber​​Men
2012年10月10日18:38

$ \ begingroup $
边缘检测不会在只想找到1条的地方产生2条线吗?找到粗线中心的方法会更好。
$ \ endgroup $
– Endolith
2012年10月10日19:31

$ \ begingroup $
@endolith在原始帖子中包含了一些关于边缘检测的讨论
$ \ endgroup $
–Cyber​​Men
2012年4月11日,12:50

$ \ begingroup $
“不需要重新发明轮子”?告诉我的老师;-)
$ \ endgroup $
–内森·史威文(Nathan Schwermann)
2012年10月20日6:56

#2 楼

    if image(xi, yj) == 1 


需要更改为

    if image(yj, xi) == 1 


为了使线路在dehough中工作

#3 楼

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

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

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


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

长线->许多对具有相同a,b的对。
零星的点->在特定单元格中进行少量计数->更像是混乱。


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


线条会强烈地投射到垂直的“收集线”,因此得分较高。
如果线与“收集线”之间的夹角不为90度,或者收集线未收集投影到该“收集线”中的所有线点,则得分会降低。