Как получить маску переднего плана, когда уже есть фоновое изображение - PullRequest
0 голосов
/ 29 июня 2018

Я знаю, что с cv2.createBackgroundSubtractorMOG2() мы можем вычесть маску переднего плана, используя метод оценки фона, основанный на каждых 500 кадрах (по умолчанию). Но как насчет У меня уже есть фоновое изображение , и я просто хочу вычесть передний план, используя это изображение в каждом кадре? То, что я играю, выглядит так:

import numpy as np
import cv2

video = "xx.avi"
cap = cv2.VideoCapture(video)
bg = cv2.imread("bg.png")

while True:
    ret, frame = cap.read()
    original_frame = frame.copy()
    if ret:
        # get foremask?
        fgmask = frame - bg

        # filter kernel for denoising:
        kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))

        opening = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel)

        closing = cv2.morphologyEx(opening, cv2.MORPH_CLOSE, kernel)

        # Dilate to merge adjacent blobs
        dilation = cv2.dilate(closing, kernel, iterations = 2)

        # show fg:dilation
        cv2.imshow('fg mask', dilation)
        cv2.imshow('original', original_frame)
        k = cv2.waitKey(30) & 0xff
        if k == 27:
            cap.release()
            cv2.destroyAllWindows()
            break
    else:
        break

Однако я получил красочные кадров при выполнении frame = frame - bg. Как я могу получить правильную маску переднего плана?

1 Ответ

0 голосов
/ 02 июля 2018

Вы получаете цветные изображения, потому что вы вычитаете 2 цветных изображения, поэтому цвет, который вы получаете на каждом пикселе, представляет собой разницу на каждом канале (B, G и R) между обоими изображениями. Чтобы выполнить вычитание фона, как отмечает dhanushka, самый простой вариант - использовать MOG2 и переслать ему свое фоновое изображение на несколько (500) кадров, чтобы он запомнил это как фон. MOG2 предназначен для изучения изменчивости цвета каждого пикселя с помощью гауссовской модели, поэтому, если вы подаете всегда одно и то же изображение, он не будет учиться этому. Во всяком случае, я думаю, что это должно работать для того, что вы собираетесь делать. Хорошая особенность этого подхода заключается в том, что MOG2 позаботится о многих других вещах, таких как обновление модели с течением времени, работа с тенями и т. Д.

Другой вариант - реализовать собственный метод вычитания фона, как вы пытались это сделать. Поэтому, если вы хотите проверить его, вам нужно преобразовать цветное изображение fgmask во что-то, что вы можете легко портировать и решить для каждого пикселя, является ли он фоном или передним планом. Простым вариантом было бы преобразовать его в оттенки серого, а затем применить простой порог, чем ниже порог, тем более «чувствителен» ваш метод вычитания (играть со значением порога), т.е.

...
# get foremask?
    fgmask = frame - bg

    gray_image = cv2.cvtColor(fgmask, cv2.COLOR_BGR2GRAY)
    thresh = 20
    im_bw = cv2.threshold(im_gray, thresh, 255, cv2.THRESH_BINARY)[1]

    # filter kernel for denoising:
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))

    opening = cv2.morphologyEx(im_bw, cv2.MORPH_OPEN, kernel)
...
...