Skip to content
On this page

视觉功能模块

初始化摄像头

初始化摄像头,并设置默认采集模式。

lua
CameraInit()
CameraInit(0, 0)       -- cached 模式
CameraInit(0, 1)       -- blocking 模式
CameraInit(0, 0, 640)  -- cached 模式,并设置正方形默认尺寸为 640

功能:初始化摄像头,开始采集画面,并配置 CameraGetLatestFrame()CameraGetLatestFrameCopy()CameraGetLatestFrameSquare()CameraGetLatestFrameSquareCopy() 的默认取帧模式。

参数

  • unused:可选,兼容旧接口的占位参数,通常传 0 或不传
  • mode:可选,采集模式,默认 0
    • 0:cached 模式。有新帧时更新内部缓存;没有新帧时返回上一次缓存帧
    • 1:blocking 模式。等待新帧,适合希望每次调用尽量拿到新画面的场景
  • square_default_size:可选,正方形取帧接口默认尺寸,默认 320

返回值:整数状态码:

  • 0:成功
  • 1:摄像头打开失败
  • 2:视频帧读取失败

示例

lua
local ret = CameraInit(0, 0, 640)
if ret == 0 then
    print("摄像头初始化成功,默认 cached 模式,正方形尺寸 640")
else
    print("摄像头初始化失败,错误码:" .. ret)
end

获取最新摄像头帧(浅拷贝)

获取摄像头最新一帧,默认使用浅拷贝,适合实时推理。

lua
CameraGetLatestFrame()
CameraGetLatestFrame(1920, 1080)

功能:设置裁切尺寸并获取摄像头最新一帧画面。尺寸只在变化时重新配置,默认 1920x1080。实际取帧方式受 CameraInit() 第二参数影响:0 为 cached,1 为 blocking。

参数

  • width:可选,裁切宽度,默认 1920
  • height:可选,裁切高度,默认 1080

返回值cv.Mat 图像对象,失败返回 nil

拷贝语义:浅拷贝。返回对象会复用内部缓存,底层图像数据也可能被后续取帧更新。适合"取图后马上推理并丢弃"的场景,不适合保存、绘制、延迟使用。

示例

lua
local frame = CameraGetLatestFrame(1920, 1080)
local results = YoloV5DetectImg(frame, 0.45, 0.25, 50)

获取摄像头新帧(normal 非阻塞)

使用原生 normal 模式采集一帧:不阻塞、不返回缓存旧帧,只在确实有新帧时返回图像。

lua
local has_frame, frame = CameraGetFrameNormal()
local has_frame, frame = CameraGetFrameNormal(1920, 1080)

功能:设置裁切尺寸并尝试获取一帧新画面。尺寸只在变化时重新配置,默认 1920x1080。该接口固定使用 normal 非阻塞模式,不受 CameraInit() 第二参数影响。

参数

  • width:可选,裁切宽度,默认 1920
  • height:可选,裁切高度,默认 1080

返回值:返回两个值:

  • has_frame:布尔值,true 表示本次拿到了新帧,false 表示当前没有新帧
  • frame:当 has_frame == true 时为 cv.Mat 图像对象;当 has_frame == false 时为 nil

拷贝语义:浅拷贝并复用内部对象。适合实时循环中"有新帧才处理"的场景;如果要保存、绘制或跨时间持有图像,建议使用深拷贝接口。

示例

lua
CameraInit(0, 0)

while true do
    local has_frame, frame = CameraGetFrameNormal(1920, 1080)
    if has_frame then
        local results = YoloV5DetectImg(frame, 0.45, 0.25, 50)
        -- 这里只处理新帧
    else
        -- 当前没有新帧,可以跳过本轮,避免重复处理旧图
    end
end

获取最新摄像头帧副本(深拷贝)

获取摄像头最新一帧的独立副本,适合保存、绘制和长期持有。

lua
CameraGetLatestFrameCopy()
CameraGetLatestFrameCopy(1920, 1080)

功能:设置裁切尺寸并获取摄像头最新一帧画面的独立副本。尺寸只在变化时重新配置,默认 1920x1080。实际取帧方式受 CameraInit() 第二参数影响:0 为 cached,1 为 blocking。

参数

  • width:可选,裁切宽度,默认 1920
  • height:可选,裁切高度,默认 1080

返回值:独立的 cv.Mat 图像对象,失败返回 nil

