только горизонтально-вертикальные линии

Я новичок в Matlab. У меня есть блок изображения, как показано ниже:  введите описание изображения здесь

Белые цвета показывают пиксель, что их значения равны 1, а черные показывают пиксель, что их значения равны 0,

Я хочу получить vertical only lines. Это означает, что горизонтальные линии следует удалить, как показано ниже:

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

Также хочу получить horizontal only lines. Это означает, что следует удалить вертикальные линии, как показано ниже:

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

Как это сделать в Matlab? Я предпочитаю для этого морфологические операции.


person Babak.Abad    schedule 12.02.2017    source источник
comment
Я думаю, вам нужно будет определить еще несколько правил, например 1) 1 пиксель не может быть ни горизонтальным, ни вертикальным, тогда он должен быть удален? 2) Что делать, если горизонтальная и вертикальная линии пересекаются в точке, тогда удаление горизонтали приведет к удалению пикселя и из вертикальной линии. Как вы хотите с этим справиться? 3) Согласны ли вы, что минимальное количество пикселей, необходимых для вызова набора пикселей, образующих линию, равно двум? После того, как вы их определите, можно будет сразу обнаружить смежные окна с интересующими черными пикселями.   -  person Abhinav    schedule 12.02.2017


Ответы (2)


Предполагая, что ваше изображение BW ниже:

% detecting all connected regions:
B = bwboundaries(BW,4);

Это приводит к массиву ячеек B, который содержит все «заплатки», которые создаются путем соединения соседних ячеек со значением 1, которые соединены с одной из 4 сторон, то есть не по диагонали.

B = 
    [11x2 double]
    [ 2x2 double]
    [ 3x2 double]
    [ 3x2 double]
    [ 2x2 double]
    [ 3x2 double]
    [ 2x2 double]
    [ 2x2 double]
    [ 3x2 double]
    [ 3x2 double]
    [ 2x2 double]
    [11x2 double]

Например:

>> B{6}
ans =
     3     7
     3     8
     3     7

Каждая строка представляет собой координаты одной ячейки. Первый столбец - это его строка, второй - его столбец, а первая и последняя ячейки всегда одинаковы.

Теперь нам нужно пройтись по ячейкам в B и найти, какие из них являются линиями, горизонтальными или вертикальными, и сохранить их в новых матрицах.

% matrices for horizontal and vertical lines:
BWh = zeros(size(BW)); % horizontal lines
BWv = zeros(size(BW)); % vertical lines
for k = 1:numel(B)
    % if the coordinates changes ONLY vertically:
    % a vertical line is where all the coulmn indecies are the same
    % and there are different row indices
    if all(B{k}(1,2)==B{k}(:,2)) && B{k}(1,1)~=B{k}(2,1) 
        BWv(sub2ind(size(BW),B{k}(:,1),B{k}(:,2))) = 1;
    end
    % if the coordinates changes ONLY horizontaly:
    % a vertical line is where all the row indecies are the same
    % and there are different column indices
    if all(B{k}(1,1)==B{k}(:,1)) && B{k}(1,2)~=B{k}(2,2)
        BWh(sub2ind(size(BW),B{k}(:,1),B{k}(:,2))) = 1;
    end
end
subplot 131
imagesc(BWh)
title('Horizontal lines')
subplot 132
imagesc(BWv)
title('Vertical lines')

«Диагональные края» - это то, что осталось после того, как мы исключили линии, поэтому мы можем просто поискать то, что мы пока не нашли:

subplot 133
imagesc(BW & ~BWv & ~BWh)
title('Diagonal edges')
colormap 'gray'

BWvh

Этот метод игнорирует все, что не является толстой линией в одну ячейку, поэтому, например, квадрат в середине на изображении ниже будет отображаться только в шаблоне Диагональные края:

демонстрационная коробка

person EBH    schedule 12.02.2017
comment
извините, есть ли способ распознать только диагональные края? Я предпочитаю делать это без вычитания изображений. - person Babak.Abad; 12.02.2017
comment
Уважаемый EBH, Если это возможно, просьба предоставить дополнительные комментарии о «Как работает ваш алгоритм» - person Babak.Abad; 12.02.2017
comment
@ Babak.Abad Я добавлю больше комментариев через несколько часов. Что такое края только по диагонали? - person EBH; 12.02.2017
comment
Диагональные края означают пиксели, которые не включены (горизонтальные и вертикальные линии). Например, на вашем последнем изображении пиксели в точках (8,2), (4,6) имеют диагональ. также он не может быть одиночным, как видно в пункте (6,12). Я прошу прощения за свои ошибки, связанные с отсутствием определения диагональных краев, и за мой плохой английский текст. Еще раз спасибо за время, которое вы потратили на мои вопросы. - person Babak.Abad; 12.02.2017
comment
@ Babak.Abad см. Мою правку для получения дополнительных объяснений и извлечения диагональных краев. - person EBH; 12.02.2017
comment
Большое спасибо за ваш полный и исчерпывающий ответ и недавнее обновление. Все ваши подходы превосходят мои подходы (анализ связанных компонентов) по скорости и сложности. - person Babak.Abad; 13.02.2017

Интересный вопрос, потому что есть много способов сделать это. По сути, вам нужно удалить последовательные пиксели определенного размера. Я вижу один из способов решить эту проблему - выполнить свертку с вектором [1 1] или [1 1]', а затем удалить все элементы, из которых вы получаете значения 2.

bw(conv2(bw,[1 1],'same')==2)=0;

при этом по-прежнему останутся отдельные пиксели, которые вы можете легко удалить, используя

bw = bwareaopen(bw,2) ;

это просто основная идея, вам, вероятно, нужно быть более осторожным с краями или заполнить нулями, чтобы избежать краевых артефактов, которые может создать conv2) ...

Другая идея - использовать преобразование Хафа для обнаружения линий и сохранения только тех с theta = 0 или 90 градусов ...

person bla    schedule 12.02.2017
comment
Спасибо, за ответы. Новый способ ... Но второй ответ правильный и полный. +1 за ваш ответ - person Babak.Abad; 12.02.2017