使用 OpenCV 通过 SIFT 算法进行对象跟踪

本文介绍如何使用 SIFT 算法跟踪对象

在当今世界,当涉及到对象检测和跟踪时,深度学习模型是最常用的,但有时传统的计算机视觉技术也可能有效。在本文中,我将尝试使用 SIFT 算法创建一个对象跟踪器。

为什么人们会选择使用传统的计算机视觉技术而不是深度学习?

深度学习确实很强大,但它也有一些要求。首先,必须有可用的数据。有时,为您的特定目的找到合适的数据集可能具有挑战性。获取数据后,需要对模型进行训练,这既消耗时间 又消耗计算资源

当谈到使用传统的计算机视觉技术时,您不需要数据集或模型训练。此外,在许多情况下,不需要**GPU 。**这些技术甚至可以在计算能力有限的小型设备上高效运行。

因此,如果您不想花时间在数据集收集和模型训练上,或者您缺乏训练资源,或者您根本无法访问足够的数据,那么您可以在深入研究之前考虑使用计算机视觉技术学习

在开始编码之前,我将简要解释一下SIFT 算法是什么。

什么是 SIFT 算法?

尺度不变特征变换(SIFT)是一种强大的计算机视觉算法。

  • SIFT 旨在检测描述匹配图像中的局部特征。
  • 它通过识别不随比例、旋转和照明变化而变化的独特关键点(兴趣点)来进行操作。
  • 这些关键点可以作为识别对象和模式的强大描述符。SIFT 的应用:对象识别、图像拼接、3D 建模、视频跟踪......。

SIFT 的应用:对象识别、图像拼接、3D 建模、视频跟踪......。

现在我将开始使用 OpenCV 使用 SIFT 算法创建一个对象跟踪器.

使用 SIFT 进行对象跟踪

该程序将非常简单。首先,用户将在视频的第一帧上绘制一个矩形,目标图像将放置在该矩形内。之后,SIFT算法将从该矩形中提取特征并保存。

然后视频将显示在屏幕上,SIFT 算法将应用于每一帧。对于每一帧,将比较第一帧的特征和从当前帧提取的特征,如果匹配,程序将在该公共点处画一个圆。此过程将应用于每一帧。

因此,当用户观看视频时,他们会看到每一帧中的目标对象上出现圆圈。所以它将是一个简单且相对强大的对象跟踪器

1. 创建用于跟踪的目标图像

要在目标对象周围绘制矩形,请单击鼠标右键。(将被跟踪的图像)。您可以修改代码以允许从任何帧中选择对象,而不仅仅是从第一帧中。我只是重用了以前项目中的代码,不想对其进行更改。

python 复制代码
# 导入必要的库
import cv2 
import numpy as np 
import matplotlib.pyplot as plt

# 视频路径  
video_path= "resources/plane (1).mp4" 
 video = cv2.VideoCapture(video_path) 

# 只读第一帧以绘制所需对象的矩形
ret,frame = video.read() 

# 我给出大随机数x_min 和 y_min 的数字,因为如果将它们初始化为零,则无论最小坐标都将为零
x_min,y_min,x_max,y_max= 36000 , 36000 , 0 , 0 


def  coordinat_chooser ( event,x,y,flags,param ): 
    global go , x_min , y_min, x_max , y_max 

    # 当你点击右键时,它将提供变量的坐标
    if event==cv2.EVENT_RBUTTONDOWN: 
        
        # 如果 x 的当前坐标低于 x_min 它将是新的 x_min ,同样的规则适用for y_min
        x_min= min (x,x_min) 
        y_min= min (y,y_min) 

         # 如果 x 的当前坐标高于 x_max 则为新的 x_max ,同样的规则适用于 y_max
        x_max= max (x,x_max) 
        y_max= max (y,y_max) 

        # 绘制矩形
        cv2.rectangle(frame,(x_min,y_min),(x_max,y_max),( 0 , 255 , 0 ), 1 ) 


    """
        如果你不喜欢你的矩形(也许你喜欢一些misscliks),用鼠标中键重置坐标,
        如果您按下鼠标中键,您的鼠标坐标将重置,您可以为矩形
    """提供新的2点对
    if event==cv2.EVENT_MBUTTONDOWN: 
        print ( "重置坐标data" ) 
        x_min,y_min,x_max,y_max= 36000 , 36000 , 0 , 0

 cv2.namedWindow( 'coefficient_screen' ) 
# 设置指定窗口的鼠标处理程序,在本例中为"coefficient_screen"窗口
cv2.setMouseCallback( 'coefficient_screen' , coordinat_chooser) 


