如何在高通RB5板上用GStreamer获取OV9282双目相机流并接入算法?
高通RB5开发板GStreamer访问OV9282双目相机及接入深度算法解决方案
一、通过GStreamer访问OV9282 MIPI双目相机
- 确认相机设备索引:RB5上的OV9282双目相机对应两个独立的
camera-id,可通过v4l2-ctl --list-devices查看对应的/dev/videoX设备,camera-id一般为设备编号(如0和1)。 - 同时采集双目流:实例化两个
qtiqmmfsrc元件,分别指定不同的camera-id即可获取左右相机数据流,示例pipeline:
gst-launch-1.0 qtiqmmfsrc camera-id=0 ! video/x-raw,format=NV12,width=1280,height=720,framerate=30/1 ! queue ! waylandsink qtiqmmfsrc camera-id=1 ! video/x-raw,format=NV12,width=1280,height=720,framerate=30/1 ! queue ! waylandsink
- 适配sensor参数:若相机无法正常输出,需检查
qtiqmmfsrc的sensor-mode参数,匹配OV9282支持的分辨率和帧率,可通过gst-inspect-1.0 qtiqmmfsrc查看参数范围。
二、将相机流接入深度检测算法
核心是用GStreamer的appsink元件把数据流导出到应用层,再传递给深度算法,具体步骤如下:
1. 修改Pipeline接入appsink
用tee元件同时输出到显示和算法处理,示例pipeline:
gst-launch-1.0 qtiqmmfsrc camera-id=0 ! video/x-raw,format=NV12,width=1280,height=720,framerate=30/1 ! tee name=t t. ! queue ! waylandsink t. ! queue ! appsink name=left_sink qtiqmmfsrc camera-id=1 ! video/x-raw,format=NV12,width=1280,height=720,framerate=30/1 ! tee name=t2 t2. ! queue ! waylandsink t2. ! queue ! appsink name=right_sink
2. 在代码中提取帧数据
通过GStreamer C API设置appsink回调,提取缓冲区数据传入算法,示例代码框架:
#include <gst/gst.h> #include <gst/app/gstappsink.h> // 左侧相机帧处理回调 static GstFlowReturn process_left_frame(GstAppSink *sink, gpointer user_data) { GstSample *sample = gst_app_sink_pull_sample(sink); if (!sample) return GST_FLOW_ERROR; GstBuffer *buffer = gst_sample_get_buffer(sample); GstMapInfo map; if (gst_buffer_map(buffer, &map, GST_MAP_READ)) { // OV9282是灰度相机,NV12格式的Y分量即为灰度数据 unsigned char *gray_data = map.data; int width = 1280; int height = 720; // 传入深度算法校准/检测接口 your_depth_alg_input_left(gray_data, width, height); gst_buffer_unmap(buffer, &map); } gst_sample_unref(sample); return GST_FLOW_OK; } // 右侧相机帧处理回调逻辑与左侧一致,此处省略process_right_frame函数 int main(int argc, char *argv[]) { gst_init(&argc, &argv); // 创建双目流pipeline GstElement *pipeline = gst_parse_launch( "qtiqmmfsrc camera-id=0 ! video/x-raw,format=NV12,width=1280,height=720,framerate=30/1 ! queue ! appsink name=left_sink " "qtiqmmfsrc camera-id=1 ! video/x-raw,format=NV12,width=1280,height=720,framerate=30/1 ! queue ! appsink name=right_sink", NULL ); // 配置左侧appsink回调 GstAppSink *left_sink = GST_APP_SINK(gst_bin_get_by_name(GST_BIN(pipeline), "left_sink")); gst_app_sink_set_callbacks(left_sink, gst_app_sink_callbacks_new(process_left_frame, NULL, NULL, NULL, NULL), NULL, NULL); // 配置右侧appsink回调 GstAppSink *right_sink = GST_APP_SINK(gst_bin_get_by_name(GST_BIN(pipeline), "right_sink")); gst_app_sink_set_callbacks(right_sink, gst_app_sink_callbacks_new(process_right_frame, NULL, NULL, NULL, NULL), NULL, NULL); // 启动pipeline gst_element_set_state(pipeline, GST_STATE_PLAYING); // 运行主事件循环 GMainLoop *loop = g_main_loop_new(NULL, FALSE); g_main_loop_run(loop); // 资源清理 gst_element_set_state(pipeline, GST_STATE_NULL); gst_object_unref(pipeline); g_main_loop_unref(loop); return 0; }
3. 帧同步与校准适配
- 帧同步:通过
gst_buffer_get_pts获取左右帧时间戳,当差值在允许范围(如10ms)内时,同时传入左右帧数据。 - 校准环节:将同步后的左右灰度帧传入深度算法校准模块,完成内参、外参计算与加载,即可进行后续深度检测。
内容的提问来源于stack exchange,提问作者Fourier
相关产品推荐
相关产品推荐

