使用 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()
相关推荐
学术 学术 Fun1 分钟前
✨ OpenAudio S1:影视级文本转语音与语音克隆Mac整合包
人工智能·语音识别
萧鼎15 分钟前
深度探索 Py2neo:用 Python 玩转图数据库 Neo4j
数据库·python·neo4j
华子w90892585931 分钟前
基于 Python Django 和 Spark 的电力能耗数据分析系统设计与实现7000字论文实现
python·spark·django
风铃喵游43 分钟前
让大模型调用MCP服务变得超级简单
前端·人工智能
旷世奇才李先生1 小时前
Pillow 安装使用教程
深度学习·microsoft·pillow
Rockson1 小时前
使用Ruby接入实时行情API教程
javascript·python
booooooty1 小时前
基于Spring AI Alibaba的多智能体RAG应用
java·人工智能·spring·多智能体·rag·spring ai·ai alibaba
PyAIExplorer1 小时前
基于 OpenCV 的图像 ROI 切割实现
人工智能·opencv·计算机视觉
风口猪炒股指标2 小时前
技术分析、超短线打板模式与情绪周期理论,在市场共识的形成、分歧、瓦解过程中缘起性空的理解
人工智能·博弈论·群体博弈·人生哲学·自我引导觉醒
ai_xiaogui2 小时前
一键部署AI工具!用AIStarter快速安装ComfyUI与Stable Diffusion
人工智能·stable diffusion·部署ai工具·ai应用市场教程·sd快速部署·comfyui一键安装