Как убрать белую рамку / край вокруг фигуры в изображении, используя python? - PullRequest
2 голосов
/ 11 ноября 2019

Я хочу удалить белую границу между черной маской и изображением тела

Примеры ввода изображения:

enter image description here

Изображениевывод с толщиной 1:

enter image description here

Вывод изображения с толщиной 2:

enter image description here

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

    thickness = 3
    image = cv2.imread('../finetune/22.png')
    blank_mask = np.zeros(image.shape, dtype=np.uint8)
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    cnts = cv2.findContours(gray, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    cnts = cnts[0] if len(cnts) == 2 else cnts[1]

    cv2.drawContours(image, cnts, -1, (255,0,0), thickness)
    cv2.imshow('image', image)
    cv2.imwrite('../finetune/22-'+str(thickness)+'r.png',image)
    cv2.waitKey()

Однако контур, который я нашел, это край черной маски, а небелая линия, которую я играл с толщиной, и она работает хорошо, но на каждом изображении этот контур отличается, также толщина не одинакова по всему рисунку

, какой самый точный способ удалить его?

Ответы [ 2 ]

0 голосов
/ 12 ноября 2019

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

Когда я использую drawContours, я могу нарисовать контуры на моемзамаскируйте и улучшите его

Так что это больше информации о моей проблеме:

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

Исходное изображение:

https://drive.google.com/open?id=1P39VCEe2FTqkD6JbdM4ueMr_71C6nI42

Маска:

https://drive.google.com/open?id=1LTHaclsDOxRJCI9t5bLg3PeanseRR9bc

Вывод:

https://drive.google.com/open?id=1-uQx77-fmMf_9qFSgNMBvo77Q6Ag8qEZ

Вот код, который я использую:

    image = cv2.imread('../finetune/1.png')
    mask = cv2.imread('../finetune/1mask.png')

    output = np.zeros(image.shape, dtype=np.uint8)

    output[np.where(mask == 255)] = image[np.where(mask == 255)]

    cv2.imshow("output",output)
    cv2.imwrite('../finetune/1.output.png',output)

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

, чтобы уточнить, я хочу улучшить маску, чтобы предотвратить появление белой границы, когда я накладываю ее на новый фон

0 голосов
/ 12 ноября 2019

Вот два метода:

Метод № 1: cv2.erode()

Вы можете использовать эрозию, чтобы размыть границыбелый объект переднего плана. По сути, идея состоит в том, чтобы выполнить двумерную свертку с ядром. Ядро может быть создано с использованием cv2.getStructuingElement(), где вы можете передать форму и размер желаемого ядра для создания. Типичные ядра: cv2.MORPH_RECT, cv2.MORPH_ELLIPSE или cv2.MORPH_CROSS. Ядро скользит по изображению, где пиксель считается 1, если все пиксели под ядром 1, в противном случае оно размыто до 0. Чистый эффект состоит в том, что все пиксели на границах будут отбрасываться в зависимости от формы и размера ядра. Толщина переднего плана уменьшается и полезна для удаления небольшого белого шума или для отделения объектов. Вы можете настроить силу эрозии с количеством итераций для выполнения.

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
erode = cv2.erode(image, kernel, iterations=1)

Метод № 1: Открытие с помощью cv2.morphologyEx()

Противоположностью эрозии является расширение, которое улучшает изображение. Как правило, набор выполняется после эрозии, чтобы «нормализовать» эффект морфологической операции. OpenCV объединяет эти шаги в одну операцию, называемую морфологическим открытием. Открытие - это еще одно название эрозии, за которой следует расширение и, как правило, дает более плавные результаты по сравнению с только эрозией.

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
opening = cv2.morphologyEx(image, cv2.MORPH_OPEN, kernel)

Результат

enter image description here

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

import cv2

image = cv2.imread('1.png')
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
opening = cv2.morphologyEx(image, cv2.MORPH_OPEN, kernel, iterations=3)

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