Как удалить краевые шумы от объекта на изображении - PullRequest
0 голосов
/ 24 сентября 2018

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

Я хочу избавиться от "белого" краевого шума от маски, и я попытался использовать простой метод проверки, если значение пикселя> = 240,результат улучшается, но все еще не совершенен, как показано ниже:

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

Спасибо!

Ответы [ 2 ]

0 голосов
/ 25 сентября 2018

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

Вот результат:

enter image description here

А вот код, основанный на этом ответе :

import cv2
import numpy as np

# Create binary threshold
img = cv2.imread('shirt.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, gray = cv2.threshold(gray, 220, 255, cv2.THRESH_BINARY)

# Dilate the image to join small pieces to the larger white sections
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
gray = cv2.dilate(gray, kernel)

# Create the mask by filling in all the contours of the dilated edges
mask = np.zeros(gray.shape, np.uint8)
_, contours, _ = cv2.findContours(gray, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
    if 10 < cv2.contourArea(cnt) < 5000:
        #  cv2.drawContours(img, [cnt], 0, (0, 255, 0), 2)
        cv2.drawContours(mask, [cnt], 0, 255, -1)

# Erode the edges back to their orig. size
# Leaving this out creates a more greedy bite of the edges, removing the single strands
#  mask = cv2.erode(mask, kernel)

cv2.imwrite('im.png', img)
cv2.imwrite('ma.png', mask)

mask = cv2.cvtColor(255 - mask, cv2.COLOR_GRAY2BGR)
img = img & mask
cv2.imwrite('fi.png', img)

Этот ответ имеет преимущество в части контуровпозволяя вам сохранять белые области меньших размеров, если вы возитесь с магическим числом 10 (я предполагаю, что это может быть не единственное изображение, над которым вы хотите запустить этот код.) Если это не нужно, тогда код может бытьнамного проще, просто 1) взяв исходный порог, 2) расширив его 3) замаскировав его на исходном изображении.

0 голосов
/ 24 сентября 2018

Я бы предложил простой конвейер для удаления краевого шума:

import numpy as np
import cv2

gray = cv2.imread("t1yfp.jpg", cv2.IMREAD_GRAYSCALE)

#  eliminate white blobs
kernel = np.ones((5, 5), np.float32)/25
processedImage = cv2.filter2D(gray, -1, kernel)
gray[processedImage > 100] = 0

#  eliminate pixels with very large value
gray[gray > 230] = 0

#  eliminate last remeaning outlier white pixels
gray = cv2.medianBlur(gray, 5)



#  display result
cv2.imshow("res", gray)
cv2.waitKey(0)

После последнего шага белые пиксели внутри маски изображения также будут удалены.Вы можете использовать усредняющий фильтр для их восстановления.Вот результат:
enter image description here

...