Допоможіть зрозуміти трансформацію Хоф


19

Я намагаюся отримати трансформацію Hough для роботи в MATLAB, але у мене виникають проблеми. У мене дійсно поганий спосіб виявити вершини, які потрібно виправити, але перед цим мені потрібно мати можливість змінити перетворення Hough, щоб знову створити лінії належним чином. Це тип матеріалів, які я зараз отримую:

введіть тут опис зображення

схоже, що вона повертається на 90 градусів, але я не знаю чому. Я не впевнений, чи неправильно це мій простір Хога, чи це я, як я де-Хоф і малюю лінії. Також хтось може допомогти покращити моє пікове виявлення? Зображення, використані в коді, є тут

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

Пов’язано: Як зробити де-хокінг Хоф-трансформованого зображення?


чи вдалося вам вирішити свою проблему? Я стикаюся з подібним питанням. дякую
Ерез Познер

перетворення de hough sous matlab pour détecter plusieurs ellipses

Відповіді:


11

По-перше, Matlab має вбудований Hough Transform : не потрібно винаходити колесо.

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

Хоча ваше зображення не обов'язково вимагає виявлення краю, ви могли б покращити час обробки та ефективність алгоритму, який я використовую. У вашому трикутнику є жирні ділянки білого та чорного кольорів. В ідеалі трикутник буде товщиною 1 піксель, що позначає краї трикутника. Використовуйте виявлення країв Canny

BW = edge(Image,'canny');

результат - \ theta знаходиться в діапазоні градусів, тоді як ваш графік (або ), тому віднімайте градусів ( ).90<θ<900<θ<1800<θ<π90π/2

Ви можете вибрати неправильний пік, оскільки існують сусідні піки, які можуть бути більшими в матриці акумулятора. Хоча є багато алгоритмів, ось такий, який я бачив раніше, використовувався в Hough Transforms:

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.

Подивіться на HoughLines для відображення лінії перетворення Hough, результати:

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

Ефекти використання детектора решт Canny

Виявлення країв потенційно може перетворити кожну сторону трикутника на дві лінії.

Метою виявлення реберних ребер є створення максимально тонких / вузьких країв, використовуючи немаксимальне придушення

Виявлення Кенні Edge в горішці (Джерело: Цифрова обробка зображень, 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

Дякую за відповідь. Я роблю це з нуля, щоб краще зрозуміти це. Кенні виявлення ребер все ще дає 2 трикутники. один для внутрішнього краю, а зовнішній для зовнішнього краю. Я вивчив теорію з wikipedia, де сказано, що тета дорівнює 0: pi. Я знаю, що вбудована функція використовує -pi / 2: pi / 2, але реальної різниці не повинно бути?
waspinator

Безпосередньо від кажана, діапазон не повинен змінити значення. . (Це означало б різницю між зображенням, розміщеним правою стороною вгору та зменшеним розміром)
CyberMen

Чи не виявлення ребра дасть 2 рядки, де ви хочете знайти лише 1? Щось, що знаходить центр товстої лінії, було б краще.
ендоліт

@endolith Включено трохи обговорення виявлення країв у початковому дописі
CyberMen

"не потрібно винаходити колесо"? Скажіть це моєму інструктору ;-)
Натан Шверман

3
    if image(xi, yj) == 1 

потрібно змінити на

    if image(yj, xi) == 1 

щоб лінії були відпрацьовані в дехо


1

Відповідь за допомогою 3-х циклів є менш оптимальною і її можна вдосконалити, тут більше інтуїтивного підходу / точки зору:

Кожна пара дійсних точок встановлює єдино і Ь y = ax + b. У рядку буде багато пар з однаковим значенням & b, тому довгий рядок буде присутній як пік. Це справедливо і для полярних координат r & teta.

Замість обробки кожної точки окремо використовуйте пари крапок. Якщо ви можете зберігати всі (зазвичай рідкісні) точки в окремому списку, це краще, але це не обов’язково.

  1. Візьміть кожну пару і обчисліть її & b. (округляються до дискретних значень)
  2. Перейдіть до конкретного місця в масиві та додайте 1.

Довга лінія -> багато пар з однаковим a, b.
Спорадичні точки -> малий підрахунок у конкретних клітинах -> більше схожий на захаращення.


Ще один спосіб поглянути на це - з точки зору Радона / Проекції.

  • Лінія буде сильно виступати на перпендикулярну "лінію збору", щоб мати високий бал.
  • Якщо кут між лінією та "лінією збору" не дорівнює 90 град. Або збиральна лінія не збирає всі точки лінії, що проектуються на цю "лінію збору", буде нижчий бал.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.