Расположение конечных точек мостоподобной структуры на изображении - PullRequest
11 голосов
/ 30 мая 2011

Как найти конечные точки мостоподобной структуры на изображении?

Ниже приведено обобщенное представление.

Enter image description here

У меня есть набор изображений, похожих на то, что вы видите в левой колонке, как показано на картинке выше.На самом деле я пытаюсь обнаружить / найти две конечные точки, которые показаны в правом столбце на рисунке выше.Это похоже на определение «двух конечных точек» «моста».

Я применил некоторые основные морфологические операции;однако, либо я делаю это неправильно, либо эти основные морфологические операции не работают в этом сценарии.(Я пытался превратить его в скелеты; однако, как только скелеты сформированы, я не могу обнаружить крест с тремя ребрами).

РЕДАКТИРОВАТЬ

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

Я приложил последние обновления к этому вопросу.Ниже приведено более подробное представление, которое включает в себя исходные сегментированные области и соответствующие изображения, которые подверглись «утончающей» морфологической операции.Опять же, левая сторона является первоначально сегментированной областью;в то время как справа будут точки, которые будут обнаружены.

Enter image description here

Ответы [ 6 ]

7 голосов
/ 30 мая 2011

Решение с использованием Python, NumPy , Pymorph и Mahotas :

import pymorph as m
import mahotas
from numpy import where, reshape

image = mahotas.imread('input.png') # Load image

b1 = image[:,:,0] < 100 # Make a binary image from the thresholded red channel
b2 = m.erode(b1, m.sedisk(4)) # Erode to enhance contrast of the bridge
b3 = m.open(b2,m.sedisk(4)) # Remove the bridge
b4 = b2-b3 # Bridge plus small noise
b5 = m.areaopen(b4,1000) # Remove small areas leaving only a thinned bridge
b6 = m.dilate(b3)*b5 # Extend the non-bridge area slightly and get intersection with the bridge.

#b6 is image of end of bridge, now find single points
b7 = m.thin(b6, m.endpoints('homotopic')) # Narrow regions to single points.
labelled = m.label(b7) # Label endpoints.

x1, y1 = reshape(where(labelled == 1),(1,2))[0]
x2, y2 = reshape(where(labelled == 2),(1,2))[0]

outputimage = m.overlay(b1, m.dilate(b7,m.sedisk(5)))
mahotas.imsave('output.png', outputimage)

Output

5 голосов
/ 01 июня 2011

Вот пример кода для определения местоположения точек ветвления после скелетирования изображения:

import pymorph as m
import mahotas
from numpy import array

image = mahotas.imread('1.png') # load image

b1 = image[:,:,1] < 150 # make binary image from thresholded green channel

b2 = m.thin(b1) # create skeleton
b3 = m.thin(b2, m.endpoints('homotopic'), 15) # prune small branches, may need tuning

# structuring elements to search for 3-connected pixels
seA1 = array([[False,  True, False],
       [False,  True, False],
       [ True, False,  True]], dtype=bool)

seB1 = array([[False, False, False],
       [ True, False,  True],
       [False,  True, False]], dtype=bool)

seA2 = array([[False,  True, False],
       [ True,  True,  True],
       [False, False, False]], dtype=bool)

seB2 = array([[ True, False,  True],
       [False, False, False],
       [False,  True, False]], dtype=bool)

# hit or miss templates from these SEs
hmt1 = m.se2hmt(seA1, seB1)
hmt2 = m.se2hmt(seA2, seB2)

# locate 3-connected regions
b4 = m.union(m.supcanon(b3, hmt1), m.supcanon(b3, hmt2))

# dilate to merge nearby hits
b5 = m.dilate(b4, m.sedisk(10))

# locate centroids
b6 = m.blob(m.label(b5), 'centroid')

outputimage = m.overlay(b1, m.dilate(b6,m.sedisk(5)))
mahotas.imsave('output.png', outputimage)  

sample output sample output

2 голосов
/ 30 мая 2011

