基于Linux操作系统的结构光单目扫描焊缝跟踪器——获取工业相机原始图像数据并通过TCP/IP协议远程传输

目录

一、系统整体架构

二、相机初始化与配置

[2.1 SDK初始化流程](#2.1 SDK初始化流程)

[2.2 关键参数设置](#2.2 关键参数设置)

三、图像捕获与灰度转换

[3.1 获取图像缓冲区](#3.1 获取图像缓冲区)

[3.2 灰度图像转换](#3.2 灰度图像转换)

四、UDP数据传输模块

[4.1 UDP客户端封装](#4.1 UDP客户端封装)

[4.2 像素数据分包策略](#4.2 像素数据分包策略)


前言:

结构光单目扫描焊缝跟踪器是基于激光三角测量原理的主动视觉传感器装置,通过单相机采集结构光在工件表面的形变条纹,经图像处理提取焊缝三维坐标信息,实时引导焊接机器人经行轨迹修正。该技术适用于汽车,船舶,钢结构,压力容器等行业的自动化焊接作业。

在工业视觉、自动化检测和远程监控等场景中,实时获取相机图像数据并传输到远端处理平台是一项常见需求。本文围绕一个实际项目------基于大恒工业相机SDK,实现灰度图像的实时采集,并通过UDP协议将像素数据分包发送至远程服务器------进行技术复盘。

一、系统整体架构

本程序运行在Linux平台(依赖unistd.htermios.h等POSIX接口),主要分为三个层次:

  1. 相机控制层 :使用厂商提供的CameraApi.h进行设备枚举、初始化、参数设置、图像采集。

  2. 数据处理层:将原始相机数据(可能为Bayer格式)转换为8位灰度,并按像素坐标组织。

  3. 网络传输层:通过UDP套接字将像素数据分片发送给指定服务器,同时支持用户交互(启动/停止、退出)。

主线程负责用户输入监听,当按下s键时启动一个独立的捕获循环(在continuousCapture函数中),该循环不断获取图像帧并调用sendPixelData发送。为避免阻塞UI,捕获循环内同时检查键盘输入以支持中途停止。

主程序逻辑如下:

二、相机初始化与配置

2.1 SDK初始化流程
cpp 复制代码
CameraSdkInit(1);
CameraEnumerateDevice(&cameraInfo, &iCameraCounts);
CameraInit(&cameraInfo, -1, -1, &hCamera);

CameraSdkInit参数1表示启用日志输出,便于调试。

枚举设备后取第一个可用相机,通过CameraInit获取相机句柄hCamera,后续所有操作依赖此句柄。

2.2 关键参数设置
cpp 复制代码
CameraSetIspOutFormat(hCamera, CAMERA_MEDIA_TYPE_MONO8);
CameraSetAeState(hCamera, FALSE);
CameraSetExposureTime(hCamera, 10000.0); // 10ms
CameraPlay(hCamera);

输出格式设为MONO8(8位灰度),省去后续色彩转换,符合项目需求。

关闭自动曝光(AE),使用固定曝光时间,保证图像亮度稳定,这对后续处理(如边缘检测)至关重要。

CameraPlay启动视频流,之后即可通过CameraGetImageBuffer获取帧数据。

注意点:曝光时间单位是微秒,10ms对于一般室内场景足够,若需要更暗或更亮可动态调整

三、图像捕获与灰度转换

3.1 获取图像缓冲区
cpp 复制代码
CameraGetImageBuffer(hCamera, &frameHead, &pRawBuffer, 100);

该函数阻塞等待最多100ms,返回原始数据指针pRawBuffer和帧头信息frameHead(包含宽高、像素格式等)。

超时返回CAMERA_STATUS_TIME_OUT,循环中处理超时以避免死等。

3.2 灰度图像转换
cpp 复制代码
CameraImageProcess(hCamera, pRawBuffer, pGrayBuffer, &frameHead);
  • 此SDK函数自动完成从原始格式(如Bayer RGGB)到MONO8的转换,输出到我们事先分配的pGrayBuffer

  • 转换后即可释放原始缓冲区CameraReleaseImageBuffer,避免内存泄漏。

四、UDP数据传输模块

4.1 UDP客户端封装

UDPClient类封装了socket创建、目标地址设置、发送接口。构造函数中直接创建SOCK_DGRAM套接字,initialize配置IP和端口,并设置发送缓冲区大小为1MB,超时1秒。

4.2 像素数据分包策略

单帧图像可能达到百万像素以上(例如1280×1024),每个像素1字节,即超过1MB。UDP包有效载荷一般建议不超过1472字节(避免IP分片),因此需要分包发送。

当前实现:

• 每帧数据发送前先发送FRAME_START标记,包含帧序号、宽高。

• 然后遍历所有像素,将每个像素的坐标和灰度值格式化为字符串"x,y gray",并用空格分隔。

• 每6个像素插入一个换行符\n,主要为了可读性(但增加冗余)。

• 使用std::ostringstream累积数据,当流大小超过1400字节时立即发送一个UDP包,并清空流。

• 帧结束时发送FRAME_END标记。

优缺点分析:

• 优点:文本格式便于调试,服务器端可直接按行解析。

• 缺点:冗余开销巨大------每个像素需要"x,y gray"字符串(约10~15字节),实际有效数据仅1字节,带宽利用率极低(约10%)。对于高帧率或高分辨率场景,这种方案不可取。

改进方向:可改为二进制传输,将像素值按行打包,附加简单的包头(帧号、行号、列数)即可,效率提升数十倍。但本文作为技术验证,优先保证了功能正确性。

结语:

后续将补充大恒相机库解析,以及udp协议接收实现。