Aidez à comprendre la transformation de Hough

19

J'essaie d'obtenir une transformation Hough pour travailler dans MATLAB, mais j'ai des problèmes. J'ai une très mauvaise façon de détecter les pics qui doivent être corrigés, mais avant cela, je dois pouvoir inverser la transformation de Hough pour recréer correctement les lignes. C'est le genre de choses que je reçois en ce moment:

entrez la description de l'image ici

ressemble à sa rotation de 90 degrés, mais je ne sais pas pourquoi. Je ne sais pas si c'est mon espace Hough qui est faux, ou si c'est la façon dont je dé-Hough et dessine les lignes. Est-ce que quelqu'un pourrait aussi aider à améliorer ma détection des pics? Les images utilisées dans le code sont ici

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

Lié: Comment faire le De-Houghing d'une Image transformée de Hough?

waspinator
la source
avez-vous réussi à résoudre votre problème? je suis confronté à un problème similaire. merci
Erez Posner
transformation de hough sous matlab pour détecter plusieurs ellipses

Réponses:

11

Tout d'abord, Matlab a une transformation Hough intégrée : pas besoin de réinventer la roue.

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

Bien que votre image ne nécessite pas nécessairement la détection des contours, vous pouvez améliorer le temps de traitement et l'efficacité de l'algorithme en l'utilisant. Votre triangle a de grosses régions blanches et noires. Idéalement, le triangle aurait une épaisseur de 1px marquant les bords du triangle. Utiliser la détection Canny Edge

BW = edge(Image,'canny');

90<θ<900<θ<1800<θ<π90π/2

Il est possible que vous choisissiez le mauvais pic, car il existe des pics voisins qui peuvent être plus grands dans la matrice de l'accumulateur. Bien qu'il existe de nombreux algorithmes, voici celui que j'ai vu utilisé dans Hough Transforms dans le passé:

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.

Regardez dans HoughLines pour afficher les lignes de transformation de Hough, résultats:

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

Effets de l'utilisation du détecteur Canny Edge

La détection des bords peut potentiellement transformer chaque côté du triangle en deux lignes.

Le but de la détection des bords astucieux est de produire des bords minces / étroits au maximum en utilisant une suppression non maximale

Détection de Canny Edge en bref (Source: Digital Image Processing, 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
CyberMen
la source
Merci pour la réponse. Je le fais à partir de zéro pour mieux le comprendre. la détection de bord rusé donne toujours 2 triangles. un pour le bord intérieur, et dehors pour le bord extérieur. J'ai appris la théorie de wikipedia, qui déclare que thêta est 0: pi. Je sais que la fonction intégrée utilise -pi / 2: pi / 2, mais il ne devrait pas y avoir de réelle différence?
waspinator
Dès le départ, la portée ne devrait pas faire de différence. (pouvez-vous faire la différence entre une ligne qui a été tournée de 180 degrés?) CEPENDANT, cela fait une différence si vous utilisez la transformation de Hough pour les algorithmes de correction d'image. (Cela signifierait la différence entre une image à l'envers et une image à l'envers)
CyberMen
La détection des contours ne produirait-elle pas 2 lignes où vous ne souhaitez en trouver qu'une? Quelque chose qui trouve le centre d'une ligne épaisse serait mieux.
endolith
@endolith Inclus un peu de discussion sur la détection des
contours
'pas besoin de réinventer la roue'? Dites cela à mon instructeur ;-)
Nathan Schwermann
3
    if image(xi, yj) == 1 

doit être changé en

    if image(yj, xi) == 1 

pour que les lignes fonctionnent dans le dehough

waspinator
la source
1

La réponse en utilisant les 3 boucles est moins qu'optimale et pourrait être améliorée, voici plus une approche / point de vue intuitif:

Chaque paire de points valides définit un a & b unique de y = ax + b. Une ligne aura beaucoup de paires avec la même valeur a & b, donc une longue ligne aura été présente comme un pic. Cela est également vrai pour les coordonnées polaires r & teta.

Au lieu de traiter chaque point séparément, utilisez des paires de points. Si vous pouvez stocker tous les points (généralement clairsemés) dans une liste séparée, c'est mieux, mais ce n'est pas un must.

  1. Prenez chaque paire et calculez ses a et b. (valeurs arrondies à discrètes)
  2. Accédez à l'emplacement spécifique dans le tableau et ajoutez 1.

Longue ligne -> beaucoup de paires avec le même a, b.
Points sporadiques -> petit comptage dans des cellules spécifiques -> plus comme un fouillis.


Une autre façon de voir les choses est d'un point de vue radon / projectif.

  • Une ligne se projettera fortement vers une "ligne de collecte" perpendiculaire, ayant ainsi un score élevé.
  • Si l'angle entre la ligne et la "ligne de collecte" n'est pas de 90 degrés ou si la ligne de collecte ne collecte pas tous les points de ligne projetés dans cette "ligne de collecte", le score sera inférieur.
Ilan sinai
la source