English 简体中文 繁體中文 한국 사람 日本語 Deutsch русский بالعربية TÜRKÇE português คนไทย french
查看: 5|回复: 0

OpenCV | 附代码:使用 ORB 算法检测和跟踪对象

[复制链接]
查看: 5|回复: 0

OpenCV | 附代码:使用 ORB 算法检测和跟踪对象

[复制链接]
查看: 5|回复: 0

233

主题

0

回帖

709

积分

高级会员

积分
709
vhCpOQS

233

主题

0

回帖

709

积分

高级会员

积分
709
2025-2-17 09:33:13 | 显示全部楼层 |阅读模式
本文中,我将解释什么是ORB,何时应该使用它?并演示如何使用ORB创建一个对象跟踪器。文末附完整代码及C++实现。

什么是ORB?

ORB(Oriented FAST and Rotated BRIEF)是一种用于计算机视觉的特征检测和描述算法。ORB旨在高效地检测和描述图像中的关键点(图像中独特且可识别的位置),使其在对象识别、跟踪和图像拼接等各种任务中非常有用。ORB结合了FAST关键点检测和BRIEF描述符中使用的技术:FAST(来自加速段测试的特征)和BRIEF(二进制鲁棒独立基本特征)。
在解释FAST和BRIEF之前,让我们简要讨论一下关键点检测和特征描述符。关键点检测是关于在图像中找到特殊且易于识别的点,而特征描述符则为我们提供了这些点周围内容的数值摘要。
现在让我们谈谈FAST和BRIEF算法。FAST是一种基于强度的角点检测算法,用于识别关键点,而BRIEF是一种为这些关键点生成二进制特征描述符的特征描述符。

ORB
ORB的优点


  • 速度:ORB非常快,适用于实时应用。
  • 尺度不变性:ORB还具有尺度不变性,使其能够在图像中检测不同尺度的特征。这使得它对物体或场景大小的变化具有鲁棒性。
  • 旋转不变性:ORB具有旋转不变性,这意味着无论图像中的方向如何,它都能检测和匹配特征。这使得它对视角的变化具有鲁棒性。
  • ORB不像SIFT或SURF那样受专利保护(在新的OpenCV版本中,SIFT和SURF也已经开源使用了),因此你可以在商业上使用它而无需支付费用。
ORB的缺点


  • 内存消耗:尽管ORB比一些替代方案更快,但它仍然可能消耗大量内存
  • 独特性有限:ORB可能难以区分看起来相似的特征,尤其是在具有重复模式或无纹理区域的场景中

ORB
主要逻辑

FAST算法识别图像中独特且可识别的关键点,然后BRIEF算法基于这些关键点生成特征描述符。这些描述符使得能够在不同图像中匹配相似的对象。通过比较这些描述符,你可以创建自己的自定义对象跟踪器。
对象跟踪器如何工作?

想象一下,你想在视频中跟踪一架飞机。首先,获取你的目标图像(飞机)并找到其关键点和描述符。然后,对于视频的每一帧,找到关键点和描述符。接下来,将目标图像的描述符与每一帧的描述符进行比较。如果两者之间有匹配,则在相应的坐标上绘制形状。
使用ORB进行对象跟踪/检测的步骤


  • 选择一张仅包含你想要检测和跟踪的对象的图像。例如,如果你想检测一架飞机,选择一张仅包含飞机的图像。避免使用包含多个对象的图像,例如机场场景,其中可能包含人、汽车和灯光等干扰物。使用这样的图像可能会导致FAST算法检测到大量不相关的关键点,从而导致跟踪器性能不佳。
  • 选择合适图像后,FAST算法识别图像中独特且可识别的关键点,BRIEF算法基于这些关键点生成特征描述符。保存目标图像的关键点和描述符。
  • 现在读取你的视频(我将使用OpenCV),对于每一帧,将第一步中获得的描述符与当前帧中提取的描述符进行比较。如果某些描述符之间存在匹配,则在匹配描述符对应的坐标上绘制一个圆圈。
