opencv--动体追踪

物体运动检测的一个思想流程以及实现

直接上代码

# coding: utf-8
import cv2
import psutil
import threading

video = cv2.VideoCapture(0)
# video = cv2.VideoCapture(r'E:\AIcamera\6773897721212085802.MP4')
# KNN背景分割器,设置阴影检测
background = None
while True:
    # 读取视频每一帧
    ret, frame = video.read()
    #将第一帧作为背景图像
    if background is None:
        background = frame
        continue
    frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    background_gray = cv2.cvtColor(background, cv2.COLOR_BGR2GRAY)
    cv2.imshow('frame-gray', frame_gray)
    cv2.imshow('background-gray', background_gray)
    #图像与背景做减法
    diff = cv2.absdiff(frame_gray, background_gray)
    cv2.imshow('diff', diff)
    #求做了减法之后的二值化处理
    threshold = cv2.threshold(diff, 20, 255, cv2.THRESH_BINARY)[1]
    cv2.imshow('threshold', threshold)
    #图像腐蚀滤波降噪----取出图像中的小噪点,使得颜色更加突出
    """
    src	输入的图像名字;信道的数目可以是任意的,但深度应该是cv_8u、cv_16u、cv_16、cv_32f或cv_64f。
    dst	输出与输入相同大小和类型的图像.
    kernel	用于侵蚀的结构元素;如果元素=mat(),则使用3 x 3矩形结构元素。可以使用getStructuringElement来创建结构元素。。
    anchor	结构元素的锚点位置,默认值value(-1,-1)表示锚点位于结构元素中心
    iterations	腐蚀操作被递归执行的次数
    borderType	推断边缘类型,可参考BorderTypes
    borderValue	在边框不变的情况下的边界值
    
    getStructuringElement()
    矩形:MORPH_RECT;
    交叉形:MORPH_CROSS;
    椭圆形:MORPH_ELLIPSE;
    第二和第三个参数分别是内核的尺寸以及锚点的位置。一般在调用erode以及dilate函数之前,先定义一个Mat类型的变量来获得
    """
    kernel_ercode = cv2.getStructuringElement(cv2.MORPH_RECT,(11, 11))
    kernel_dilate = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
    # ercode = cv2.erode(threshold, None)
    # cv2.imshow('ercode', ercode)

    #高斯平滑滤波
    gas = cv2.GaussianBlur(threshold, (25, 25), 0)
    cv2.imshow('gas', gas)
    #膨胀图像
    dilate = cv2.dilate(gas, kernel_dilate, iterations=5)
    cv2.imshow('dilate', dilate)

    #查找轮廓并且绘制出轮廓
    contours, hierarchy = cv2.findContours(diff.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    for c in contours:
        if cv2.contourArea(c) > 2500:
            # 绘制目标矩形框
            (x, y, w, h) = cv2.boundingRect(c)
            cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 255, 0), 2)
    cv2.imshow('frame', frame)


    if cv2.waitKey(10) & 0xff == ord('q'):
        break

video.release()
cv2.destroyAllWindows()

使用KNN算法做物体运动检测

可参考此文章:
https://rinetd.gitlab.io/language/python/opencv/opencv-erode-dilate/

“”“
知识点:
腐蚀 :
腐蚀操作会把前景物体的边缘腐蚀掉。原理是卷积核沿着图像滑动,如果与卷积核对应的原图像像素值都是1,那么中心元素保持原值,否则为0.
效果,靠近前景的像素被腐蚀为0,前景物体变小,图像白色区域减少,对于去除白噪声很有用,可以断开两个连接在一起的物体。

膨胀 :
与腐蚀相反,卷积核当中只要有一个值是1,中心元素值就是1。此操作会增加前景中的白色区域,一般在去噪声的时候都是先腐蚀再膨胀,腐蚀的过程会使得前景变小,使用膨胀操作使前景变换回来。膨胀也可以使相互分离的物体连接。

腐蚀的作用是消除物体的边界点,使目标缩小,这个根据操作的过程可以显然的想到,物体的边界处像素值肯定是有01,腐蚀操作后这些紧邻着为1的像素点都会变成0,所以腐蚀操作会消除那些小的且无意义的物体,使边界向内部收缩的过程。
相反,膨胀(dilate)的作用当然是使目标增大,填充物体内细小的空洞,并且平滑物体的边界,边界向外部扩张的作用。

开运算是先腐蚀(erode)后膨胀(dilate)的过程,可以消除图像上细小的噪声,并平滑物体的边界

闭运算是先膨胀(dilate)后腐蚀(erode)的过程,可以填充物体内细小的空洞,并平滑物体边界
”“”
import cv2

# 获取视频
video = cv2.VideoCapture(0)
# video = cv2.VideoCapture(r'E:\AIcamera\6773897721212085802.MP4')
# KNN背景分割器,设置阴影检测
bs = cv2.createBackgroundSubtractorKNN(detectShadows=True)

while True:
    # 读取视频每一帧
    ret, frame = video.read()
    # 计算视频的前景掩码
    fgmask = bs.apply(frame)
    # 图像阈值化
    th = cv2.threshold(fgmask.copy(), 244, 255, cv2.THRESH_BINARY)[1]
    erode = cv2.erode(th, (21, 21), iterations=1)
    # 膨胀图像,减少错误
    dilated = cv2.dilate(erode, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5)), iterations=2)

    # 得到图像中的目标轮廓
    contours, hier = cv2.findContours(dilated, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    for c in contours:
        if cv2.contourArea(c) > 1500:
            # 绘制目标矩形框
            (x, y, w, h) = cv2.boundingRect(c)
            cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 255, 0), 2)

    # 显示差异视频
    cv2.imshow('mog', fgmask)
    cv2.imshow('thresh', th)
    cv2.imshow('erode', erode)
    cv2.imshow('dilated', dilated)
    # 显示检测视频
    cv2.imshow('detection', frame)
    if cv2.waitKey(10) & 0xff == ord('q'):
        break

video.release()
cv2.destroyAllWindows()
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值