2017-01-17 13 views
1

Я работаю над изображениями с перекрывающимися линиями (левый участок). В конечном итоге я хочу сегментировать отдельные объекты. Я работаю с преобразованием Hough для достижения этого, и он хорошо работает в поиске линий (значительно) различной ориентации - например, представленный двумя максимумами в пространстве hough ниже (средний участок).Извлечь строчные объекты

houghline - full example

  • зеленые и желтые линии (оставил участок) и крестики (правого участка) проистекают от подхода, чтобы сделать что-то с толщиной линии. Я не мог понять, как извлечь широкую линию, поэтому я не стал следить.
  • Я знаю о двусмысленности присвоения «перекрывающихся пикселей». Я расскажу об этом позже.

Поскольку я не знаю, сколько объектов линии может быть связано одна область, моя идея состоит в том, чтобы итеративно извлечь объект, соответствующий линии hough с наивысшей активацией (здесь окрашен в синий цвет), то есть удалить образный объект с изображением, так что следующая итерация найдет только другую строку.

Но как определить, какие пиксели относятся к объекту с линейной формой?

Функция hough_bin_pixels(img, theta, rho, P) (от here - показано в правой участке) дает пиксели, соответствующие конкретной линии. Но это, очевидно, слишком тонкое из строки для представления объекта.

Есть ли способ сегментировать/обнаруживать весь объект, который ориентирован вдоль самого сильного houghline?

ответ

1

Ключ, зная, что толстые линии в исходном изображении преобразуются в более широкие пики на Преобразование Хафа. На этом изображении показаны пики тонкой и толстой линии.

Thick and thin line with resulting Hough Transform

Вы можете использовать любую стратегию вы хотите сгруппировать все пиксели/аккумуляторные баки каждого пика вместе. Я бы рекомендовал использовать multithresh и imquantize, чтобы преобразовать его в изображение BW, а затем bwlabel для обозначения подключенных компонентов. Вы также можете использовать любое количество других стратегий кластеризации/сегментации. Единственная потенциально сложная часть - это определение уровней порогового уровня. Если вы не можете получить что-нибудь подходящее для своего приложения, ошибайтесь со стороны слишком много, потому что вы можете всегда избавиться от ошибочных пикселей позже.

Вот пики преобразования Хка после пороговой (слева) и маркировок (справа)

Thresholded peaksLabeled peaks

После того, как у вас есть пиковые регионы, вы можете узнать, какие пиксели в исходном изображении способствовал для каждого накопительного бункера с использованием hough_bin_pixels. Затем для каждой области пика объедините результаты hough_bin_pixels для каждого бина, который является частью региона.

Reconstructed Lines

Вот код, который я бросил вместе, чтобы создать образцы изображений. Я просто возвращаюсь в Matlab после того, как не использовал его какое-то время, поэтому, пожалуйста, простите неряшливый код.

% Create an image 
image = zeros(100,100); 

for i = 10:90 
    image(100-i,i)=1; 
end; 

image(10:90, 30:35) = 1; 

figure, imshow(image); % Fig. 1 -- Original Image 

% Hough Transform 
[H, theta_vals, rho_vals] = hough(image); 
figure, imshow(mat2gray(H)); % Fig. 2 -- Hough Transform 

% Thresholding 
thresh = multithresh(H,4); 
q_image = imquantize(H, thresh); 
q_image(q_image < 4) = 0; 
q_image(q_image > 0) = 1; 
figure, imshow(q_image) % Fig. 3 -- Thresholded Peaks 

% Label connected components 
L = bwlabel(q_image); 
figure, imshow(label2rgb(L, prism)) % Fig. 4 -- Labeled peaks 

% Reconstruct the lines 
[r, c] = find(L(:,:)==1); 
segmented_im = hough_bin_pixels(image, theta_vals, rho_vals, [r(1) c(1)]); 
for i = 1:size(r(:)) 
    seg_part = hough_bin_pixels(image, theta_vals, rho_vals, [r(i) c(i)]); 
    segmented_im(seg_part==1) = 1; 
end 
region1 = segmented_im; 

[r, c] = find(L(:,:)==2); 
segmented_im = hough_bin_pixels(image, theta_vals, rho_vals, [r(1) c(1)]); 
for i = 1:size(r(:)) 
    seg_part = hough_bin_pixels(image, theta_vals, rho_vals, [r(i) c(i)]); 
    segmented_im(seg_part==1) = 1; 
end 
region2 = segmented_im; 

figure, imshow([region1 ones(100, 1) region2]) % Fig. 5 -- Segmented lines 

% Overlay and display 
out = cat(3, image, region1, region2); 
figure, imshow(out); % Fig. 6 -- For fun, both regions overlaid on original image 
+0

На самом деле это была действительно крутая идея. У этого есть свои проблемы, если линии действительно различны по длине, подход порогового значения может маскировать локальные максимумы Хау (соответствующие меньшим линиям), которые не являются «высокими», как глобальные максимумы. Я все еще работаю над этим, но в остальном это хороший подход! Спасибо! – Honeybear

+0

Для тех, кто ссылается на этот ответ в будущем, хорошим способом решения проблемы с порогом является использование среднего сдвига для поиска локальных максимумов в преобразовании Хафа. –

+0

Привет @Honeybear, если этот ответ решил ваш вопрос, пожалуйста, рассмотрите [принятие его] (https://meta.stackexchange.com/q/5234/179419), нажав на галочку. Это указывает более широкому сообществу, что вы нашли решение и дали некоторую репутацию как самому, так и самому себе. Это не обязательно. –