注意

这是最新开发分支配套的文档,可能包含已发布版本中尚未提供的功能。如果您要查看特定版本的文档,请使用左侧的下拉菜单并选择所需要的版本。

v4l2_drm Python使用参考#

概述#

k230_v4l2_drm 是嘉楠堪智 K230 平台上 V4L2 视频采集与 DRM 显示的 Python 绑定库。它将 Linux V4L2 (Video4Linux2) 摄像头采集和 DRM (Direct Rendering Manager) 显示输出整合为统一的流水线,支持:

  • 多路摄像头采集:通过多个 context 同时采集多路视频

  • 零拷贝 DRM 显示:V4L2 buffer 直接送 DRM 显示,无需额外拷贝

  • OSD 叠加:在视频画面上叠加 ARGB8888/RGB888 图层(如检测框、文字)

  • 旋转/翻转:硬件级旋转 (0°/90°/180°/270°) 和镜像翻转

  • 裁剪/偏移:设置显示偏移和裁剪区域

  • 后台显示线程:display_start() 在后台线程持续刷新显示


快速开始#

示例1:摄像头直出显示#

最简单的模式:摄像头采集 → DRM 显示,无 AI 推理。

import time
from k230_v4l2_drm import V4l2Drm, ROTATION_0, ROTATION_90

v4l2 = V4l2Drm(context_num=1)
display_width, display_height = v4l2.drm_init()
print(f"INFO: display {display_width}x{display_height}")

# 根据显示方向自动选择旋转角度
if display_width > display_height:
    rotation = ROTATION_0
else:
    rotation = ROTATION_90

v4l2.set_context(
    index=0, device=1,
    width=max(display_width, display_height), height=min(display_width, display_height),
    format="NV12", display=True
)
v4l2.set_rotation(0, rotation)

if not v4l2.setup():
    print("Error: V4L2-DRM setup failed!")
    exit(-1)

v4l2.display_start()

try:
    while True:
        time.sleep(1)  # display_start 后台线程自动处理采集和显示,主线程休眠等待
except KeyboardInterrupt:
    print("\nStopping...")

v4l2.display_stop()
print("Done!")

示例2:AI 推理 + OSD 叠加显示#

双路 context:一路显示,一路 AI 推理,OSD 叠加检测结果。

import time
import numpy as np
import cv2
from k230_v4l2_drm import V4l2Drm, DRM_FORMAT_ARGB8888, ROTATION_0, ROTATION_90

# 创建双路实例, 启用OSD
v4l2 = V4l2Drm(context_num=2, osd=True)
display_w, display_h = v4l2.drm_init()
print(f"INFO: display {display_w}x{display_h}")

# 根据显示方向自动选择旋转角度
if display_w > display_h:
    rotation = ROTATION_0
else:
    rotation = ROTATION_90

# Context 0: 摄像头1 → 显示 (NV12)
v4l2.set_context(
    index=0, device=1,
    width=max(display_w, display_h), height=min(display_w, display_h),
    format="NV12", display=True
)

# Context 1: 摄像头2 → AI推理输入 (BG3P格式, 不显示)
v4l2.set_context(
    index=1, device=2,
    width=1280, height=720,
    format="BG3P", display=False
)

v4l2.set_rotation(0, rotation)

# 配置OSD格式
v4l2.set_osd_format(DRM_FORMAT_ARGB8888)

# 初始化流水线
if not v4l2.setup():
    print("Error: V4L2-DRM setup failed!")
    exit(-1)

v4l2.display_start()
v4l2.dump_start(index=1)  # 启动AI路采集

try:
    frame_count = 0
    fps = 0.0
    fps_start_time = time.time()

    while True:
        # 采集AI路帧
        if not v4l2.dump_frame(index=1, timeout_ms=1000):
            continue

        # 获取帧数据 (BG3P格式: shape=(3, H, W))
        frame = v4l2.get_buffer_array(index=1)

        # 释放帧缓冲区
        v4l2.dump_release(index=1)

        # AI推理 (使用nncaseruntime等)
        # results = ai_inference(frame)

        # 帧率统计
        frame_count += 1
        elapsed = time.time() - fps_start_time
        if elapsed >= 1.0:
            fps = frame_count / elapsed
            frame_count = 0
            fps_start_time = time.time()
            print(f"[{time.strftime('%H:%M:%S')}] FPS: {fps:.1f}")

        # 生成OSD图像 (ARGB8888)
        osd_img = np.zeros((min(display_w, display_h), max(display_w, display_h), 4), dtype=np.uint8)
        # 在osd_img上绘制检测框、文字等...
        # cv2.rectangle(osd_img, (x1, y1), (x2, y2), (B, G, R, A), 2)

        # 显示帧率到OSD
        cv2.putText(osd_img, f"FPS: {fps:.1f}", (10, 40),
                    cv2.FONT_HERSHEY_SIMPLEX, 1.2, (0, 255, 0, 255), 2)

        # 更新OSD显示
        v4l2.osd_update(osd_img)

except KeyboardInterrupt:
    print("\nStopping...")

v4l2.dump_stop(index=1)
v4l2.display_stop()
print("Done!")

评论列表
条评论
登录