while  True : 
    cv2.imshow( "coefficient_screen" ,frame) # 仅显示第一帧
    
    k = cv2.waitKey( 5 ) & 0xFF  # 绘制矩形后按 esc    
    if k == 27 : 
        cv2.destroyAllWindows() 
        break
  • 下面,我用鼠标右键为目标对象绘制了一个矩形
python 复制代码
# 获取感兴趣区域(取矩形内部)
 roi_image=frame[y_min:y_max,x_min:x_max] 

# 将 roi 转换为灰度,SIFT 算法适用于灰度图像
roi_gray=cv2.cvtColor(roi_image,cv2.COLOR_BGR2GRAY)

roi_image:简单来说就是在其周围画一个矩形得到的目标图像。

2. 寻找ROI(目标图像)的关键点

python 复制代码
# 创建 SIFT 算法对象
sift = cv2.SIFT_create() 

# 查找 roi 的关键点和描述符
keypoints_1,descriptors_1 = sift.detectAndCompute(roi_gray, None ) 

roi_keypoint_image=cv2.drawKeypoints(roi_gray,keypoints_1,roi_gray)

# 可视化关键点
plt.subplot( 121 ) 
plt.imshow(roi_gray,cmap= "gray" ) 

plt.subplot( 122 ) 
plt.imshow(roi_keypoint_image,cmap= "gray" )

3. 跟踪视频中的目标物体

python 复制代码
# 视频路径  
video_path= "resources/plane (1).mp4"  
 video = cv2.VideoCapture(video_path) 

# 匹配器对象
bf = cv2.BFMatcher() 

while  True : 
  # 读取视频
  ret,frame=video.read() 
  
  #将帧转换为灰度
  frame_gray=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY) 

  
  # 查找当前帧关键点和描述符
  keypoints_2,descriptors_2 = sift.detectAndCompute(frame_gray, None ) 

  
  """比较从    第一帧
    提取的关键点/描述符(
来自目标对象)与从当前帧中提取的内容。
   """
  匹配 =bf。match (descriptors_1,descriptors_2) 

 
 for  match  in matches: 
      # .queryIdx 和 .trainIdx 给出关键点的索引

      # .queryIdx 给出目标图像的关键点
      索引 query_idx = match .queryIdx 

      # .trainIdx 给出当前帧的关键点
      索引 train_idx = match .trainIdx 
      
      #取匹配的坐标
      pt1 = keypoints_1[query_idx].pt 

      # 当前帧关键点坐标
      pt2 = keypoints_2[train_idx].pt 
      
      # 将圆绘制到 pt2 坐标,因为 pt2 给出当前帧坐标
      cv2.circle(frame,( int (pt2[ 0 ]), int (pt2[ 1 ])), 2 ,( 255 , 0 , 0 ), 2 ) 

  # 将帧显示到屏幕
  cv2.imshow( "coordinate_screen" ,frame) 
   

  k = cv2.waitKey( 5 ) & 0xFF  #绘制矩形后按 esc    
  if k == 27 : 
      cv2.destroyAllWindows() 
      break
      
 cv2.destroyAllWindows()
相关推荐
测试杂货铺几秒前
selenium元素定位---元素点击交互异常解决方法
自动化测试·软件测试·python·selenium·测试工具·职场和发展·交互
墨绿色的摆渡人12 分钟前
用 Python 从零开始创建神经网络(三):添加层级(Adding Layers)
人工智能·python·深度学习·神经网络
nuc_baixu14 分钟前
opencv kdtree & pcl kdtree 效率对比
人工智能·opencv·计算机视觉
DbWong_091816 分钟前
langchain_chatchat+ollama部署本地知识库,联网查询以及对数据库(Oracle)数据进行查询
python·oracle·langchain·ollama
iamBailey20 分钟前
flask+vue使用jwt验证
vue.js·python·flask
学步_技术31 分钟前
自动驾驶系列—自动驾驶中的短距离感知:超声波雷达的核心技术与场景应用
人工智能·机器学习·自动驾驶·uss
凡人的AI工具箱33 分钟前
15分钟学 Go 第 54 天 :项目总结与经验分享
开发语言·人工智能·后端·算法·golang
R-sz36 分钟前
java如何利用流式计算筛选出同一天时间最新的一条数据
java·windows·python
&永恒的星河&38 分钟前
爆火的AI智能助手ChatGPT中自注意力机制的演化与优化
人工智能·chatgpt
B站计算机毕业设计超人40 分钟前
计算机毕业设计Python+CNN卷积神经网络股票预测系统 股票推荐系统 股票可视化 股票数据分析 量化交易系统 股票爬虫 股票K线图 大数据毕业设计 AI
大数据·爬虫·python·深度学习·机器学习·课程设计·数据可视化