当前位置:   article > 正文

yolov8跟踪模式部署Ros系统上,跟踪鼠标选择的目标,实时发布目标的坐标信息(python实现)_ros2 目标跟踪

ros2 目标跟踪

具体实现:

鼠标不点击目标,不发送任何信息,图像显示的是yolov8检测目标的所有结果

鼠标点击后,跟踪鼠标选择的目标并实时循环发布目标的坐标信息,图像显示的是目标的坐标框

若选择的目标丢失在摄像头内,暂停发送坐标信息,且图像显示的是yolov8检测目标的所有结果,等待鼠标下次点击,选择目标

实现思路:

opencv调用摄像头

加载yolov8 track模式

Yolov8的results的plot()方法,绘制结果图片

给绘制的结果图片添加窗名

opencv鼠标响应函数绑定操作的窗口

编写鼠标响应的回调函数

编写选择目标框的一个算法

使用opencv在图像上画矩形框的函数 rectangle函数 使用方法见:python-opencv第五期:rectangle函数详解

发送选择目标的坐标信息,并只显示跟踪的目标的目标框

视频演示:

yolov8目标跟踪,坐标发送


代码附下,含详细注释,供大家参考学习。创作不易,如有错误,欢迎大家指正,敬请谅解。

  1. #!/usr/bin/env python
  2. import cv2
  3. from ultralytics import YOLO
  4. import numpy as np
  5. import rospy
  6. from communication_yolo.msg import yolomsg
  7. def onMouse(event, x, y, flags,param): #鼠标回调函数,每点击鼠标响应一次,所做出的动作即:选择出目标框并发送目标框的坐标信息
  8. global start_x, start_y,n,is_mouse_clicked,boxes_id
  9. start_x, start_y = -1, -1 #每次执行鼠标响应函数前,将坐标归零
  10. if event == cv2.EVENT_LBUTTONDOWN: #鼠标左键下降沿触发
  11. start_x, start_y = x, y
  12. n = chooseobj(point, start_x, start_y) #调用选择目标框函数,传入所有目标框坐标二维列表point、鼠标点击时的坐标start_x、start_y
  13. boxes_id = results[0].boxes[n].id #获取点击鼠标时,目标的id
  14. is_mouse_clicked=True #记录鼠标点击的标志,为if条件判断作准备
  15. def chooseobj(p,start_x,start_y): #选择目标框的函数,取目标框中心点与鼠标响应时坐标最短距离的目标框的编号
  16. point_center = list() #创建列表,存储计算得来的所有目标框的中心点(为一个二维的列表)
  17. i = 0
  18. while i < len(p):
  19. point_center.append([int((p[i][2] - p[i][0]) / 2 + p[i][0]), int((p[i][3] - p[i][1]) / 2 + p[i][1])]) #求各个boxes的中心点坐标,并依次赋值于列表
  20. i=i+1
  21. distance = list() #创建列表,存放各个目标框中心点距离与鼠标响应时坐标的距离
  22. m = 0
  23. while m < len(p):
  24. pixe1 = np.array([start_x, start_y]) #鼠标响应时坐标
  25. pixe2 = np.array([point_center[m][0], point_center[m][1]]) #各个目标框中心点坐标
  26. distance.append(cv2.norm(pixe1, pixe2)) #计算各个目标框中心点与鼠标响应时坐标的距离(即两个像素点的距离)
  27. m=m+1
  28. minimum = min(distance) #找各个目标框距离列表中的最小值
  29. boxes_index = distance.index(minimum) #通过列表索引,将最小值对应的列表下表返回
  30. return boxes_index
  31. rospy.init_node("yolo_ros_pub") #初始化Ros节点
  32. pub = rospy.Publisher("yolomsg",yolomsg,queue_size=10) #创建发布对象,指定发布方的话题和消息类型
  33. # Load the YOLOv8 model
  34. model = YOLO("/home/zzb/yolov8_ws/src/communication_yolo/yolov8_main/yolov8n.pt") #加载yolo的模型权重
  35. # Open the video file
  36. cap = cv2.VideoCapture(0)
  37. # Loop through the video frames
  38. #初始化参数
  39. is_mouse_clicked=False
  40. n = 0
  41. boxes_id=0
  42. while cap.isOpened():
  43. # Read a frame from the video
  44. success, frame = cap.read()
  45. if success:
  46. # Run YOLOv8 inference on the frame
  47. results = model.track(source=frame,persist=True)
  48. # 将Tensor类型的xy坐标数据转为一个二维列表,外层列表长度为识别目标boxes的个数,内层为xyxy四个目标坐标信息
  49. point = results[0].boxes.xyxy.tolist()
  50. #确保results是否有目标,且由于point 是实时刷新的,防止出现之前点击选择的n很大,而导致下面实时索引results[0].boxes[n].id时n超出范围的bug,即:使n与results的n实时绑定
  51. #且鼠标选择了目标且确保发送目标框坐标信息,是自己之前点击的id,就发送信息
  52. if n<len(point) and is_mouse_clicked and results[0].boxes[n].id == boxes_id:
  53. msg = yolomsg() #创建自定义消息的对象
  54. msg.xmin= int(point[n][0]) #赋值选择出的目标框的四个坐标信息
  55. msg.ymin = int(point[n][1])
  56. msg.xmax =int(point[n][2])
  57. msg.ymax = int(point[n][3])
  58. pub.publish(msg) #发送消息
  59. annotated_copy = frame.copy()
  60. x_min, y_min, x_max, y_max = map(int, point[n]) # Extract coordinates
  61. annotated_results = cv2.rectangle(annotated_copy, (x_min, y_min), (x_max, y_max), (0, 255, 0), 2) #opencv画矩形框的函数,根据选择的目标的坐标画矩形框
  62. cv2.imshow("YOLOv8 Inference", annotated_results)
  63. else :
  64. # Visualize the yolov8 results on the frame
  65. annotated_frame = results[0].plot() #Yolov8的results的plot()方法,绘制结果图片
  66. # Display the annotated frame
  67. cv2.imshow("YOLOv8 Inference", annotated_frame)
  68. is_mouse_clicked = False #results无目标就将鼠标点击置0等待下次点击
  69. cv2.setMouseCallback("YOLOv8 Inference", onMouse) #while循环监听opencv鼠标响应函数
  70. # Break the loop if 'q' is pressed
  71. if cv2.waitKey(1) & 0xFF == ord("q"):
  72. break
  73. else:
  74. # Break the loop if the end of the video is reached
  75. break
  76. # Release the video capture object and close the display window
  77. cap.release()
  78. cv2.destroyAllWindows()

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/732383
推荐阅读
相关标签
  

闽ICP备14008679号