当前位置:首页 > 工业控制 > 工业控制
[导读]工业相机画面叠加测量数据,最容易写成“OpenCV imshow加putText”样——开发机上看没问题,上嵌入式平台直接掉到个位数帧率。根因是视频解码/格式转换和文字渲染全挤在CPU一条线上,还没做硬件图层分离。正经做法是视频走视频层、文字框线走OSD层,显示控制器做硬件混合,两边只在“同一帧时间戳”上对齐。


工业相机画面叠加测量数据,最容易写成“OpenCV imshow加putText”样——开发机上看没问题,上嵌入式平台直接掉到个位数帧率。根因是视频解码/格式转换和文字渲染全挤在CPU一条线上,还没做硬件图层分离。正经做法是视频走视频层、文字框线走OSD层,显示控制器做硬件混合,两边只在“同一帧时间戳”上对齐。

一、采集与显示解耦

GigE/USB3 Vision相机先过厂商SDK或Aravis取流,V4L2子系统走REQBUFS+mmap拿DMA缓冲。

ioctl(fd, VIDIOC_REQBUFS, &req);   // DMA缓冲

for(i=0;i<req.count;i++){

   ioctl(fd, VIDIOC_QUERYBUF, &buf);

   map[i] = mmap(...);

   ioctl(fd, VIDIOC_QBUF, &buf);   // 还回队列

}

ioctl(fd, VIDIOC_STREAMON, &type);

采集线程只做“取帧→丢给显示层→还缓冲”,不在这里画框、不在这里跑算法。测量算法另起线程,结果写共享结构体带帧序号。

二、双图层:视频层+OSD层

小项目可以fb0叠加凑合,但1080p以上CPU转YUYV→RGB会爆。量产走DRM Plane:

Plane 0(视频层):相机YUV帧,dma-buf零拷贝送入

Plane 1(OSD层):ARGB8888透明图层,画框/文字/数值

Z-order和Global Alpha由显示控制器混合输出

/* OSD层只更新变化区 */

drmModeSetPlane(drm_fd, osd_plane, crtc,

   osd_bo_handle, 0,

   x, y, w, h,         // 目标位置

   0,0,w<<16,h<<16);

OSD缓冲用ARGB,文字区域alpha=255,空白区alpha=0,硬件混合时不影响视频层。

三、测量数据绑定帧时间戳

叠加错位大多不是画歪了,是“新数据套旧帧”。规则:

相机每帧带硬件时间戳(GigE走PTP或SDK取帧时间)

算法结果结构带frame_id

OSD刷新时取“当前显示帧对应frame_id的最新结果”

没新结果就沿用上一帧标注,不清屏

typedef struct {

   uint64_t frame_id;

   uint64_t ts_ns;

   float    width_mm;

   float    pos_x, pos_y;     // 像素坐标

   uint8_t  ok;

} meas_t;


meas_t latest;                // 算法线程写

__atomic_store(&disp_meas, &latest);

显示线程按当前video plane的frame_id挑结果,别按“最新算完的”挑。

四、坐标映射:先标定再画

测距/定位框必须过相机内参+手眼标定,否则中心准、边缘偏。广角镜头径向畸变能让边缘偏10像素以上。

棋盘格标定内参和畸变系数

显示用去畸变后的图,标注坐标统一在校正图里

像素→世界坐标走仿射/单应矩阵

九点标定够平面定位,3D场景走内外参

/* 像素坐标→显示坐标(已校正图) */

int dx = (int)(meas.pos_x);

int dy = (int)(meas.pos_y);

draw_rect(osd_buf, dx-20, dy-20, 40, 40);

draw_text(osd_buf, dx+24, dy, "%.2fmm", meas.width_mm);

若视频层是原图不去畸变,框坐标要做畸变逆变换,别两套混用。

五、OSD渲染性能要点

文字别每帧sprintf全屏重画,只擦改动区

固定标签(如“宽度”“坐标”)预渲染到位图

数值变化区局部blit

字体用SDL_ttf或freetype渲到offscreen,再拷进OSD plane

中文/特殊符号别用默认点阵,直接花屏

stride按真实行字节算,YUYV是width2,RGB565是width2,RGB888是width*3

六、多相机/外部触发同步

产线运动物体要硬触发:

传感器信号接相机Line1触发,曝光对齐工件到位

多相机走PTP或外部同步信号

软件时间戳只作参考,别拿来当几何对齐基准

不同相机帧率不一致时,OSD按各自frame_id取最近测量结果,不强制“同帧”。

七、落坑清单

相机回调里直接画框→采集线程被渲染拖死

fb0全屏重绘OSD→1080p掉帧

YUYV当RGB565拷→花屏

stride按width算→斜移错位

OSD每帧全清重画→CPU空转

测量数据不绑frame_id→框套错帧

原图未去畸变直接画→边缘偏

文字用默认ASCII点阵→中文乱码

多相机用软件时钟对齐→时间戳漂

DQBUF后忘QBUF→几帧后卡死

八、落地顺序

V4L2/SDK取流,mmap缓冲跑通预览

先fb0出图验证格式和stride

算法线程独立,结果带frame_id写共享区

标定向校正,像素坐标映射世界坐标

OSD走独立ARGB图层,只更新变化区

DRM双plane:视频层YUV+OSD层ARGB

dma-buf共享去掉memcpy

硬触发+帧时间戳对齐,OSD按frame_id取数

工业视觉叠加的本质是“视频和标注分两层、时间绑同一帧”:相机流走DMA到视频plane,测量数据走OSD plane硬件混合,算法结果不直接进采集回调。框准不准看标定,画面卡不卡看有没有把OSD全屏重画、有没有把格式转换扔给CPU。小屏调试fb0够用,上量平台必须拆plane——显示控制器混一次比CPU逐像素合成快一个数量级,也更稳。



本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
关闭