Как избежать утечки цвета при извлечении переднего плана? - PullRequest
0 голосов
/ 27 мая 2019

Мне нужно извлечь передний план из статического, известного фона (на моей веб-камере). Прямо сейчас я получаю средневзвешенное значение, используя первые 30 кадров фона, используя cv2.accumulateWeighted (), а затем сравниваю текущий кадр с фоном. (Все в оттенках серого)

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

код

def getBackground(gray, aWeight=0.2):

    global bg

    if bg is None:
        bg = gray.copy().astype(float)
        return

    cv2.accumulateWeighted(gray, bg, aWeight)

def extractForeground(gray, threshold=25):
    global bg

    diff = cv2.absdiff(bg.astype('uint8'), gray)

    thresholded = cv2.threshold(diff,
                                threshold,
                                255,
                                cv2.THRESH_BINARY)[1]

    kernel = np.ones((3,3),np.uint8)

    thresholded = cv2.erode(thresholded,kernel,iterations = 2)
    thresholded = cv2.dilate(thresholded,kernel,iterations = 2)


    return thresholded

#global
bg = None

cap = cv2.VideoCapture(0)
numFrames = 0


while True:

    ret,frame = cap.read()
    frame = imutils.resize(frame, width = 700)

    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    if (numFrames<30):
        getBackground(gray)

    else:
        fg = extractForeground(gray)

    numFrames += 1

    if cv2.waitKey(1) & 0xFF == ord('q'):
    break

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

Заранее спасибо

1 Ответ

0 голосов
/ 27 мая 2019

Попробуйте использовать Gaussian Blur с изображением в градациях серого, прежде чем передавать его на передний план. Я обычно использую ядро ​​(15,15), затем настраиваю его, чтобы увидеть, дает ли оно лучшие результаты. Другой подход - попытаться извлечь фон, используя несколько изображений:

  1. Используйте вашу функцию extractForeground, чтобы получить область с передним планом. Затем замените пиксели переднего плана на np.nan.
  2. После сохранения нескольких изображений добавьте их в пакет из n изображений. Пример: (n, image.shape). Затем используйте np.nanmean для вычисления среднего фона (nanmean рассчитывает средний пиксель, но не тот, который имеет значение np.nan) => U, чтобы получить фон без переднего плана.
  3. Возьмите следующее изображение и абсдиф со средним фоном, чтобы получить передний план.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...