拷贝语义:深拷贝。每次调用都会创建独立图像对象并复制像素,适合截图保存、画框、推流、GUI 显示、延迟访问。

示例

lua
local frame = CameraGetLatestFrameCopy(1920, 1080)
cv.imwrite("frame.png", frame)

获取最新正方形摄像头帧(浅拷贝)

获取摄像头最新一帧的正方形裁剪区域,默认使用浅拷贝,适合实时 YOLO 推理。

lua
CameraGetLatestFrameSquare()
CameraGetLatestFrameSquare(640)

功能:获取摄像头最新一帧的正方形裁剪区域。实际取帧方式受 CameraInit() 第二参数影响:0 为 cached,1 为 blocking。

参数

  • size:可选,正方形裁切尺寸。不传时使用 CameraInit(0, 0, square_default_size) 的第三个参数;如果未设置,则默认 320

返回值cv.Mat 图像对象,失败返回 nil

拷贝语义:浅拷贝。返回对象会复用内部缓存,不适合保存、绘制、等待后再使用。

示例

lua
CameraInit(0, 0, 640)
local square_frame = CameraGetLatestFrameSquare()
local results = YoloV5DetectImg(square_frame, 0.45, 0.25, 50)

获取最新正方形摄像头帧副本(深拷贝)

获取摄像头最新一帧正方形裁剪区域的独立副本,适合截图、绘制、保存。

lua
CameraGetLatestFrameSquareCopy()
CameraGetLatestFrameSquareCopy(640)

功能:获取摄像头最新一帧的正方形裁剪区域,并返回独立图像副本。实际取帧方式受 CameraInit() 第二参数影响:0 为 cached,1 为 blocking。

参数

  • size:可选,正方形裁切尺寸。不传时使用 CameraInit(0, 0, square_default_size) 的第三个参数;如果未设置,则默认 320

返回值:独立的 cv.Mat 图像对象,失败返回 nil

拷贝语义:深拷贝。每次调用都会创建独立图像对象并复制像素,适合保存、画框、截图对比、推流、GUI 显示。

示例

lua
CameraInit(0, 0, 640)
local img1 = CameraGetLatestFrameSquareCopy()
local img2 = CameraGetLatestFrameSquareCopy()

cv.imwrite("img1.png", img1)
cv.imwrite("img2.png", img2)

浅拷贝和深拷贝用法说明

浅拷贝接口

  • CameraGetLatestFrame()
  • CameraGetLatestFrameSquare()

浅拷贝不会复制完整像素,只复用内部图像对象或引用当前帧数据,因此速度快、延迟低、适合实时推理。

推荐场景

  • YOLO 实时推理
  • 只使用检测坐标
  • 取图后马上处理,处理完立即丢弃
  • 高帧率循环检测

不推荐场景

  • cv.imwrite() 保存图片
  • 在图片上画框
  • sleep() 后再访问图片
  • 保存多帧做对比
  • 推流或 GUI 长时间显示

正确示例:

lua
while true do
    local img = CameraGetLatestFrameSquare()
    local results = YoloV5DetectImg(img, 0.45, 0.25, 20)
    -- 这里只使用 results,不保存 img
end

错误示例:

lua
local img1 = CameraGetLatestFrameSquare()
local img2 = CameraGetLatestFrameSquare()
sleep(2)
cv.imwrite("img1.png", img1) -- 不推荐:浅拷贝图像可能已经失效或被覆盖
cv.imwrite("img2.png", img2) -- 不推荐

深拷贝接口

  • CameraGetLatestFrameCopy()
  • CameraGetLatestFrameSquareCopy()

深拷贝会创建独立图像对象并复制像素,因此更安全,但性能开销比浅拷贝高。

推荐场景

  • 保存截图
  • YOLO 推理后画框
  • 保存检测结果图
  • 多张图片对比
  • 推流或 GUI 显示
  • 图像需要跨函数、跨时间继续使用

正确示例:

lua
local img = CameraGetLatestFrameSquareCopy(640)
local results = YoloV5DetectImg(img, 0.45, 0.25, 20)

-- 可以在 img 上绘制检测框,然后保存
cv.imwrite("detect_result.png", img)

选择建议

