Как убрать изменяющийся фон из видео в Python с помощью opencv2? - PullRequest
0 голосов
/ 02 февраля 2020

У меня возникла проблема с тем, как удалить изменяющийся фон из видео. Это фоновое изображение в моем видео: background1

Но фон постепенно будет становиться все ярче и ярче, так как цель, которую я хочу, выглядит следующим образом: background2(no target)

Это изображение цели, и фон становится более ярким

bakground3(The target appears and background become more bright)

Это изображение, которое является целью самый видимый и самый яркий фон

the target is most visible and the background is almost the brightest

Все, что я знаю, это то, что форма объекта, который я пытаюсь выделить, - это круг. Это становится эллипсом, потому что экран наклонен под углом 45 градусов. И круг не в центре экрана. Я хочу удалить изменяющийся фон и получить границу целевого объекта. Я пробовал KNN, и мой код выглядит следующим образом:

import cv2

# video path
datapath = "E:/pythonAPP/"
bs = cv2.createBackgroundSubtractorKNN(detectShadows=False)  
# number of frame
history = 1
bs.setHistory(history)
frames = 0
camera = cv2.VideoCapture(datapath + "data3.mp4")
count = 0

while True:
    ret, frame = camera.read()  
    if ret == True:

        fgmask = bs.apply(frame)
        if frames < history:
            frames += 1
            continue

        print('Read a new frame: ', ret)

        th = cv2.threshold(fgmask.copy(), 244, 255, cv2.THRESH_BINARY)[1]

        th = cv2.erode(th, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3)), iterations=1)
        dilated = cv2.dilate(th, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (8, 3)), iterations=1)
        # Draws the foreground image detection box
        contours, hier = cv2.findContours(dilated, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        for c in contours:

            if cv2.contourArea(c) > 1000:

                (x, y, w, h) = cv2.boundingRect(c)
                cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 255, 0), 2)
        cv2.imwrite("frame%d.jpg" % count, fgmask)  # save images
        # show
        cv2.imshow("mog", fgmask)
        cv2.imshow("thresh", th)
        cv2.imshow("diff", frame & cv2.cvtColor(fgmask, cv2.COLOR_GRAY2BGR))
        cv2.imshow("detection", frame)
        count += 1
        if cv2.waitKey(100) & 0xFF == ord('q'):
            break
    else:
        break
camera.release()
cv2.destroyAllWindows()

Но он работает не очень хорошо. Это изображение моего результата:

KNN result1 KNN result2

Кроме того, поскольку самая яркая часть видео имеет серый цвет значение 255, существует некоторая область Балька разделенного объекта. Это не имеет значения, мне нужна только граница объекта.

По сравнению с исходным изображением, вы можете увидеть, что граница результата меньше, чем один на картинке. И граница результата не очень ясна.

Я не знаю, как решить эту проблему. Есть ли лучший способ или алгоритм, чтобы понять, что я хочу сделать? Спасибо!

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