Тонкие контурные линии в двоичном изображении - PullRequest
0 голосов
/ 02 апреля 2012

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

Может кто-нибудь дать мне источник, пример кода или дополнительную информацию для этогоКакого рода проблемы и где искать помощь, пожалуйста?

Ответы [ 4 ]

3 голосов
/ 30 декабря 2013

Фактически существует алгоритм для этого, называемый алгоритмом истончения Чжан-Суена. Вы можете найти его код здесь: http://rosettacode.org/wiki/Zhang-Suen_thinning_algorithm

Также я написал векторизованную версию Python, которая примерно в 10 раз быстрее, чем этот код. Вот код:

def neighbours_vec(image):
    return image[2:,1:-1], image[2:,2:], image[1:-1,2:], image[:-2,2:], image[:-2,1:-1],     image[:-2,:-2], image[1:-1,:-2], image[2:,:-2]

def transitions_vec(P2, P3, P4, P5, P6, P7, P8, P9):
    return ((P3-P2) > 0).astype(int) + ((P4-P3) > 0).astype(int) + \
    ((P5-P4) > 0).astype(int) + ((P6-P5) > 0).astype(int) + \
    ((P7-P6) > 0).astype(int) + ((P8-P7) > 0).astype(int) + \
    ((P9-P8) > 0).astype(int) + ((P2-P9) > 0).astype(int)

def zhangSuen_vec(image, iterations):
    for iter in range (1, iterations):
        print iter
        # step 1    
        P2,P3,P4,P5,P6,P7,P8,P9 = neighbours_vec(image)
        condition0 = image[1:-1,1:-1]
        condition4 = P4*P6*P8
        condition3 = P2*P4*P6
        condition2 = transitions_vec(P2, P3, P4, P5, P6, P7, P8, P9) == 1
        condition1 = (2 <= P2+P3+P4+P5+P6+P7+P8+P9) * (P2+P3+P4+P5+P6+P7+P8+P9 <= 6)
        cond = (condition0 == 1) * (condition4 == 0) * (condition3 == 0) * (condition2 == 1) * (condition1 == 1)
        changing1 = numpy.where(cond == 1)
        image[changing1[0]+1,changing1[1]+1] = 0
        # step 2
        P2,P3,P4,P5,P6,P7,P8,P9 = neighbours_vec(image)
        condition0 = image[1:-1,1:-1]
        condition4 = P2*P6*P8
        condition3 = P2*P4*P8
        condition2 = transitions_vec(P2, P3, P4, P5, P6, P7, P8, P9) == 1
        condition1 = (2 <= P2+P3+P4+P5+P6+P7+P8+P9) * (P2+P3+P4+P5+P6+P7+P8+P9 <= 6)
        cond = (condition0 == 1) * (condition4 == 0) * (condition3 == 0) * (condition2 == 1) * (condition1 == 1)
        changing2 = numpy.where(cond == 1)
        image[changing2[0]+1,changing2[1]+1] = 0
    return image
2 голосов
/ 03 апреля 2012

Если вы ищете реализации Python, взгляните на scikit-image .

Один из их примеров , по сути, ваш вариант использования.

В качестве альтернативы, если вы хотите придерживаться "прямой" сципи, вы можете сделать это, используя последовательные эрозии и расширения, используя scipy.ndimage. (Как упоминает @AxezDNyde.)

Редактировать: Исправлены ссылки.

1 голос
/ 02 апреля 2012

Комбинация эрозии и расширения (и наоборот) на бинарном изображении может помочь избавиться от соли и перца, как шум, оставляя маленькие линии нетронутыми. Ключевые слова: «фильтры рангового порядка» и «морфологические фильтры».

0 голосов
/ 28 ноября 2014

В PyPi есть пакет под названием thinning , который вы можете просто установить pip.В нем реализован алгоритм прореживания Го и Холла для неровных массивов / изображений в градациях серого opencv.

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