【问题标题】:Improving background extraction with shiny objects (OpenCV/Python)使用闪亮对象改进背景提取(OpenCV/Python)
【发布时间】:2019-06-11 14:18:08
【问题描述】:

我一直在研究一种“有趣”的解决方案,该解决方案将来自安全摄像头的多个视频组合成一个视频,其想法是将数小时内的前景运动叠加到几秒钟内,以实现“快速预览”。感谢StephenBahramdum 让我走上了正确的道路。

该项目是open source,任何人都可以看到。到目前为止,我已经使用了以下背景提取:

  • 使用多种算法的 OpenCV 背景减法
  • 蒙版 R-CNN
  • Yolov3/TinyYolo
  • 光流
  • (我还没有尝试过检测+质心跟踪,接下来会这样做)

根据我目前的实验,OpenCV 的背景提取通常效果最好,因为它完全基于运动提取前景。加上它非常快。没错,它还可以提取移动的树叶等内容,但我们可以努力移除这些内容。

这是一个将 3 小时的视频混合到一个短视频中的示例https://youtu.be/C-mJfzvFTdg

我目前面临的挑战是,它对闪亮的物体(例如汽车)做得不好。

这是一个例子:

背景减法在为闪亮对象提取多边形方面一直表现不佳,findContours 也没有更好的表现。

我尝试了几个选项,但我目前的方法记录在 here,其要点是:

  1. 将帧转换为 HSV
  2. 移除强度(我在另一个 SO 线程中读到了这个关于闪亮对象的内容)
  3. 应用背景减法
  4. 使用 MORPH_OPEN 清除外界噪音
  5. 模糊蒙版以希望在 blob 附近连接
  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

【问题讨论】:

  • 尝试使用 createBackgroundSubtractorMOG 增加变量 int history=400。这意味着您需要更长的平均历史记录。哪辆车去那里和去那里不会持续超过 100 帧,因此它与 400 帧前的平均值相比是异常值。
  • 同时调整背景比例变量。此阈值定义组件是否足够重要以包含在背景模型中。 TB=0.9 是默认值。对于 alpha=0.001,这意味着该模式应该存在大约 105 帧,然后才被视为前景。我认为你应该尝试 bgfg 模型中的各种参数以获得完美的分割输出
  • 谢谢。我第一次尝试使用 MOG。我没有发现它可以提供改进,但我同意,使用参数可能会有所帮助。我会继续努力
  • 无论如何,有趣的项目。值得点赞

标签: python opencv


【解决方案1】:

我发现不同条件下的变化太多,无法使用 openCV 的背景提取进行预测

所以我切换到 yolov3 进行对象识别(实际上是作为一个新选项添加​​的)。虽然 TinyYOLO 非常糟糕,但 YoloV3 似乎足够了,尽管速度要慢得多。

不幸的是,鉴于 YoloV3 只处理矩形而不是主题蒙版,我不得不切换到 cv2 的 addWeighted 方法来在混合帧的顶部混合一个新对象。

示例:https://github.com/pliablepixels/zmMagik/blob/master/sample/1.gif

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-17
    • 2021-02-28
    • 1970-01-01
    • 2021-08-29
    • 2014-11-30
    • 1970-01-01
    相关资源
    最近更新 更多