需求推荐接口
实时 YOLO,只拿坐标CameraGetLatestFrameSquare()
实时 YOLO,完整画面输入CameraGetLatestFrame()
保存正方形截图CameraGetLatestFrameSquareCopy()
保存完整截图CameraGetLatestFrameCopy()
YOLO 后画框并保存CameraGetLatestFrameSquareCopy()
推流或 GUI 显示CameraGetLatestFrameCopy()CameraGetLatestFrameSquareCopy()

查询摄像头数据

查询摄像头数据

lua
getCameraFormats(device_name)

功能:查询指定视频设备支持的格式、分辨率和帧率

参数

  • device_name:视频设备名称,如"video0"

返回值:支持的格式信息字符串

示例

lua
local formats = getCameraFormats("video0")
print(formats)

设置视频格式

设置视频格式

lua
setCameraFormat(device_name, width, height, format, fps)

注意:此方法必须在 初始化摄像头 前使用。

功能:设置指定视频设备的分辨率、编码格式和帧率

参数

  • device_name:视频设备名称,如"video0"
  • width:宽度分辨率
  • height:高度分辨率
  • format:视频编码格式,如"NV12"
  • fps:帧率

返回值:布尔值,表示设置是否成功

示例

lua
local ok = setCameraFormat("video0", 1920, 1080, "NV12", 60)
print("设置" .. (ok and "成功" or "失败"))

加载YoloV5模型

加载YoloV5模型

lua
YoloV5LoadModel(model_file, class_count)

功能:加载YoloV5神经网络模型

参数

  • model_file:模型文件名 可以加载rkdata和rknn模型
  • class_count:模型类别数量

返回值:整数,0表示成功,非0表示失败

注意:截图大小在推理内部始终和模型的尺寸是一致的,如果模型尺寸是320,输入的图片尺寸就是320,如果设置的截图范围小于320就放大到320,会导致识别范围较小或者是放大后失真识别不到目标。如果输入图片尺寸是640,在推理内部就会将图片缩放到模型大小为320,这样会导致损失很小的细节导致小目标无法被识别,优点是可以有更广的识别范围

示例

lua
local ret = YoloV5LoadModel("yolov5s.rknn", 2)
if ret == 0 then
    print("模型加载成功")
else
    print("模型加载失败")
end

加载YoloV8模型

加载YoloV8模型

lua
YoloV8LoadModel(model_file, class_count)

功能:加载YoloV8神经网络模型

参数

  • model_file:模型文件名 可以加载rkdata和rknn模型
  • class_count:模型类别数量

返回值:整数,0表示成功,非0表示失败

注意:截图大小在推理内部始终和模型的尺寸是一致的,如果模型尺寸是320,输入的图片尺寸就是320,如果设置的截图范围小于320就放大到320,会导致识别范围较小或者是放大后失真识别不到目标。如果输入图片尺寸是640,在推理内部就会将图片缩放到模型大小为320,这样会导致损失很小的细节导致小目标无法被识别,优点是可以有更广的识别范围

示例

lua
local ret = YoloV8LoadModel("yolov8s.rknn", 2)
if ret == 0 then
    print("模型加载成功")
else
    print("模型加载失败")
end

YoloV5目标检测

目标检测

lua
YoloV5DetectImg(image, nms_threshold, confidence_threshold, max_detections)

功能:使用YoloV5模型对图像进行目标检测

参数

  • image:输入图像(RGB888原始图像数据),opencv mat图像得通过专用函数转一下才能用
  • nms_threshold:NMS阈值,用于抑制重叠框
  • confidence_threshold:置信度阈值
  • max_detections:最大检测数量

返回值:检测到的目标数组,每个目标包含属性:

  • cls_id:目标类别ID
  • prop:目标置信度
  • box_x:框左上角X坐标
  • box_y:框左上角Y坐标
  • box_w:框宽度
  • box_h:框高度

示例

lua
local results = YoloV5DetectImg(frame, 0.45, 0.25, 100)
if results and #results > 0 then
    for i, det in ipairs(results) do
        print(string.format("目标%d: 类别=%d 置信度=%.2f 位置=(%d,%d,%d,%d)",
            i, det.cls_id, det.prop, det.box_x, det.box_y, det.box_w, det.box_h))
    end
else
    print("未检测到目标")
end

YoloV8目标检测

目标检测

lua
YoloV8DetectImg(image, nms_threshold, confidence_threshold, max_detections)

功能:使用YoloV8模型对图像进行目标检测

