1

У меня есть скелетное изображение (показано ниже).Поиск пересечений скелетного изображения в python opencv

Skeleton Image

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

def getSkeletonIntersection(skeleton): 
    image = skeleton.copy(); 
    image = image/255; 
    intersections = list(); 
    for y in range(1,len(image)-1): 
     for x in range(1,len(image[y])-1): 
      if image[y][x] == 1: 
       neighbourCount = 0; 
       neighbours = neighbourCoords(x,y); 
       for n in neighbours: 
        if (image[n[1]][n[0]] == 1): 
         neighbourCount += 1; 
       if(neighbourCount > 2): 
        print(neighbourCount,x,y); 
        intersections.append((x,y)); 
    return intersections; 

Он находит координаты белых пикселей, где есть более двух смежных пикселей. Я думал, что это только вернет углы, но это не так - оно возвращает еще много очков.

Skeleton with marked coordinates

Это выход с точками он обнаруживает, помеченных на изображении. Это происходит потому, что он обнаруживает некоторые из приведенных ниже примеров, которые не являются пересечениями.

0 0 0 1 1 0 0 1 1 
1 1 1 0 1 0 1 1 0 
0 0 1 0 0 1 0 0 0 

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

+0

возможно увеличить счет до 4 или 6, чтобы отфильтровать точки в этой строке 'if (neighbourCount> 2):'. –

ответ

2

Я не уверен OpenCV особенностей, но вы должны, может быть, попробовать использовать Hit и мисс морфологию, которая описана here.

Читайте на линии Junctions и посмотреть 12 шаблонов вы должны проверить:

enter image description here

+0

Приветствия. Закончилось тестирование из большого списка линейных соединений. –

1

Это может помочь, если когда для данного пикселя, вместо подсчета количества общего 8- соседи (= соседи с подключением 8), вы сосчитать число 8-соседей , которые не являются 4-соседи друг с другом

Таким образом, в вашем примере ложных срабатываний

0 0 0 1 1 0 0 1 1 
1 1 1 0 1 0 1 1 0 
0 0 1 0 0 1 0 0 0 

Для каждого случая у вас есть 3 соседи, но каждый раз 2 из них 4-подключены. (Пикселей с пометкой «2» в следующем фрагменте кода)

0 0 0 2 2 0 0 2 2 
1 1 2 0 1 0 1 1 0 
0 0 2 0 0 1 0 0 0 

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

0 1 0 0 1 0 0 1 0 
1 1 1 0 1 0 1 1 0 
0 0 0 1 0 1 0 0 1 

, которые до сих пор имеют 3 вновь определенных соседей.

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

1

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

def getSkeletonIntersection(skeleton): 
    """ Given a skeletonised image, it will give the coordinates of the intersections of the skeleton. 

    Keyword arguments: 
    skeleton -- the skeletonised image to detect the intersections of 

    Returns: 
    List of 2-tuples (x,y) containing the intersection coordinates 
    """ 
    # A biiiiiig list of valid intersections    2 3 4 
    # These are in the format shown to the right   1 C 5 
    #             8 7 6 
    validIntersection = [[0,1,0,1,0,0,1,0],[0,0,1,0,1,0,0,1],[1,0,0,1,0,1,0,0], 
         [0,1,0,0,1,0,1,0],[0,0,1,0,0,1,0,1],[1,0,0,1,0,0,1,0], 
         [0,1,0,0,1,0,0,1],[1,0,1,0,0,1,0,0],[0,1,0,0,0,1,0,1], 
         [0,1,0,1,0,0,0,1],[0,1,0,1,0,1,0,0],[0,0,0,1,0,1,0,1], 
         [1,0,1,0,0,0,1,0],[1,0,1,0,1,0,0,0],[0,0,1,0,1,0,1,0], 
         [1,0,0,0,1,0,1,0],[1,0,0,1,1,1,0,0],[0,0,1,0,0,1,1,1], 
         [1,1,0,0,1,0,0,1],[0,1,1,1,0,0,1,0],[1,0,1,1,0,0,1,0], 
         [1,0,1,0,0,1,1,0],[1,0,1,1,0,1,1,0],[0,1,1,0,1,0,1,1], 
         [1,1,0,1,1,0,1,0],[1,1,0,0,1,0,1,0],[0,1,1,0,1,0,1,0], 
         [0,0,1,0,1,0,1,1],[1,0,0,1,1,0,1,0],[1,0,1,0,1,1,0,1], 
         [1,0,1,0,1,1,0,0],[1,0,1,0,1,0,0,1],[0,1,0,0,1,0,1,1], 
         [0,1,1,0,1,0,0,1],[1,1,0,1,0,0,1,0],[0,1,0,1,1,0,1,0], 
         [0,0,1,0,1,1,0,1],[1,0,1,0,0,1,0,1],[1,0,0,1,0,1,1,0], 
         [1,0,1,1,0,1,0,0]]; 
    image = skeleton.copy(); 
    image = image/255; 
    intersections = list(); 
    for x in range(1,len(image)-1): 
     for y in range(1,len(image[x])-1): 
      # If we have a white pixel 
      if image[x][y] == 1: 
       neighbours = zs.neighbours(x,y,image); 
       valid = True; 
       if neighbours in validIntersection: 
        intersections.append((y,x)); 
    # Filter intersections to make sure we don't count them twice or ones that are very close together 
    for point1 in intersections: 
     for point2 in intersections: 
      if (((point1[0] - point2[0])**2 + (point1[1] - point2[1])**2) < 10**2) and (point1 != point2): 
       intersections.remove(point2); 
    # Remove duplicates 
    intersections = list(set(intersections)); 
    return intersections; 

Это также доступно на github here.