使用OpenCV实现道路车辆计数

点击上方“小白学视觉”,选择加"星标"或“置顶

重磅干货,第一时间送达5088e0b804da3b51279dd9b1efed29ea.png

61a25fd81d82cb88634ac8464ca756c5.png

今天,我们将一起探讨如何基于计算机视觉实现道路交通计数。

在本教程中,我们将仅使用Python和OpenCV,并借助背景减除算法非常简单地进行运动检测。

我们将从以下四个方面进行介绍:

1. 用于物体检测的背景减法算法主要思想。

2. OpenCV图像过滤器。

3. 利用轮廓检测物体。

4. 建立进一步数据处理的结构。

背景扣除算法

2ae3816d15d3b9bbcade4a79f50f19fb.png

有许多不同的背景扣除算法,但是它们的主要思想都很简单。

假设有一个房间的视频,在某些帧上没有人和宠物,那么此时的视频基本为静态的,我们将其称为背景(background_layer)。因此要获取在视频上移动的对象,我们只需要:用当前帧减去背景即可。

由于光照变化,人为移动物体,或者始终存在移动的人和宠物,我们将无法获得静态帧。在这种情况下,我们从视频中选出一些图像帧,如果绝大多数图像帧中都具有某个相同的像素点,则此将像素作为background_layer中的一部分。

我们将使用MOG算法进行背景扣除

f3490af7a1c458e323bb451aa0f60e2b.png

原始帧

代码如下所示:

import os
import logging
import logging.handlers
import random


import numpy as np
import skvideo.io
import cv2
import matplotlib.pyplot as plt


import utils
# without this some strange errors happen
cv2.ocl.setUseOpenCL(False)
random.seed(123)


# ============================================================================
IMAGE_DIR = "./out"
VIDEO_SOURCE = "input.mp4"
SHAPE = (720, 1280)  # HxW
# ============================================================================


def train_bg_subtractor(inst, cap, num=500):
    '''
        BG substractor need process some amount of frames to start giving result
    '''
    print ('Training BG Subtractor...')
    i = 0
    for frame in cap:
        inst.apply(frame, None, 0.001)
        i += 1
        if i >= num:
            return cap


def main():
    log = logging.getLogger("main")


    # creting MOG bg subtractor with 500 frames in cache
    # and shadow detction
    bg_subtractor = cv2.createBackgroundSubtractorMOG2(
        history=500, detectShadows=True)


    # Set up image source
    # You can use also CV2, for some reason it not working for me
    cap = skvideo.io.vreader(VIDEO_SOURCE)


    # skipping 500 frames to train bg subtractor
    train_bg_subtractor(bg_subtractor, cap, num=500)


    frame_number = -1
    for frame in cap:
        if not frame.any():
            log.error("Frame capture failed, stopping...")
            break


        frame_number += 1
        utils.save_frame(frame, "./out/frame_%04d.png" % frame_number)
        fg_mask = bg_subtractor.apply(frame, None, 0.001)
        utils.save_frame(frame, "./out/fg_mask_%04d.png" % frame_number)
# ============================================================================


if __name__ == "__main__":
    log = utils.init_logging()


    if not os.path.exists(IMAGE_DIR):
        log.debug("Creating image directory `%s`...", IMAGE_DIR)
        os.makedirs(IMAGE_DIR)


    main()

处理后得到下面的前景图像

0237e37c628eea260c8a9e59085a40fc.png

去除背景后的前景图像

我们可以看出前景图像上有一些噪音,可以通过标准滤波技术可以将其消除。

滤波

针对我们现在的情况,我们将需要以下滤波函数:Threshold、Erode、Dilate、Opening、Closing。

首先,我们使用“Closing”来移除区域中的间隙,然后使用“Opening”来移除个别独立的像素点,然后使用“Dilate”进行扩张以使对象变粗。代码如下:

def filter_mask(img):
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (2, 2))
    # Fill any small holes
    closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
    # Remove noise
    opening = cv2.morphologyEx(closing, cv2.MORPH_OPEN, kernel)
 
  • 9
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白学视觉

您的赞赏是我们坚持下去的动力~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值