参数

  • image:输入图像(RGB888原始图像数据),opencv mat图像得通过专用函数转一下才能用
  • nms_threshold:NMS阈值,用于抑制重叠框
  • confidence_threshold:置信度阈值
  • max_detections:最大检测数量

返回值:检测到的目标数组,每个目标包含属性:

  • cls_id:目标类别ID
  • prop:目标置信度
  • box_x:框左上角X坐标
  • box_y:框左上角Y坐标
  • box_w:框宽度
  • box_h:框高度

示例

lua
local results = YoloV8DetectImg(frame, 0.45, 0.25, 100)
if results and #results > 0 then
    for i, det in ipairs(results) do
        print(string.format("目标%d: 类别=%d 置信度=%.2f 位置=(%d,%d,%d,%d)",
            i, det.cls_id, det.prop, det.box_x, det.box_y, det.box_w, det.box_h))
    end
else
    print("未检测到目标")
end

初始化网页预览服务

初始化网页预览服务

lua
StartMJPEGServer(port)

功能:启动MJPEG流服务器用于网页预览

参数

  • port:服务器端口(可空,默认5656,无特殊要求请勿修改)

示例

lua
StartMJPEGServer(5656)
print("预览服务已启动在端口5656")

推送图片到预览窗口

推送图片到预览窗口

lua
StreamPushFrame(frame)

功能:将图像推送到网页预览窗口

参数

  • frame:图像数据(RGB888原始图像数据),opencv mat图像得通过专用函数转一下才能用

示例

lua
local frame = CameraGetLatestFrame()
StreamPushFrame(frame)

标准模板匹配

标准模板匹配

lua
templateMatchingStandard(bigImg, smallImg, x1, y1, x2, y2, sim, multiTarget)

功能:在大图中搜索与模板图匹配的目标区域

参数

  • bigImg:大图RGB888对象(待搜索的图像)
  • smallImg:模板图RGB888对象(用于匹配的模板)
  • x1:搜索区域左上角X坐标(0表示从图像左边界开始)
  • y1:搜索区域左上角Y坐标(0表示从图像上边界开始)
  • x2:搜索区域右下角X坐标(0表示到图像右边界)
  • y2:搜索区域右下角Y坐标(0表示到图像下边界)
  • sim:相似度阈值(0.0-1.0之间的浮点数)
  • multiTarget:是否进行多目标匹配(true/false)

返回值

  • status:状态码
    • 1:匹配成功
    • 0:未找到匹配目标
    • -2:输入参数错误
    • -100:坐标无效
  • results:匹配结果数组,每个结果包含属性:
    • x:匹配区域左上角X坐标
    • y:匹配区域左上角Y坐标
    • width:匹配区域宽度
    • height:匹配区域高度
    • score:匹配相似度分数

示例

lua
-- 读取源图和模板图
local srcMat = ensure24BitBGR(imread("dt.png"))
local templateMat = ensure24BitBGR(imread("mb3.jpg"))

local status, results = templateMatchingStandard(srcMat , templateMat , 0, 0, 0, 0, 0.8, true)
if status == 1 and results and #results > 0 then
    for i, match in ipairs(results) do
        print(string.format("匹配%d: 位置=(%d,%d) 大小=(%d×%d) 相似度=%.2f",
            i, match.x, match.y, match.width, match.height, match.score))
    end
elseif status == 0 then
    print("未找到匹配目标")
elseif status == -2 then
    print("输入参数错误")
elseif status == -100 then
    print("搜索区域坐标无效")
end

多尺度单目标模板匹配

多尺度单目标模板匹配

lua
multiScaleTemplateMatching(bigImg, smallImg, x1, y1, x2, y2, scaleMin, scaleMax, scaleStep)

功能:在不同缩放尺度下搜索与模板图最匹配的单个目标

参数

  • bigImg:大图RGB888对象(待搜索的图像)
  • smallImg:模板图RGB888对象(用于匹配的模板)
  • x1:搜索区域左上角X坐标(0表示从图像左边界开始)
  • y1:搜索区域左上角Y坐标(0表示从图像上边界开始)
  • x2:搜索区域右下角X坐标(0表示到图像右边界)
  • y2:搜索区域右下角Y坐标(0表示到图像下边界)
  • scaleMin:最小缩放比例(如0.5表示缩小到50%)
  • scaleMax:最大缩放比例(如2.0表示放大到200%)
  • scaleStep:缩放步长(如0.1表示每次增加10%)

