Ajude a entender a transformação Hough

19

Estou tentando fazer com que uma transformação Hough funcione no MATLAB, mas estou tendo problemas. Eu tenho uma maneira realmente ruim de detectar picos que precisam ser corrigidos, mas antes disso eu preciso ser capaz de reverter a transformação hough para criar as linhas novamente corretamente. Este é o tipo de coisa que estou recebendo agora:

insira a descrição da imagem aqui

parece girar 90 graus, mas não sei por que. Não tenho certeza se é o meu espaço Hough que está errado, ou se é o modo como eu de-Hough e traço as linhas. Também alguém poderia ajudar a melhorar minha detecção de pico? As imagens usadas no código estão aqui

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

Linked: Como fazer a remoção do houghing de uma imagem transformada hough?

waspinator
fonte
você conseguiu resolver o seu problema? Estou enfrentando um problema semelhante. obrigado
Erez Posner
transformação de Hough sous Matlab derramar detecter plusieurs elipses

Respostas:

11

Em primeiro lugar, o Matlab possui uma transformação Built-Hough : não há necessidade de reinventar a roda.

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

Embora sua imagem não exija necessariamente detecção de borda, você pode melhorar o tempo de processamento e a eficácia do algoritmo ao usá-lo. Seu triângulo possui regiões gordas de branco e preto. Idealmente, o triângulo teria 1px de espessura marcando as bordas do triângulo. Use a detecção de borda flexível

BW = edge(Image,'canny');

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

Existe a possibilidade de você escolher o pico errado, porque existem picos vizinhos que podem ser maiores na matriz do acumulador. Embora existam muitos algoritmos, aqui é um que eu vi usado no Hough Transforms no passado:

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.

Procure no HoughLines para exibir as linhas de transformação do hough, resultados:

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

Efeitos do uso do Canny Edge Detector

A detecção de borda pode potencialmente transformar cada lado do triângulo em duas linhas.

O objetivo da detecção de arestas inteligentes é produzir arestas finas / estreitas ao máximo usando supressão não-máxima

Detecção de Canny Edge em poucas palavras (Fonte: 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
fonte
Obrigado pela resposta. Estou fazendo isso do zero para entender melhor. A detecção inteligente de arestas ainda dá 2 triângulos. um para a borda interna e para fora da borda externa. Eu aprendi a teoria da wikipedia, que afirma que teta é 0: pi. Eu sei que a função interna usa -pi / 2: pi / 2, mas não deve haver uma diferença real?
Waspinator
Logo de cara, o alcance não deve fazer diferença. (você pode dizer a diferença entre uma linha que foi girada em 180 graus?) NO ENTANTO, isso faz diferença se você estiver usando a transformação hough para algoritmos de correção de imagem. (Seria significar a diferença entre uma rightside-se e imagem de cabeça para baixo)
CYBERMEN
A detecção de borda não produziria duas linhas nas quais você deseja encontrar apenas uma? Algo que encontre o centro de uma linha grossa seria melhor.
Endolith
@endolith incluído um pouco de discussão de detecção de borda no post original
CYBERMEN
'Não há necessidade de reinventar a roda'? Diga isso ao meu instrutor ;-)
Nathan Schwermann
3
    if image(xi, yj) == 1 

precisa ser alterado para

    if image(yj, xi) == 1 

para que as linhas funcionem em profundidade

waspinator
fonte
1

A resposta usando os 3 loops é menor que a ideal e pode ser melhorada. Aqui está uma abordagem / ponto de vista intuitivo:

Cada par de pontos válidos define um a & b exclusivo y = ax + b. Uma linha terá muitos pares com o mesmo valor a & b; portanto, uma linha longa estará presente como um pico. Isso também se aplica às coordenadas polares r & teta.

Em vez de tratar cada ponto separadamente, use pares de pontos. Se você pode armazenar todos os pontos (geralmente esparsos) em uma lista separada, é melhor, mas não é obrigatório.

  1. Pegue cada par e calcule seu a & b. (arredondado para valores discretos)
  2. Vá para o local específico na matriz e adicione 1.

Linha longa -> muitos pares com o mesmo a, b.
Pontos esporádicos -> pequena contagem em células específicas -> mais como desordem.


Outra maneira de ver isso é do ponto de vista projetivo / Radon.

  • Uma linha será projetada fortemente para uma "linha de coleta" perpendicular, obtendo uma pontuação alta.
  • Se o ângulo entre a linha e a "linha de coleta" não for 90 graus ou a linha de coleta não coletar todos os pontos de linha projetados nessa "linha de coleta", haverá uma pontuação menor.
Ilan sinai
fonte