这种实现使用了共享全局内存 + 互斥锁同步的方式在线程间传递图像数据,是一种经典的生产者-消费者模型。

1. 共享全局内存
c
unsigned char g_rgb_frame[FRAME_WIDTH * FRAME_HEIGHT * 3]; // RGB图像缓冲区
-
存储格式:连续的RGB像素数据
-
内存布局 :
[R0, G0, B0, R1, G1, B1, ..., Rn, Gn, Bn]
-
特点:
- 全局可见:所有线程可直接访问
- 固定大小:预分配内存避免运行时分配
- 裸数据存储:不包含OpenCV头信息
2. 互斥锁同步
c
pthread_mutex_t g_frame_mutex = PTHREAD_MUTEX_INITIALIZER;
- 保护对象 :
- 图像数据缓冲区
g_rgb_frame
- 状态标志
g_frame_ready
- 图像数据缓冲区

3. 状态标志
c
int g_frame_ready = 0; // 0=未就绪, 1=新帧就绪
- 作用:避免不必要的锁竞争
- 工作逻辑 :
- 采集线程:写入数据后设为1
- 识别线程:读取数据后设为0
- 无新帧时识别线程跳过处理
4. 完整工作流程
采集线程(生产者):
c
void* capture_thread(void* arg) {
while (running) {
// 1. 从摄像头获取帧(伪代码)
unsigned char* camera_buffer = get_camera_frame();
// 2. 加锁保护共享资源
pthread_mutex_lock(&g_frame_mutex);
// 3. 复制数据到全局缓冲区
memcpy(g_rgb_frame, camera_buffer,
FRAME_WIDTH * FRAME_HEIGHT * 3);
// 4. 设置就绪标志
g_frame_ready = 1;
// 5. 立即解锁
pthread_mutex_unlock(&g_frame_mutex);
// 6. 按帧率等待
usleep(1000000 / FPS);
}
return NULL;
}
识别线程(消费者):
c
void* detection_thread(void* arg) {
while (running) {
pthread_mutex_lock(&g_frame_mutex);
if (g_frame_ready) { // 检查新帧标志
// 创建OpenCV Mat对象(包装原始数据)
Mat frame(FRAME_HEIGHT, FRAME_WIDTH,
CV_8UC3, g_rgb_frame);
// 关键:深拷贝图像数据
Mat img = frame.clone();
// 重置就绪标志
g_frame_ready = 0;
pthread_mutex_unlock(&g_frame_mutex);
// 在锁外进行耗时处理
process_image(img); // 人脸/手掌检测
} else {
pthread_mutex_unlock(&g_frame_mutex);
usleep(5000); // 短暂休眠
}
}
return NULL;
}
5. 关键技术细节
- 内存拷贝 vs 零拷贝:
memcpy
保证数据完整性但增加CPU开销- 替代方案:双缓冲技术(避免拷贝)
c
// 全局定义
unsigned char* buffers[2];
int active_buffer = 0;
// 采集线程
memcpy(buffers[active_buffer], data, size);
active_buffer = 1 - active_buffer; // 切换缓冲区
// 识别线程
Mat frame(..., buffers[1 - active_buffer]);
- 数据封装:
c
Mat frame(FRAME_HEIGHT, FRAME_WIDTH, CV_8UC3, g_rgb_frame);
- 创建OpenCV Mat对象包装原始数据
- 不复制数据 :Mat对象仅包含指向
g_rgb_frame
的指针 - 危险:直接操作可能破坏共享数据
- 安全隔离:
c
Mat img = frame.clone(); // 关键安全措施
clone()
执行深拷贝创建独立副本- 作用:
- 避免识别线程修改原始缓冲区
- 允许识别线程长时间处理不影响新帧采集
- 解决OpenCV操作可能改变数据布局的问题
- 性能优化点 :
- 减少锁持有时间:只保护数据复制操作
- 避免忙等待:无数据时休眠(usleep)
- 批处理优化:积累多帧后批量处理
6. 总结
这种共享全局内存+互斥锁
的图像传递方式:
- 核心原理:通过物理内存共享实现零拷贝传递
- 关键安全措施:互斥锁保护数据一致性 + clone()隔离处理
- 适用场景:单生产者单消费者、实时性要求高、资源受限系统
- 典型应用:嵌入式视觉系统、实时视频分析、机器人控制
