【发布时间】:2019-06-11 14:18:08
【问题描述】:
我一直在研究一种“有趣”的解决方案,该解决方案将来自安全摄像头的多个视频组合成一个视频,其想法是将数小时内的前景运动叠加到几秒钟内,以实现“快速预览”。感谢Stephen 和Bahramdum 让我走上了正确的道路。
该项目是open source,任何人都可以看到。到目前为止,我已经使用了以下背景提取:
- 使用多种算法的 OpenCV 背景减法
- 蒙版 R-CNN
- Yolov3/TinyYolo
- 光流
- (我还没有尝试过检测+质心跟踪,接下来会这样做)
根据我目前的实验,OpenCV 的背景提取通常效果最好,因为它完全基于运动提取前景。加上它非常快。没错,它还可以提取移动的树叶等内容,但我们可以努力移除这些内容。
这是一个将 3 小时的视频混合到一个短视频中的示例。 https://youtu.be/C-mJfzvFTdg
我目前面临的挑战是,它对闪亮的物体(例如汽车)做得不好。
这是一个例子:
背景减法在为闪亮对象提取多边形方面一直表现不佳,findContours 也没有更好的表现。
我尝试了几个选项,但我目前的方法记录在 here,其要点是:
- 将帧转换为 HSV
- 移除强度(我在另一个 SO 线程中读到了这个关于闪亮对象的内容)
- 应用背景减法
- 使用 MORPH_OPEN 清除外界噪音
- 模糊蒙版以希望在 blob 附近连接
- 在新面具上寻找轮廓
- 只保留特定最小区域的轮廓
- 创建一个新蒙版,我们只用填充绘制这些轮廓
- 进行最终膨胀以连接新蒙版的闭合填充轮廓 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
【问题讨论】:
-
尝试使用 createBackgroundSubtractorMOG 增加变量 int history=400。这意味着您需要更长的平均历史记录。哪辆车去那里和去那里不会持续超过 100 帧,因此它与 400 帧前的平均值相比是异常值。
-
同时调整背景比例变量。此阈值定义组件是否足够重要以包含在背景模型中。 TB=0.9 是默认值。对于 alpha=0.001,这意味着该模式应该存在大约 105 帧,然后才被视为前景。我认为你应该尝试 bgfg 模型中的各种参数以获得完美的分割输出
-
谢谢。我第一次尝试使用 MOG。我没有发现它可以提供改进,但我同意,使用参数可能会有所帮助。我会继续努力
-
无论如何,有趣的项目。值得点赞