Здесь у вас есть пример кода в Mathematica , возможно, не оптимальный:

f[i_] := 
   Module[{t, i2, w, z, neighbours, i3, cRed}, 
  (t = Thinning[ColorNegate@i, 15]; 
   i2 = ImageData@Binarize[ DeleteSmallComponents[
        ImageSubtract[t, Dilation[Erosion[t, 1], 1]], 100], .1];

    For[w = 2, w < Dimensions[i2][[1]], w++,
     For[z = 2, z < Dimensions[i2][[2]], z++,
      If[i2[[w, z]] == 1 && i2[[w + 1, z + 1]] == 1, 
         i2[[w, z + 1]] = i2[[w + 1, z]] = 0];
      If[i2[[w, z]] == i2[[w - 1, z - 1]] == 1, 
         i2[[w, z - 1]] = i2[[w - 1, z]] = 0];
      If[i2[[w, z]] == i2[[w + 1, z - 1]] == 1, 
         i2[[w, z - 1]] = i2[[w + 1, z]] = 0];
      If[i2[[w, z]] == i2[[w - 1, z + 1]] == 1, 
         i2[[w, z + 1]] = i2[[w - 1, z]] = 0];
      ]
     ];

    neighbours[l_, k_, j_] := 
      l[[k - 1, j]] +     l[[k + 1, j]] +     l[[k, j + 1]] + l[[k, j - 1]] + 
      l[[k + 1, j + 1]] + l[[k + 1, j - 1]] + l[[k - 1, j + 1]] + 
      l[[k - 1, j - 1]];

    i3 = Table[
      If[i2[[w, z]] ==1,neighbours[i2, w, z], 0],{w,2,Dimensions[i2][[1]]-1}, 
                                                 {z,2,Dimensions[i2][[2]]-1}];
    cRed = 
     ColorNegate@Rasterize[Graphics[{Red, Disk[]}], ImageSize -> 15];

    ImageCompose[
     ImageCompose[i, 
      cRed, {#[[2]], Dimensions[i2][[1]] - #[[1]]} &@
       Position[i3, 1][[1]]], 
      cRed, {#[[2]], Dimensions[i2][[1]] - #[[1]]} &@
       Position[i3, 1][[2]]])];

enter image description here

1 голос
/ 30 мая 2011

На ум приходит общий подход:

1) обведите контур и превратите его в путь.Таким образом, есть один путь, который проходит по всей форме, он состоит из отрезков линии

2) ищет стержень - место на отрезке, где отрезки линии приблизительно параллельны для некоторого расстояния (пространственноеИндекс, например, octree или kdtree поможет сохранить поиск локализованным)

3) следуйте по пути в некотором направлении, пока две стороны внезапно не разойдутся.Это конечная точка для ствола

4) следуйте по пути в другом направлении, чтобы найти другую конечную точку

0 голосов
/ 04 ноября 2013

Одна интересная найденная особенность - это точка соединения в скелете, которая имеет наименьшее значение функции расстояния дополнения объекта, связанного с ним.

X - объект, заданный черным на входном изображении D(X) - Функция расстояния объекта XD (~ X) - Функция расстояния дополнения объекта - это обычно напоминает скелетонизацию объекта, установленного им самим.

Таким образом, основная интуиция здесь заключается в том, чтоТопология объекта X такова, что рядом с тяжелыми головами можно найти щепотку - место, где вы обязательно будете иметь точку соединения в скелете - и в то же время низкое значение функции расстояния дополнения объекта.Шея или щепотка дают минимум здесь в точке соединения.

Может быть, эта идея нуждается в некоторой настройке - но я думаю, что можно обойти.

0 голосов
/ 30 мая 2011

Вы также можете попробовать запустить движущееся окно поверх изображения с фильтром, который является суммой значений пикселей внутри. Настройте размер, чтобы сказать удвоить размер ширины моста. Вы должны ожидать довольно резкого перехода, когда бежите с моста на берег.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...