yolov8部署ros,stream=True模式,调用摄像头发布坐标信息代码

本文介绍了如何利用Python编程实现基于YOLOv8的目标检测系统,结合ROS进行通信,用户可以通过鼠标选择并发送选定目标框的坐标。代码展示了如何处理鼠标事件,以及在视频流中实现实时目标框标注和坐标发送。
摘要由CSDN通过智能技术生成
#!/usr/bin/env python
import cv2
from ultralytics import YOLO
import numpy as np
import rospy
from communication_yolo.msg import  yolomsg
 
 
def onMouse(event, x, y, flags,param):      #鼠标回调函数,每点击鼠标响应一次,所做出的动作即:选择出目标框并发送目标框的坐标信息
    global start_x, start_y,n,is_mouse_clicked,boxes_id
    start_x, start_y = -1, -1           #每次执行鼠标响应函数前,将坐标归零
    if event == cv2.EVENT_LBUTTONDOWN:         #鼠标左键下降沿触发
        start_x, start_y = x, y
        n = chooseobj(point, start_x, start_y)           #调用选择目标框函数,传入所有目标框坐标二维列表point、鼠标点击时的坐标start_x、start_y
        boxes_id = results[0].boxes[n].id   #获取点击鼠标时,目标的id
        is_mouse_clicked=True      #记录鼠标点击的标志,为if条件判断作准备
        
 
 
def chooseobj(p,start_x,start_y):           #选择目标框的函数,取目标框中心点与鼠标响应时坐标最短距离的目标框的编号
    point_center = list()           #创建列表,存储计算得来的所有目标框的中心点(为一个二维的列表)
    i = 0
    while i < len(p): 
        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的中心点坐标,并依次赋值于列表
        i=i+1
    distance = list()       #创建列表,存放各个目标框中心点距离与鼠标响应时坐标的距离
    m = 0
    while m < len(p):
        pixe1 = np.array([start_x, start_y]) #鼠标响应时坐标
        pixe2 = np.array([point_center[m][0], point_center[m][1]]) #各个目标框中心点坐标
        distance.append(cv2.norm(pixe1, pixe2)) #计算各个目标框中心点与鼠标响应时坐标的距离(即两个像素点的距离)
        m=m+1
    minimum = min(distance)  #找各个目标框距离列表中的最小值
    boxes_index = distance.index(minimum)  #通过列表索引,将最小值对应的列表下表返回
    return boxes_index
 
rospy.init_node("yolo_ros_pub")        #初始化Ros节点
 
pub = rospy.Publisher("yolomsg",yolomsg,queue_size=10)         #创建发布对象,指定发布方的话题和消息类型
 
# Load the YOLOv8 model
model = YOLO("/home/zzb/yolov8_ws/src/communication_yolo/yolov8_main/yolov8n.pt")    #加载yolo的模型权重
# Open the video file
cap = cv2.VideoCapture(0)
# Loop through the video frames
 
#初始化参数
is_mouse_clicked=False
n = 0
boxes_id=0
 
while cap.isOpened():
    # Read a frame from the video
    success, frame = cap.read()
 
    if success:
        # Run YOLOv8 inference on the frame
        results_generator = model.track(source=frame,persist=True,stream=True)
        # 将Tensor类型的xy坐标数据转为一个二维列表,外层列表长度为识别目标boxes的个数,内层为xyxy四个目标坐标信息
        results=next(results_generator)
        point = results.boxes.xyxy.tolist()

        #确保results是否有目标,且由于point 是实时刷新的,防止出现之前点击选择的n很大,而导致下面实时索引results[0].boxes[n].id时n超出范围的bug,即:使n与results的n实时绑定
        #且鼠标选择了目标且确保发送目标框坐标信息,是自己之前点击的id,就发送信息
        if  n<len(point) and is_mouse_clicked and results.boxes[n].id == boxes_id:
            msg = yolomsg()             #创建自定义消息的对象
            msg.xmin= int(point[n][0])   #赋值选择出的目标框的四个坐标信息
            msg.ymin = int(point[n][1])
            msg.xmax =int(point[n][2])
            msg.ymax = int(point[n][3])
            pub.publish(msg) #发送消息
            annotated_copy = frame.copy()
            x_min, y_min, x_max, y_max = map(int, point[n])  # Extract coordinates
            annotated_results = cv2.rectangle(annotated_copy, (x_min, y_min), (x_max, y_max), (0, 255, 0), 2) #opencv画矩形框的函数,根据选择的目标的坐标画矩形框
            cv2.imshow("YOLOv8 Inference", annotated_results)
        else :
            # Visualize the yolov8 results on the frame
            annotated_frame = results.plot()  #Yolov8的results的plot()方法,绘制结果图片
            # Display the annotated frame
            cv2.imshow("YOLOv8 Inference", annotated_frame)
            is_mouse_clicked = False    #results无目标就将鼠标点击置0等待下次点击

        cv2.setMouseCallback("YOLOv8 Inference", onMouse)      #while循环监听opencv鼠标响应函数
 
        # Break the loop if 'q' is pressed
        if cv2.waitKey(1) & 0xFF == ord("q"):
            break
    else:
        # Break the loop if the end of the video is reached
        break
 
# Release the video capture object and close the display window
cap.release()
cv2.destroyAllWindows()

注:opencv capture.read()函数 好像是一帧一帧读取图片 会导致rtsp视频流 读取变卡 

在usb摄像头好像没有这种bug

 opencv的imshow函数 后面必须接waitkey函数  否则imshow出来是黑屏的https://zhuanlan.zhihu.com/p/251398560

https://www.volcengine.com/theme/7772002-O-7-1

  • 6
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

似苦又甜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值