Улучшение извлечения фона с блестящими объектами (OpenCV / Python) - PullRequest
1 голос
/ 11 июня 2019

Я работаю над «забавным» решением, которое объединяет несколько видео с камеры безопасности в одно видео, идея состоит в том, чтобы наложить движение переднего плана на несколько часов на несколько секунд для «быстрого предварительного просмотра». Спасибо Стивену и Бахрамдуму за то, что вы выбрали меня на правильном пути.

Проект с открытым исходным кодом , на всеобщее обозрение. До сих пор я играл со следующими фоновыми извлечениями:

  • OpenCV BackgroundSubtraction с использованием различных алгоритмов
  • Маска R-CNN
  • Yolov3 / TinyYolo
  • Оптический поток
  • (я еще не пробовал обнаружение + отслеживание центроида, сделаю это дальше)

Исходя из моих экспериментов, извлечение фона в OpenCV обычно работает лучше всего, потому что оно извлекает передний план исключительно на основе движения. Плюс это очень быстро. Правда, он также извлекает такие вещи, как перемещение листьев и т. Д., Но мы можем поработать над их удалением.

Вот пример 3-часового видео, объединенного в одно короткое видео . https://youtu.be/C-mJfzvFTdg

Моя текущая проблема заключается в том, что он плохо справляется с блестящими объектами, такими как автомобили.

Вот пример:

enter image description here

Вычитание фона постоянно плохо справляется с извлечением полигонов для блестящих объектов, и findContours тоже не лучше.

Я пробовал несколько вариантов, но мой текущий подход задокументирован здесь , суть которого:

  1. Конвертировать кадр в HSV
  2. убрать интенсивность (я читал это в другой ветке SO для блестящих объектов)
  3. Применить вычитание фона
  4. Очистить внешний шум с помощью MORPH_OPEN
  5. Размытая маска, которая, как мы надеемся, соединится рядом, пока капли
  6. найти контуры на новых масках
  7. сохранить только контуры определенной минимальной области
  8. создать новую маску, где мы рисуем только эти контуры с заливкой
  9. Сделайте окончательное расширение, чтобы соединить близкие заполненные контуры новых масок 10. Используйте эту новую маску, чтобы извлечь передний план из кадра и наложить его на текущее смешанное видео

У кого-нибудь есть предложения по улучшению извлечения отражающих объектов?

 self.fgbg = cv2.createBackgroundSubtractorMOG2(detectShadows=False,    
    history=self.history) 
    frame_hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
    frame_hsv[:,:,0] = 0 # see if removing intensity helps
   # gray = cv2.cvtColor(frame_hsv, cv2.COLOR_BGR2GRAY)

    # create initial background subtraction
    frame_mask = self.fgbg.apply(frame_hsv)
    # remove noise
    frame_mask = cv2.morphologyEx(frame_mask, cv2.MORPH_OPEN, self.kernel_clean)
    # blur to merge nearby masks, hopefully
    frame_mask = cv2.medianBlur(frame_mask,15)
    #frame_mask = cv2.GaussianBlur(frame_mask,(5,5),cv2.BORDER_DEFAULT)
    #frame_mask = cv2.blur(frame_mask,(20,20))

    h,w,_ = frame.shape
    new_frame_mask = np.zeros((h,w),dtype=np.uint8)
    copy_frame_mask = frame_mask.copy()
    # find contours of mask
    relevant = False
    ctrs,_ =  cv2.findContours(copy_frame_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    rects = []
    # only select relevant contours 
    for contour in ctrs:
        area = cv2.contourArea(contour)
        if area >= self.min_blend_area:
            x,y,w,h = cv2.boundingRect(contour)
            pts = Polygon([[x,y], [x+w,y], [x+w, y+h], [x,y+h]])
            if g.poly_mask is None or g.poly_mask.intersects(pts):
                relevant = True
                cv2.drawContours(new_frame_mask, [contour], -1, (255, 255, 255), -1)
                rects.append([x,y,w,h])

    # do a dilation to again, combine the contours
    frame_mask = cv2.dilate(new_frame_mask,self.kernel_fill,iterations = 5)
    frame_mask = new_frame_mask

1 Ответ

0 голосов
/ 13 июня 2019

Я нашел слишком много вариаций в различных условиях, чтобы иметь что-то предсказуемое, используя извлечение фона openCV

Итак, я переключился на yolov3 для идентификации объекта (на самом деле добавил его как новую опцию). В то время как TinyYOLO был довольно ужасен, YoloV3 кажется адекватным, хотя и намного медленнее.

К сожалению, учитывая, что YoloV3 делает только прямоугольные, а не предметные маски, мне пришлось переключиться на addWeighted метод cv2, чтобы смешать новый объект поверх смешанного фрейма.

Пример: https://github.com/pliablepixels/zmMagik/blob/master/sample/1.gif

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