OpenCV实现对象跟踪的方法

 更新时间:2021年10月19日 00:00  点击:2034

介绍

OpenCV 是一个很好的处理图像和视频的工具。无论你是想让你的照片呈现 90 年代的黑白效果,还是执行复杂的数学运算,OpenCV 都可以随时为你服务。

如果你对计算机视觉感兴趣,则必须具备 OpenCV 的知识。该库包含 2500 多种优化算法,可用于执行各种任务。它被谷歌、微软、IBM 等许多行业巨头使用,并被广泛用于研究小组。该库支持多种语言,包括 java、c++ 和 python。

本文将向你展示如何使用 OpenCV 中的一些基本功能来执行复杂的对象跟踪任务。

对象跟踪

对象跟踪是在视频中定位移动对象的过程。你可以考虑一个足球比赛的例子。

你有正在进行的比赛的实时馈送,你的任务是随时跟踪球的位置。对于普通人来说,这项任务似乎很简单,但即使是最聪明的机器,它还是太复杂了。

你可能知道,计算机只能理解数字。它不了解图像是什么,但了解与图像相关联的像素值。在人眼看来完全相同的两个图像在计算机看来可能并不相同,因为即使像素的微小变化也会导致图片之间的差异。因为对象跟踪被认为是计算机视觉中最复杂的任务之一。虽然复杂,但也不是无法实现的。

可以使用机器学习以及基于深度学习的方法来执行对象跟踪。

一方面,深度学习方法在复杂任务上提供了更好的结果,并且非常通用,需要大量的训练数据。而基于 ML 的方法非常简单,但不是通用的。

在本文中,我们将使用基于 ML 的方法以及我们将在本文后面讨论的各种计算机视觉技术。

该技术广泛应用于监控、安全、交通监控、机器人视觉、视频通信等领域。此外,对象跟踪有几个用例,例如人群计数、自动驾驶汽车、人脸检测等。你能想出更多可以在日常生活中使用对象跟踪的示例吗?

由于现实生活中有如此多的应用,因此该领域正在进行不断的研究,以实现更高的准确性并使模型更加稳健。

对于本文,我们将使用此视频(https://drive.google.com/file/d/1N6NcFpveLQLc_DnFjfuMMvfuCMTAJRFm/view?usp=sharing)。

正如你将看到的,有一个红色的球在迷宫中移动,我们的任务是检测球的位置并找到它的质心。你还可以在背景中看到巨大的噪音(人群),使任务更具挑战性。

91d4fea877e0d3170384998316e5ebbd.jpg

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()

b6decc3fd55c1004b61e133dd4bf1c9e.jpg

(此图已调整大小)

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)

d322b9afd5f1618649233b5160acc913.jpg

(此图已调整大小)

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)

364ad9a8e21446d83e0c2124040577f0.jpg

到此这篇关于开始使用 OpenCV 进行对象跟踪的文章就介绍到这了,更多相关OpenCV 对象跟踪内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!

[!--infotagslink--]

相关文章

  • python opencv 画外接矩形框的完整代码

    这篇文章主要介绍了python-opencv-画外接矩形框的实例代码,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-09-04
  • python opencv通过4坐标剪裁图片

    图片剪裁是常用的方法,那么如何通过4坐标剪裁图片,本文就详细的来介绍一下,感兴趣的小伙伴们可以参考一下...2021-06-04
  • OpenCV如何去除图片中的阴影的实现

    这篇文章主要介绍了OpenCV如何去除图片中的阴影的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-29
  • 解决使用OpenCV中的imread()内存报错问题

    这篇文章主要介绍了解决使用OpenCV中的imread()内存报错问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-16
  • python OpenCV学习笔记

    这篇文章主要介绍了python OpenCV的相关资料,帮助大家更好的理解和学习使用python的opencv,感兴趣的朋友可以了解下...2021-03-31
  • 使用OpenCV去除面积较小的连通域

    这篇文章主要介绍了使用OpenCV去除面积较小的连通域,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-05
  • 详解pycharm的python包opencv(cv2)无代码提示问题的解决

    这篇文章主要介绍了详解pycharm的python包opencv(cv2)无代码提示问题的解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-01-29
  • 在C#中使用OpenCV(使用OpenCVSharp)的实现

    这篇文章主要介绍了在C#中使用OpenCV(使用OpenCVSharp)的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-11-15
  • C++ opencv实现车道线识别

    这篇文章主要为大家详细介绍了C++ opencv实现车道线识别,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-02-20
  • 详解opencv中画圆circle函数和椭圆ellipse函数

    这篇文章主要介绍了opencv中画圆circle函数和椭圆ellipse函数,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下...2020-05-09
  • Opencv LBPH人脸识别算法详解

    这篇文章主要为大家详细介绍了Opencv LBPH人脸识别算法的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-04-25
  • python中的opencv和PIL(pillow)转化操作

    这篇文章主要介绍了python中的opencv和PIL(pillow)转化操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-16
  • python基于opencv检测程序运行效率

    这篇文章主要介绍了python基于opencv检测程序运行效率,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-05-09
  • 浅谈OpenCV中的新函数connectedComponentsWithStats用法

    这篇文章主要介绍了浅谈OpenCV中的新函数connectedComponentsWithStats用法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-05
  • Opencv实现绿幕视频背景替换功能

    这篇文章主要为大家详细介绍了Opencv实现绿幕视频背景替换功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-04-25
  • OpenCV-Python实现凸包的获取

    凸包是一个计算几何中的概念,在图像处理过程中,我们常常需要寻找图像中包围某个物体的凸包,本文就使用OpenCV实现,感兴趣的可以了解一下...2021-06-08
  • python基于OpenCV模板匹配识别图片中的数字

    这篇文章主要介绍了python基于OpenCV模板匹配识别图片中的数字,帮助大家更好的理解和学习使用python,感兴趣的朋友可以了解下...2021-03-31
  • python-OpenCV 实现将数组转换成灰度图和彩图

    今天小编就为大家分享一篇python-OpenCV 实现将数组转换成灰度图和彩图,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-04-27
  • 使用opencv识别图像红色区域,并输出红色区域中心点坐标

    这篇文章主要介绍了使用opencv识别图像红色区域,并输出红色区域中心点坐标,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-06-03
  • Python编程OpenCV和Numpy图像处理库实现图片去水印

    这篇文章主要介绍了Python编程中如何实现图片去水印本文采用了OpenCV和Numpy的图像处理的方法来实现,文中附含详细示例代码,有需要的朋友可以借鉴参考下...2021-09-26