Как убрать фон с шумного изображения и извлечь прозрачные объекты?

У меня проблема с обработкой изображений, которую я не могу решить. У меня есть набор из 375 изображений, подобных приведенному ниже (1). Я пытаюсь удалить фон, чтобы сделать "вычитание фона" (или "извлечение переднего плана") и получить только отходы на простом фоне (черный / белый /...).

(1) Пример изображения

Я пробовал много чего, включая createBackgroundSubtractorMOG2 из OpenCV или порог. Я также попытался удалить фон пиксель за пикселем, вычтя его из переднего плана, потому что у меня есть набор из 237 фоновых изображений (2) (ковер без отходов, но который немного смещен относительно изображения с объектами). Также есть вариации яркости фоновых изображений.

(2) Пример фонового изображения

Вот пример кода, который я смог протестировать и который дает мне результаты ниже (3) и (4). Я использую Python 3.8.3.

# Function to remove the sides of the images
def delete_side(img, x_left, x_right):
    for i in range(img.shape[0]):
        for j in range(img.shape[1]):
            if j<=x_left or j>=x_right:
                img[i,j] = (0,0,0)
    return img

# Intialize the background model
backSub = cv2.createBackgroundSubtractorMOG2(history=250, varThreshold=2, detectShadows=True)

# Read the frames and update the background model
for frame in frames:
    if frame.endswith(".png"):
        filepath = FRAMES_FOLDER + '/' + frame
        img = cv2.imread(filepath)
        img_cut = delete_side(img, x_left=190, x_right=1280)
        gray = cv2.cvtColor(img_cut, cv2.COLOR_BGR2GRAY)
        mask = backSub.apply(gray)
        newimage = cv2.bitwise_or(img, img, mask=mask)
        img_blurred = cv2.GaussianBlur(newimage, (5, 5), 0)
        gray2 = cv2.cvtColor(img_blurred, cv2.COLOR_BGR2GRAY)
        _, binary = cv2.threshold(gray2, 10, 255, cv2.THRESH_BINARY)
        final = cv2.bitwise_or(img, img, mask=binary)
        newpath = RESULT_FOLDER + '/' + frame
        cv2.imwrite(newpath, final)

Меня вдохновили многие другие случаи, найденные в Stackru или других (пример: удаление пикселей размером меньше n (шум) в изображении - откройте CV python).

(3) Результат, полученный с помощью кода выше

(4) Результат при увеличении аргумента varThreshold до 10

К сожалению, на полученных снимках по-прежнему много шума.

Как новичок в "вычитании фона", у меня нет всех ключей для получения оптимального решения. Если у кого-то возникнет идея выполнить эту задачу более эффективным и чистым способом (есть ли специальный метод для обработки случая прозрачных объектов? Можно ли более эффективно устранить шум на объектах? И т. Д.), Меня интересует:) Спасибо

0 ответов

Спасибо за ответы. Для информации я просто меняю методологию и использую модель сегментации (U-Net) с двумя метками (передний план, фон) для определения фона. Работает неплохо.

Другие вопросы по тегам