Python-OpenCV 处理视频(五): 运动方向判断
admin
2023-07-31 01:52:44
0

注意,我使用的OpenCV 版本是 3.0, 低版本就有可能出现第一条评论里的报错

在检测出运动的物体之后,我还需要知道运动的方向,使用了上一节中的办法检测运动我发现很难去计算运动方向,开始考虑通过计算轮廓的中点的变化来实现,但是因为每次检测出得轮廓的数量不稳定,所以这个办法会让误差不可控。

这时我发现了 goodFeaturesToTrack 函数,简直是救了我,goodFeaturesToTrack 函数可以获取图像中的最大特征值的角点,以下是我的思路:

Tips: 看代码之前请先看看我下面写的实现思路,另外还有代码里的注释也对于理解代码会有所帮助

  • 对两帧图像做一个 absdiff 得到新图像。

  • 对新图像做灰度和二值化处理。

  • 使用 goodFeaturesToTrack 函数得到最大特征值的角点。

  • 计算角点的平均点,写入队列。(通过计算平均点的解决办法类似物理中刚体问题抽象成质点解决的思路)

  • 维护一个长度为 10 的队列,队列满时计算队列中数据的增减情况,来确定运动方向。

代码示例(只实现了左右移动的判断):

#!usr/bin/env python
#coding=utf-8

import cv2
import numpy as np
import Queue

camera = cv2.VideoCapture(0)
width = int(camera.get(3))
height = int(camera.get(4))

firstFrame = None
lastDec = None
firstThresh = None

feature_params = dict( maxCorners = 100,
                       qualityLevel = 0.3,
                       minDistance = 7,
                       blockSize = 7 )

lk_params = dict( winSize  = (15,15),
                  maxLevel = 2,
                  criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))

color = np.random.randint(0,255,(100,3))
num = 0

q_x = Queue.Queue(maxsize = 10)
q_y = Queue.Queue(maxsize = 10)

while True:
  (grabbed, frame) = camera.read()
  gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
  gray = cv2.GaussianBlur(gray, (21, 21), 0)

  if firstFrame is None:
    firstFrame = gray
    continue

  # 对两帧图像进行 absdiff 操作
  frameDelta = cv2.absdiff(firstFrame, gray)
  # diff 之后的图像进行二值化
  thresh = cv2.threshold(frameDelta, 25, 255, cv2.THRESH_BINARY)[1]
  # 下面的是几种不同的二值化的方法,感觉对我来说效果都差不多
  # thresh = cv2.adaptiveThreshold(frameDelta,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,\\
            # cv2.THRESH_BINARY,11,2)
  # thresh = cv2.adaptiveThreshold(frameDelta,255,cv2.ADAPTIVE_THRESH_MEAN_C,\\
  #           cv2.THRESH_BINARY,11,2)
  thresh = cv2.dilate(thresh, None, iterations=2)
  # 识别角点
  p0 = cv2.goodFeaturesToTrack(thresh, mask = None, **feature_params)
  if p0 is not None:
    x_sum = 0
    y_sum = 0
    for i, old in enumerate(p0):
      x, y = old.ravel()
      x_sum += x
      y_sum += y
    # 计算出所有角点的平均值
    x_avg = x_sum / len(p0)
    y_avg = y_sum / len(p0)
    
    # 写入固定长度的队列
    if q_x.full():
      # 如果队列满了,就计算这个队列中元素的增减情况
      qx_list = list(q_x.queue)
      key = 0
      diffx_sum = 0
      for item_x in qx_list:
        key +=1
        if key < 10:
          # 下一个元素减去上一个元素
          diff_x = item_x - qx_list[key]
          diffx_sum += diff_x
      # 加和小于0,表明队列中的元素在递增
      if diffx_sum < 0:
        print \"left\"
        cv2.putText(frame, \"some coming form left\", (100,100), 0, 0.5, (0,0,255),2)
      else:
        print \"right\"

      print x_avg
      q_x.get()
    q_x.put(x_avg)
    cv2.putText(frame, str(x_avg), (300,100), 0, 0.5, (0,0,255),2)
    frame = cv2.circle(frame,(int(x_avg),int(y_avg)),5,color[i].tolist(),-1)
  
  cv2.imshow(\"Security Feed\", frame)
  firstFrame = gray.copy()

camera.release()
cv2.destroyAllWindows()

总的来讲作为一个图像处理的小白,不断地折腾和尝试,终于搞出了自己想要的东西,OpenCV绝对是喜欢折腾的人必要掌握的一个库了,以后肯定还会继续研究这块东西。

相关内容

热门资讯

Mobi、epub格式电子书如... 在wps里全局设置里有一个文件关联,打开,勾选电子书文件选项就可以了。
定时清理删除C:\Progra... C:\Program Files (x86)下面很多scoped_dir开头的文件夹 写个批处理 定...
scoped_dir32_70... 一台虚拟机C盘总是莫名奇妙的空间用完,导致很多软件没法再运行。经过仔细检查发现是C:\Program...
500 行 Python 代码... 语法分析器描述了一个句子的语法结构,用来帮助其他的应用进行推理。自然语言引入了很多意外的歧义,以我们...
小程序支付时提示:appid和... [Q]小程序支付时提示:appid和mch_id不匹配 [A]小程序和微信支付没有进行关联,访问“小...
pycparser 是一个用... `pycparser` 是一个用 Python 编写的 C 语言解析器。它可以用来解析 C 代码并构...
微信小程序使用slider实现... 众所周知哈,微信小程序里面的音频播放是没有进度条的,但最近有个项目呢,客户要求音频要有进度条控制,所...
65536是2的几次方 计算2... 65536是2的16次方:65536=2⁶ 65536是256的2次方:65536=256 6553...
Apache Doris 2.... 亲爱的社区小伙伴们,我们很高兴地向大家宣布,Apache Doris 2.0.0 版本已于...
项目管理和工程管理的区别 项目管理 项目管理,顾名思义就是专注于开发和完成项目的管理,以实现目标并满足成功标准和项目要求。 工...