OpenCV实现对象跟踪的方法
作者:woshicver 发布时间:2022-02-06 04:23:42
介绍
OpenCV 是一个很好的处理图像和视频的工具。无论你是想让你的照片呈现 90 年代的黑白效果,还是执行复杂的数学运算,OpenCV 都可以随时为你服务。
如果你对计算机视觉感兴趣,则必须具备 OpenCV 的知识。该库包含 2500 多种优化算法,可用于执行各种任务。它被谷歌、微软、IBM 等许多行业巨头使用,并被广泛用于研究小组。该库支持多种语言,包括 java、c++ 和 python。
本文将向你展示如何使用 OpenCV 中的一些基本功能来执行复杂的对象跟踪任务。
对象跟踪
对象跟踪是在视频中定位移动对象的过程。你可以考虑一个足球比赛的例子。
你有正在进行的比赛的实时馈送,你的任务是随时跟踪球的位置。对于普通人来说,这项任务似乎很简单,但即使是最聪明的机器,它还是太复杂了。
你可能知道,计算机只能理解数字。它不了解图像是什么,但了解与图像相关联的像素值。在人眼看来完全相同的两个图像在计算机看来可能并不相同,因为即使像素的微小变化也会导致图片之间的差异。因为对象跟踪被认为是计算机视觉中最复杂的任务之一。虽然复杂,但也不是无法实现的。
可以使用机器学习以及基于深度学习的方法来执行对象跟踪。
一方面,深度学习方法在复杂任务上提供了更好的结果,并且非常通用,需要大量的训练数据。而基于 ML 的方法非常简单,但不是通用的。
在本文中,我们将使用基于 ML 的方法以及我们将在本文后面讨论的各种计算机视觉技术。
该技术广泛应用于监控、安全、交通监控、机器人视觉、视频通信等领域。此外,对象跟踪有几个用例,例如人群计数、自动驾驶汽车、人脸检测等。你能想出更多可以在日常生活中使用对象跟踪的示例吗?
由于现实生活中有如此多的应用,因此该领域正在进行不断的研究,以实现更高的准确性并使模型更加稳健。
对于本文,我们将使用此视频(https://drive.google.com/file/d/1N6NcFpveLQLc_DnFjfuMMvfuCMTAJRFm/view?usp=sharing)。
正如你将看到的,有一个红色的球在迷宫中移动,我们的任务是检测球的位置并找到它的质心。你还可以在背景中看到巨大的噪音(人群),使任务更具挑战性。
1.首先,我们导入将要使用的所需库。
import numpy as np
import cv2
2.我们将定义一个函数来调整图像的大小,以便它们在足够大的情况下适合我们的屏幕。这一步是完全可选的,可以随意跳过。
def resize(img):
return cv2.resize(img,(512,512)) # arg1- input image, arg- output_width, output_height
3.你可能知道,视频是由帧组成的。帧只不过是构成整个动态画面的众多静止图像之一。下一步将使用 OpenCV 中的 VideoCapture() 函数读取这些帧,并使用 while 循环,我们可以看到帧在移动。
你可以使用将屏幕暂停 x 毫秒的 cv2.waitKey(x) 来调整视频的速度。
cap=cv2.VideoCapture(vid_file_path)
ret,frame=cap.read()
while ret==True:
ret,frame=cap.read()
cv2.imshow("frame",resize(frame))
key=cv2.waitKey(1)
if key==ord('q'):
break
cv2.waitKey(0)
cv2.destroyAllWindows()
4.现在是时候执行一些阈值和预处理了。OpenCV 读取 BGR 格式的图像,因此我们将把色彩空间从 BGR 转换为 HSV。
为什么是 HSV 而不是 BGR 或任何其他格式?
我们使用 HSV 颜色格式,因为它对外部照明的微小变化更敏感。因此,它将提供更准确的蒙版,从而获得更好的结果。
转换色彩空间后,我们要做的是过滤掉红色通道并创建一个蒙版框。
hsv 格式的红色通道出现在 [0,230,170] 到 [255,255,220] 范围内。
cap=cv2.VideoCapture(vid_file_path)
ret,frame=cap.read()
l_b=np.array([0,230,170])# lower hsv bound for red
u_b=np.array([255,255,220])# upper hsv bound to red
while ret==True:
ret,frame=cap.read()
hsv=cv2.cvtColor(frame,cv2.COLOR_BGR2HSV)
mask=cv2.inRange(hsv,l_b,u_b)
cv2.imshow("frame",resize(frame))
cv2.imshow("mask",mask)
key=cv2.waitKey(1)
if key==ord('q'):
break
cv2.waitKey(0)
cv2.destroyAllWindows()
(此图已调整大小)
5.到目前为止,我们已经创建了帧的蒙版图像,并且我们已经过滤掉了大部分噪声。接下来是获得球的边界。为此,我们将使用轮廓检测的概念。
轮廓只不过是围绕我们球的边界。值得庆幸的是,我们不必自己找到这些边界,因为 OpenCV 允许我们可以将其用于我们的目的的函数 findContours()。它需要一个蒙版图像并返回一个轮廓数组。
有关轮廓的更多信息,请访问:https://docs.opencv.org/4.5.2/d4/d73/tutorial_py_contours_begin.html
理想情况下,在我们的例子中,轮廓的值应该是 1,因为我们只有一个球,但由于有些人戴着红帽子,我们会得到不止一个。你能想出一些办法来进一步降低这种噪音吗?
为了解决这个问题,我们将使用 OpenCV 中的另一个函数 cv2.contourArea()。我们知道在蒙版图像中,球的面积最大,它的轮廓也是如此。因此,我们将得到面积最大的轮廓。
我们有球的轮廓,我们可以使用 cv2.drawContours() 函数直接绘制这些轮廓。但是对于检测任务,我们一般做的就是用一个紧密绑定的矩形来表示对象已经被检测到了。
为此,我们将使用 cv2.boundingRect() 函数。此函数将返回矩形的坐标,然后 cv2.rectangle() 函数将为我们绘制矩形。
cap=cv2.VideoCapture(vid_file_path)
ret,frame=cap.read()
l_b=np.array([0,230,170])# lower hsv bound for red
u_b=np.array([255,255,220])# upper hsv bound to red
while ret==True:
ret,frame=cap.read()
hsv=cv2.cvtColor(frame,cv2.COLOR_BGR2HSV)
mask=cv2.inRange(hsv,l_b,u_b)
contours,_= cv2.findContours(mask,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
max_contour = contours[0]
for contour in contours:
if cv2.contourArea(contour)>cv2.contourArea(max_contour):
max_contour=contour
contour=max_contour
approx=cv2.approxPolyDP(contour, 0.01*cv2.arcLength(contour,True),True)
x,y,w,h=cv2.boundingRect(approx)
cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),4)
cv2.imshow("frame",resize(frame))
cv2.imshow("mask",mask)
(此图已调整大小)
6.此外,我们可以做的是同时检测球的质心。为此,我们将使用 cv2.moments。cv2.moments 计算轮廓内像素强度的加权平均总和,因此允许从斑点中获取一些更有用的信息,如其半径、质心等。
确保在使用该函数之前将图像转换为二进制格式。你可以在这里了解更多关于时刻的信息:https://docs.opencv.org/3.4/d0/d49/tutorial_moments.html。
cap=cv2.VideoCapture(vid_file_path)
ret,frame=cap.read()
l_b=np.array([0,230,170])# lower hsv bound for red
u_b=np.array([255,255,220])# upper hsv bound to red
while ret==True:
ret,frame=cap.read()
hsv=cv2.cvtColor(frame,cv2.COLOR_BGR2HSV)
mask=cv2.inRange(hsv,l_b,u_b)
contours,_= cv2.findContours(mask,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
max_contour = contours[0]
for contour in contours:
if cv2.contourArea(contour)>cv2.contourArea(max_contour):
max_contour = contour
approx=cv2.approxPolyDP(contour, 0.01*cv2.arcLength(contour,True),True)
x,y,w,h=cv2.boundingRect(approx)
cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),4)
M=cv2.moments(contour)
来源:https://blog.csdn.net/woshicver/article/details/120681740


