物体追踪

什么是物体追踪?

简单地说,在视频的连续帧中定位对象被称为追踪。

用opencv2简单实现对象跟踪

在我们的程序中,我们要追踪一个蓝色的物体。下面就是就是我们要做的几步:
• 从视频中获取每一帧图像
• 将图像转换到 HSV 空间
• 设置 HSV 阈值到蓝色范围。
• 获取蓝色物体,当然我们还可以做其他任何我们想做的事,比如:在蓝色 物体周围画一个圈。

需要的库

  • cv2

     pip install opencv-python
    
  • numpy

代码示例

#coding:utf-8
import cv2
import numpy as np

cap = cv2.VideoCapture(0)

while(1):

    # 获取每一帧
    _, frame = cap.read()

    # 转到HSV
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

    # 设定蓝色阈值
    lower_blue = np.array([110,50,50])
    upper_blue = np.array([130,255,255])

    # 根据阈值构建掩模
    mask = cv2.inRange(hsv, lower_blue, upper_blue)

    # 对原图像和掩模进行位运算
    res = cv2.bitwise_and(frame,frame, mask= mask)
    #显示图片
    cv2.imshow('frame',frame)
    cv2.imshow('mask',mask)
    cv2.imshow('res',res)
    k = cv2.waitKey(5) & 0xFF
    #按Esc退出
    if k == 27:
        break
#关闭窗口
cv2.destroyAllWindows()

输出结果

在这里插入图片描述

函数详解

1.VideoCapture()

VideoCapture()中参数是0,表示打开笔记本的内置摄像头,参数是视频文件路径则打开视频,如cap = cv2.VideoCapture(“…/test.avi”)

2. cap.read()

功 能:返回两个值
先返回一个布尔值,如果视频读取正确,则为 True,
如果错误,则为 False,也可用来判断是否到视频末尾再返回一个值,为每一帧的图像,该值是一个三维矩阵
通用接收方法为:

ret,frame = cap.read();

这样 ret 存储布尔值,frame 存储图像
若使用一个变量来接收两个值,如

frame = cap.read()

则 frame 为一个元组,原来使用 frame 处需更改为 frame[1]
返回值:R1:布尔值
R2:图像的三维矩阵
cap = cv2.VideoCapture(0)

3. cv2.cvtColor()

opencv中颜色空间转换函数 cv2.cvtColor()

opencv中有多种色彩空间,包括 RGB、HSI、HSL、HSV、HSB、YCrCb、CIE XYZ、CIE Lab8种,使用中经常要遇到色彩空间的转化,以便生成mask图等操作。

HSV 表示hue、saturation、value
可以使用下面的色彩空间转化函数 cv2.cvtColor( )进行色彩空间的转换:

image_hsv = cv2.cvtColor(image,cv2.COLOR_BGR2HSV)
转换颜色空间

在opencv中有超过150种颜色空间转换方法(震惊-_-)
但是经常用的只有BGR-灰度图和BGR-HSV
使用函数cv2.cvtColor(input_image ,flag),flag是转换类型
BGR和灰度图的转换使用 cv2.COLOR_BGR2GRAY
BGR和HSV的转换使用 cv2.COLOR_BGR2HSV

使用如下命令可以得到可以使用的flags

import cv2
import numpy as np

flags = [i for i in dir(cv2) if i.startswith('COLOR_')]

print(flags)

HSV空间中,H表示色彩/色度,取值范围 [0,179],
S表示饱和度,取值范围 [0,255],
V表示亮度,取值范围 [0,255]。
但是不同的软件使用值不同

4. cv2.inRange

利用cv2.inRange函数设阈值,去除背景部分

mask = cv2.inRange(hsv, lower_blue, upper_blue)

函数很简单,参数有三个

第一个参数:hsv指的是原图

第二个参数:lower_blue指的是图像中低于这个lower_blue的值,图像值变为0

第三个参数:upper_blue指的是图像中高于这个upper_blue的值,图像值变为0

而在lower_red~upper_red之间的值变成255

5.图像的位运算

图像的基本运算有很多种,比如两幅图像可以相加、相减、相乘、相除、位运算、平方根、对数、绝对值等;图像也可以放大、缩小、旋转,还可以截取其中的一部分作为ROI(感兴趣区域)进行操作,各个颜色通道还可以分别提取及对各个颜色通道进行各种运算操作。总之,对于图像可以进行的基本运算非常的多,只是挑了些常用的操作详解。

bitwise_and是对二进制数据进行“与”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“与”操作,1&1=1,1&0=0,0&1=0,0&0=0
bitwise_or是对二进制数据进行“或”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“或”操作,1|1=1,1|0=0,0|1=0,0|0=0
bitwise_xor是对二进制数据进行“异或”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“异或”操作,11=0,10=1,01=1,00=0
bitwise_not是对二进制数据进行“非”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“非”操作,1=0,0=1

6.掩模详细介绍

https://blog.csdn.net/u011028345/article/details/77278467

7.

    k = cv2.waitKey(5) & 0xFF
    #按Esc退出
    if k == 27:
        break

waitKey(5) 中的数字代表等待按键输入之前的无效时间,单位为毫秒,在这个时间段内按键 ‘Esc‘ (Esc的值为27)不会被记录,在这之后按键才会被记录。
也即经过无效时间以后,检测在上一次显示图像的时间段内按键 ‘Esc’ 有没有被按下,若无则跳出if语句段,捕获并显示下一帧图像。

若此参数置零,则代表在捕获并显示了一帧图像之后,程序将停留在if语句段中一直等待 ‘Esc’ 被键入。

cv2.waitKey(1) 与 0xFF(1111 1111)相与是因为cv2.waitKey(1) 的返回值不止8位,但是只有后8位实际有效,为避免产干扰,通过 ‘与’ 操作将其余位置0。

猜你喜欢

转载自blog.csdn.net/i_m_jack/article/details/85015239