当前位置: 首页 > article >正文

用Python替代OpenMV IDE显示openmv USB 图像

原理是利用openmv的usb模仿串口,然后用Python代码打开串口接收

能替代openmv ide 跑48帧图像

Python端需要的依赖:

需要的是:
from ultralytics import YOLO
import cv2
import numpy as np
from serial import Serial
import time
from collections import deque

pyserial              3.5

numpy                 2.0.2

ultralytics           8.3.67 

opencv-contrib-python 4.11.0.86
opencv-python         4.11.0.86

Python端代码:

from ultralytics import YOLO
import cv2
import numpy as np
from serial import Serial
import time
from collections import deque

# 配置参数
SERIAL_PORT = 'COM25'  # 串口号(Windows)
BAUD_RATE = 1  # 波特率
HEADER = b'\xAA\x55\xAA\x55'  # 帧头
HEADER_LEN = len(HEADER)  # 帧头长度
FPS_WINDOW_SIZE = 30  # 计算FPS的窗口大小(帧数)

# 初始化YOLO模型
model = YOLO('yolov8n.pt')  # 确认模型路径正确

# 性能统计变量
fps_queue = deque(maxlen=FPS_WINDOW_SIZE)  # 存储时间戳用于计算FPS
serial_read_time = 0.0  # 串口读取耗时
inference_time = 0.0  # 推理耗时


def find_header(ser):
    """同步数据流,找到帧头位置"""
    buffer = bytearray()
    while True:
        byte = ser.read(1)
        if not byte:
            continue
        buffer += byte
        if len(buffer) >= HEADER_LEN and buffer[-HEADER_LEN:] == HEADER:
            return
        elif len(buffer) > 100:
            buffer.clear()


def draw_stats(img, fps, srt, inf_t):
    """在图像上绘制性能统计信息"""
    cv2.putText(img, f"FPS: {fps:.1f}", (10, 30),
                cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
    cv2.putText(img, f"Serial: {srt:.1f}ms", (10, 60),
                cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 1)
    cv2.putText(img, f"Inference: {inf_t:.1f}ms", (10, 90),
                cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 1)
    return img


try:
    ser = Serial(SERIAL_PORT, BAUD_RATE, timeout=0.1)
    print(f"Connected to {SERIAL_PORT}")

    while True:
        frame_start = time.perf_counter()

        # 步骤1:同步到帧头
        find_header(ser)

        # 步骤2:读取图像大小
        size_bytes = ser.read(4)
        if len(size_bytes) != 4:
            continue

        # 步骤3:读取图像数据
        size = int.from_bytes(size_bytes, 'little')
        img_bytes = bytearray()
        read_start = time.perf_counter()
        while len(img_bytes) < size:
            remaining = size - len(img_bytes)
            img_bytes += ser.read(remaining)
        serial_read_time = (time.perf_counter() - read_start) * 1000  # ms

        # 解码图像
        decode_start = time.perf_counter()
        img = cv2.imdecode(np.frombuffer(img_bytes, np.uint8), cv2.IMREAD_COLOR)
        if img is None:
            continue

        # YOLO推理
        inference_start = time.perf_counter()
        # results = model(img, show=False, verbose=False)  # 关闭冗余输出
        inference_time = (time.perf_counter() - inference_start) * 1000  # ms

        # 计算FPS
        fps_queue.append(frame_start)
        if len(fps_queue) > 1:
            fps = len(fps_queue) / (fps_queue[-1] - fps_queue[0])
        else:
            fps = 0

        # 绘制统计信息
        # annotated_img = results[0].plot()
        annotated_img = draw_stats(img, fps, serial_read_time, inference_time)

        # 显示结果
        cv2.imshow('YOLO Detection', annotated_img)

        # 退出检测
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

except KeyboardInterrupt:
    print("User interrupted.")
except Exception as e:
    print(f"Error: {e}")
finally:
    ser.close()
    cv2.destroyAllWindows()
    print("Resources released.")

把openmv代码作为main放到openmv里然后断开连接重新连接,并且一定要保证openmv  ide连不到openmv

openmv端代码:

import sensor, image, time, pyb

# 摄像头初始化
sensor.reset()
sensor.set_pixformat(sensor.JPEG)    # 设置JPEG压缩模式
sensor.set_framesize(sensor.QVGA)    # 分辨率320x240(可调整)
sensor.set_quality(80)               # 压缩质量(0-100,越高越清晰)
sensor.skip_frames(time=2000)        # 等待摄像头稳定

usb = pyb.USB_VCP()                  # USB虚拟串口对象
HEADER = b'\xAA\x55\xAA\x55'         # 帧头标识(4字节)

while True:
    try:
        img = sensor.snapshot()
        img_bytes = img.bytearray()  # 获取JPEG图像字节流

        # 发送数据包格式:[帧头(4字节) + 图像大小(4字节) + 图像数据]
        usb.write(HEADER)                            # 1. 发送帧头
        usb.write(len(img_bytes).to_bytes(4, 'little'))  # 2. 发送图像大小(小端序)
        usb.write(img_bytes)                         # 3. 发送图像数据

        time.sleep_ms(1)  # 控制帧率(约20FPS,根据实际调整)

    except Exception as e:
        print("OpenMV Error:", e)
        break


http://www.kler.cn/a/530027.html

相关文章:

  • day6手机摄影社区,可以去苹果摄影社区学习拍摄技巧
  • Oracle数据库高效管理与优化实践
  • 深入解析 CSS 中不常用属性及其相互作用
  • python实现金属杆与圆形纸片运动模拟
  • 药店药品销售管理系统的设计与实现
  • MySQL高可用
  • vscode+vue3+高得地图开发过过程中本地视频及地图json文件的发布问题
  • 算法题(55):用最少数量的箭引爆气球
  • 【贪心算法篇】:“贪心”之旅--算法练习题中的智慧与策略(二)
  • DeepSeek R1 简易指南:架构、本地部署和硬件要求
  • 软件工程概论试题五
  • Visual Basic语言的云计算
  • 设计模式-创建型模式-建造者模式
  • 【单层神经网络】基于MXNet的线性回归实现(底层实现)
  • 【华为OD-E卷 - 最大矩阵和 100分(python、java、c++、js、c)】
  • Mac上有哪些好用的开源粘贴板app
  • TB6600和DM542C两种常见的步进电机驱动器
  • 数据库安全管理中的权限控制:保护数据资产的关键措施
  • 实战:如何利用网站日志诊断并解决收录问题?
  • c++可变参数详解
  • 前端知识速记--HTML篇:src和href
  • 【4】阿里面试题整理
  • Joplin 插件在Vscode中无法显示图片
  • UE5 蓝图学习计划 - Day 6:角色蓝图
  • Observability:实现 OpenTelemetry 原生可观察性的商业价值
  • Python面试宝典13 | Python 变量作用域,从入门到精通