返回值

  • status:状态码(1成功,0未找到,-2输入错误,-100坐标无效)
  • results:匹配结果数组,每个结果包含属性:
    • x:匹配区域左上角X坐标
    • y:匹配区域左上角Y坐标
    • width:匹配区域宽度
    • height:匹配区域高度
    • score:匹配相似度分数

示例

lua
-- 读取源图和模板图
local srcMat = ensure24BitBGR(imread("dt.png"))
local templateMat = ensure24BitBGR(imread("mb3.jpg"))

print("【3】多尺度单目标模板匹配")

local status3, results3 = multiScaleTemplateMatching(srcMat , templateMat, 0, 0, 0, 0, 0.5, 2.0, 0.1)

if status3 == 1 and #results3 > 0 then
    local match = results3[1]
    local x, y, w, h, score = match[1], match[2], match[3], match[4], match[5]
    local scale = w / templateMat:cols()

    print(string.format("  找到匹配: 位置(%d, %d), 尺寸: %dx%d", x, y, math.floor(w), math.floor(h)))
    print(string.format("  缩放比例: %.3f, 相似度: %.4f", scale, score))

else
    print("  未找到匹配 (状态码: " .. status3 .. ")")
end

多尺度多目标模板匹配(带NMS)

多尺度多目标模板匹配(带NMS)

lua
multiScaleTemplateMatchingNMS(bigImg, smallImg, x1, y1, x2, y2, scaleMin, scaleMax, scaleStep, threshold, nmsIOU)

功能:在不同缩放尺度下搜索多个匹配目标,并使用NMS算法抑制重叠检测框

参数

  • bigImg:大图RGB888对象(待搜索的图像)
  • smallImg:模板图RGB888对象(用于匹配的模板)
  • x1:搜索区域左上角X坐标(0表示从图像左边界开始)
  • y1:搜索区域左上角Y坐标(0表示从图像上边界开始)
  • x2:搜索区域右下角X坐标(0表示到图像右边界)
  • y2:搜索区域右下角Y坐标(0表示到图像下边界)
  • scaleMin:最小缩放比例(如0.5表示缩小到50%)
  • scaleMax:最大缩放比例(如2.0表示放大到200%)
  • scaleStep:缩放步长(如0.1表示每次增加10%)
  • threshold:匹配阈值(0.0-1.0之间,高于此值才认为匹配成功)
  • nmsIOU:NMS的IOU阈值(0.0-1.0之间,用于抑制重叠框)

返回值

  • status:状态码(1成功,0未找到,-2输入错误,-100坐标无效)
  • results:匹配结果数组,每个结果包含属性:
    • x:匹配区域左上角X坐标
    • y:匹配区域左上角Y坐标
    • width:匹配区域宽度
    • height:匹配区域高度
    • score:匹配相似度分数

示例

lua
-- 读取源图和模板图
local srcMat = ensure24BitBGR(imread("dt.png"))
local templateMat = ensure24BitBGR(imread("mb3.jpg"))

print("【4】多尺度多目标模板匹配(带NMS去重)")
local status4, results4 = multiScaleTemplateMatchingNMS(
    srcMat , templateMat,
    0, 0, 0, 0,           -- 全图搜索
    0.5, 1.5, 0.025,        -- 缩放范围: 0.7~1.3, 步长0.1
    0.8,                  -- 匹配阈值
    0.3                   -- NMS IOU阈值
)

if status4 == 1 and #results4 > 0 then
    print("  找到 " .. #results4 .. " 个不重复的匹配位置")

    -- 定义多种颜色用于区分不同匹配
    local colors = {
        {255, 255, 0},  -- 青色
        {255, 0, 255},  -- 品红
        {0, 255, 255},  -- 黄色
        {255, 128, 0},  -- 橙色
        {128, 0, 255}   -- 紫色
    }

    for i = 1, #results4 do
        local match = results4[i]
        local x, y, w, h, score = match[1], match[2], match[3], match[4], match[5]
        local scale = w / templateMat:cols()

        print(string.format("    #%d: 位置(%d, %d), 尺寸: %dx%d, 缩放: %.2fx, 分数: %.4f",
                            i, x, y, math.floor(w), math.floor(h), scale, score))

        -- 循环使用颜色
        local colorIdx = ((i - 1) % #colors) + 1
        local color = colors[colorIdx]

    end

else
    print("  未找到匹配 (状态码: " .. status4 .. ")")
end