猜你喜欢
- MYSQL常用命令1.导出整个数据库mysqldump -u 用户名 -p --default-character-set=latin1 数
- 1 MySQL的autocommit设置MySQL默认是开启自动提交的,即每一条DML(增删改)语句都会被作为一个单独的事务进行隐式提交。如
- 本文为 djangorestframework-simplejwt 使用记录。(官方文档) 1. 安装 pip inst
- Geohash 是一种地址编码,它能把二维的经纬度编码成一维的字符串。比如,北海公园的编码是wx4g0ec1。Geohash 的原理、算法下
- 前言:看似简单的任务,往往隐藏陷阱!一个常见的任务是在一个列表上迭代,并根据条件删除一些元素。本文将展示如何完成该任务的不同方法,同时展示一
- 前言在ES6新增的数组方法中,包含了多个遍历方法,其中包含了用于筛选的filter和reducefilter主要用于筛选数组的filter方
- 微信小程序 scroll-view实现上拉加载与下拉刷新的实例实现效果图:如图,使用小程序的scroll-view实现的上拉加载数据,下拉刷
- 一般的django项目我都喜欢采用以下的文件结构,使用include的方式,实现从总的url分配给apps里面的urlExample:-pr
- MySQL 创建数据库和创建数据表MySQL 是最常用的数据库,在数据库操作中,基本都是增删改查操作,简称CRUD。在这之前,需要先安装好
- 概述os.access() 方法使用当前的uid/gid尝试访问路径。大部分操作使用有效的 uid/gid, 因此运行环境可以在 suid/
- 本文介绍我使用QQ得到服务器上回传的python代码的探索历程,面向的对象是对计算机网络有一定了解的读者。期待有兴趣的人和我一起探讨!需求来
- 前言最近在评估项目时,要开启评估平台,查看平台和保存平台,感觉非常繁琐,开发了一款可以获取评估平台数据,查看项目排期和直接保存数据到数据库的
- 本文实例讲述了Python聚类算法之DBSACN。分享给大家供大家参考,具体如下:DBSCAN:是一种简单的,基于密度的聚类算法。本次实现中
- 书接上文用Python搓一个太阳系你们要的3D太阳系3体人真的存在吗太长不看版最小势能点在由两个大质量物体构成的重力系统中,有一些特殊的区域
- 数据表都已经创建起来了,假设我们已经插入了许多的数据,我们就可以用自己喜欢的方式对数据表里面的信息进行检索和显示了,比如说:可以象下面这样把
- 通过AngularJS实现图片上传及缩略图展示示例,废话不多说了,具体如下:从项目中截出的代码HTML部分:<section>
- JavaScript中indexOf函数方法是返回 String 对象内第一次出现子字符串的字符位置。使用方法:strObj.indexOf
- 开发环境与配置win_x64Ubuntu14.04Python3.xpip安装pymysql模块直接使用pip安装 pip install
- 结合网上的资料,自己亲自的去安装了一次MySQL,安装版本是win7x64 5.7.16。在安装过程中出现并解决了如下问题:“mysql 服
- 我相信站长们做网站的最终目的还是想要获得收入的,我想象站长们大部分的都做Google的联盟的,我相信站长中大部分的人都有考虑过做英文站的,但