Я работаю над «забавным» решением, которое объединяет несколько видео с камеры безопасности в одно видео, идея состоит в том, чтобы наложить движение переднего плана на несколько часов на несколько секунд для «быстрого предварительного просмотра». Спасибо Стивену и Бахрамдуму за то, что вы выбрали меня на правильном пути.
Проект с открытым исходным кодом , на всеобщее обозрение. До сих пор я играл со следующими фоновыми извлечениями:
- OpenCV BackgroundSubtraction с использованием различных алгоритмов
- Маска R-CNN
- Yolov3 / TinyYolo
- Оптический поток
- (я еще не пробовал обнаружение + отслеживание центроида, сделаю это дальше)
Исходя из моих экспериментов, извлечение фона в OpenCV обычно работает лучше всего, потому что оно извлекает передний план исключительно на основе движения. Плюс это очень быстро. Правда, он также извлекает такие вещи, как перемещение листьев и т. Д., Но мы можем поработать над их удалением.
Вот пример 3-часового видео, объединенного в одно короткое видео .
https://youtu.be/C-mJfzvFTdg
Моя текущая проблема заключается в том, что он плохо справляется с блестящими объектами, такими как автомобили.
Вот пример:
![enter image description here](https://i.stack.imgur.com/tIja9.png)
Вычитание фона постоянно плохо справляется с извлечением полигонов для блестящих объектов, и findContours
тоже не лучше.
Я пробовал несколько вариантов, но мой текущий подход задокументирован здесь , суть которого:
- Конвертировать кадр в HSV
- убрать интенсивность (я читал это в другой ветке SO для блестящих объектов)
- Применить вычитание фона
- Очистить внешний шум с помощью MORPH_OPEN
- Размытая маска, которая, как мы надеемся, соединится рядом, пока капли
- найти контуры на новых масках
- сохранить только контуры определенной минимальной области
- создать новую маску, где мы рисуем только эти контуры с заливкой
- Сделайте окончательное расширение, чтобы соединить близкие заполненные контуры новых масок
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