现在,我将使用OpenCV库中的ORB算法创建一个对象跟踪器,但在那之前,我有一个小提醒,你需要知道何时不应该使用ORB。
在使用ORB之前

在项目中使用ORB之前,你必须意识到一些事情。如果你想使用ORB检测或跟踪对象,背景必须清晰,例如天空或道路。如果背景杂乱,包含行人、动物或其他对象,你的算法将找到大量关键点,从而显著降低速度和FPS(每秒帧数)。这使得它在实时应用中不切实际。
使用ORB算法的对象跟踪器

(1) 安装相关库
import cv2import matplotlib.pyplot as plt import numpy as npimport time

  • 1.
  • 2.
  • 3.
  • 4.





image = cv2.imread("helicopter_roi.png")gray_image = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)rgb_image =cv2.cvtColor(image,cv2.COLOR_BGR2RGB)plt.imshow(rgb_image)

  • 1.
  • 2.
  • 3.
  • 4.






# Initiate ORBorb = cv2.ORB_create()# find the keypoints with ORBkeypoints_1, descriptors_1 = orb.detectAndCompute(gray_image, None)# draw only keypoints location,not size and orientationimg2 = cv2.drawKeypoints(rgb_image,keypoints,None,color=(0,255,0), flags=0)plt.imshow(img2)

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.






# path to video  video_path="helicopter_2.mp4"  video = cv2.VideoCapture(video_path)

  • 1.
  • 2.
  • 3.





# Initialize variables for FPS calculationt0 = time.time()n_frames = 1# Initiateorb = cv2.ORB_create()# matcher objectbf = cv2.BFMatcher()while True :# reading video     ret,frame=video.read()    if ret:          # convert frame to gray scale         frame_gray=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)        # compute the descriptors with BRIEF        keypoints_2, descriptors_2 =  orb.detectAndCompute(frame_gray, None)        """        Compare the keypoints/descriptors extracted from the         first frame(from target object) with those extracted from the current frame.        """        matches =bf.match(descriptors_1, descriptors_2)        for match in matches:            # queryIdx gives keypoint index from target image            query_idx = match.queryIdx            # .trainIdx gives keypoint index from current frame             train_idx = match.trainIdx            # take coordinates that matches            pt1 = keypoints_1[query_idx].pt            # current frame keypoints coordinates            pt2 = keypoints_2[train_idx].pt            # draw circle to pt2 coordinates , because pt2 gives current frame coordinates            cv2.circle(frame,(int(pt2[0]),int(pt2[1])),2,(255,0,0),2)        elapsed_time = time.time() - t0        avg_fps = (n_frames / elapsed_time)        print("Average FPS: " + str(avg_fps))        cv2.putText(frame, str(avg_fps) , (50,50) , cv2.FONT_HERSHEY_SIMPLEX,1,(255,0,0), 1, cv2.LINE_AA)        n_frames += 1        #cv2.putText(frame,f"FPS :{str(avg_fps)}" , (50,50) , cv2.FONT_HERSHEY_SIMPLEX,1,(255,255,0), 2, cv2.LINE_AA)        cv2.imshow("coordinate_screen",frame)         k = cv2.waitKey(5) & 0xFF # after drawing rectangle press esc           if k == 27:            cv2.destroyAllWindows()            break    else:        breakcv2.destroyAllWindows()

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.






ORB

ORB官方论文中的图像

C++实现:https://github.com/siromermer/OpenCV-Projects-cpp-python/tree/master/opencv-projects-c%2B%2B/ObjectTracking-orb
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

233

主题

0

回帖

709

积分

高级会员

积分
709

QQ|智能设备 | 粤ICP备2024353841号-1

GMT+8, 2025-3-12 19:46 , Processed in 1.046170 second(s), 29 queries .

Powered by 智能设备

©2025

|网站地图