一、硬件环境
基于征程5的LS500 uSOM基础开发套件(EDK),摄像头模组为MIPI接口的摄像头模组,型号为淘宝买的30pin模组:SG2-IMX390C-5200-MIPI-H120H 自己手工DIY了一下环境,如下:
二、代码实现过程
首先来看一下我的代码目录,取文件夹名字为edk_rx3_imx390c_efficientnetb0,基于OE包V1.1.68版本修改的,目录如下:
.
├── CMakeLists.txt
├── README.md
├── build_and_deploy.sh
├── configs
│ ├── codec
│ ├── model
│ └── vio
├── deps
│ └── aarch64
├── run_sample.sh
├── src
│ ├── common
│ ├── ls_usr
│ ├── main.cc
│ ├── message
│ ├── modules
│ ├── utils
│ └── uws_server
└── tools
└── webservice
15 directories, 5 files
这里由于基于工具链中的示例来移植导EDK开发板上,不进行模型替换的话,我们只需要修改配置文件即可,配置文件在configs目录下,看看目录树长这样:
.
├── codec
│ └── j5_codec_config.json #用于web显示的编码配置
├── model
│ ├── fcos_efficientnetb0_mscoco.hbm #hbm是只含有BPU算子的模型文件
│ ├── inference_config.json #推理配置文件
│ └── postprocess_config.json #后处理配置文件
└── vio
├── j5_vio_config.json #VIO通路配置文件
├── vin #
│ └── camera
│ ├── hb_j5dev.json
│ └── j5_camera_source.json
└── vpm
└── sen_cimdma_pym2_1080p_imx390c_fpc #J5内处理器配置
└── vpm_config.json
我们可以看到配置文件夹下有三个文件夹codec,model和vin,分别是配置web显示的编码大小配置,模型文件以及模型配置文件,通路配置文件。下面来看看各配置json文件的参数:
j5_codec_config.json
{
"codec_chn_num": 1,
"chn_0": {
"chn_id": 0,
"codec_type": 3,
"image_width": 1936, # 这里和VPM中PYM配置相同
"image_height": 1080, #这里也是
"frame_buf_count": 3,
"jpeg_quality": 80
}
}
下面配置文件配置模型文件路径和级别
inference_config.json
{
"model_file_path": "./configs/model/fcos_efficientnetb0_mscoco.hbm", #模型文件路径
"pyramid_level": 0
}
这个配置文件很容易理解,就是用于后处理的配置文件,配置了步长,topk值,阈值还有分类的类别标签和ID值,可以看到有80种类别标签。
postprocess_config.json
{
"strides": [8, 16, 32, 64, 128],
"topk": 5,
"score_threshold": 0.5,
"iou_threshold": 0.6,
"model_detect_class": {
"person": 1, "bicycle": 2, "car": 3,
"motorcycle": 4, "airplane": 5, "bus": 6,
"train": 7, "truck": 8, "boat": 9,
"traffic light": 10, "fire hydrant": 11, "stop sign": 12,
"parking meter": 13, "bench": 14, "bird": 15,
"cat": 16, "dog": 17, "horse": 18,
"sheep": 19, "cow": 20, "elephant": 21,
"bear": 22, "zebra": 23, "giraffe": 24,
"backpack": 25, "umbrella": 26, "handbag": 27,
"tie": 28, "suitcase": 29, "frisbee": 30,
"skis": 31, "snowboard": 32, "sports ball": 33,
"kite": 34, "baseball bat": 35, "baseball glove": 36,
"skateboard": 37, "surfboard": 38, "tennis racket": 39,
"bottle": 40, "wine glass": 41, "cup": 42,
"fork": 43, "knife": 44, "spoon": 45,
"bowl": 46, "banana": 47, "apple": 48,
"sandwich": 49, "orange": 50, "broccoli": 51,
"carrot": 52, "hot dog": 53, "pizza": 54,
"donut": 55, "cake": 56, "chair": 57,
"couch": 58, "potted plant": 59, "bed": 60,
"dining table": 61, "toilet": 62, "tv": 63,
"laptop": 64, "mouse": 65, "remote": 66,
"keyboard": 67, "cell phone": 68, "microwave": 69,
"oven": 70, "toaster": 71, "sink": 72,
"refrigerator": 73, "book": 74, "clock": 75,
"vase": 76, "scissors": 77, "teddy bear": 78,
"toothbrush": 79, "hair drier": 80
}
}
下面这个文件就是配置摄像头的文件了,dev就是设备的意思,容易理解
hb_j5dev.json
{
"config_number":1,
"board_name":"j5_edk",
"config_0":{
"comment": "imx390C(sensing) 1920x1080 yuv422 30fps on host3 ,",
"interface_type": "mipi",
"deserial_num":0,
"deserial_0":{
"deserial_name":"max96712",
"deserial_addr":"0x29",
"bus_type":0,
"bus_num":6,
"power_mode":1,
"gpio_pin":[456],
"gpio_level":[0]
},
"port_number":1,
"port_0":{
"dev_port":0,
"bus_type":0,
"bus_num":6,
"entry_num":3,
"serial_addr":"0x41",
"sensor_addr":"0x6d",
"sensor_name":"imx390",
"reg_width":16,
"extra_mode":2,
"config_index":0,
"sensor_mode":0,
"fps":30,
"resolution":1080,
"deserial_index":0,
"deserial_port":0,
"data_path":"/app/bin/vps/vpm/cfg/evm/sen_cimdma_pym2_1080p_imx390_gdc_nano/cim_config.json",
"config_path":"/app/bin/vps/vpm/cfg/evm/sen_cimdma_pym2_1080p_imx390_gdc_nano/hb_mipi_imx390c_yuv422_%dfps_%dP.json",
"config_path+":"./hb_mipi_fscam_%dfps_%dP.json"
}
}
}
这是一个中间配置文件:
j5_camera_source.json
{
"cam_index": 0,
"cam_cfg_file": "configs/vio/vin/camera/hb_j5dev.json",
"frame_count": -1
}
这里到了重要的配置部分了,配置金字塔处理图像,模型的输入图像大小从金字塔读取,可以看到模型的输入大小为512X512,金字塔分高斯和双线性用法都类似,通常是gs–>ds–model input或者bl–>ds–>model input,当然这个通路不是绝对的,因为如果你的模型数据直接用原图可以或者通过ISP处理之后就能满足模型的输入条件,那么就不用金字塔缩放图像了。PYM配置如下:
vpm_config.json
{
"pipeline0": {
"pym": {
"pym_config": {
"pym_hw_id":2,
"pym_mode": 2,
"output_buf_num": 6,
"time_out": 6000,
"y_hor_coeff4": 0,
"y_hor_coeff3": 1,
"y_hor_coeff2": 1,
"y_hor_coeff1": 0,
"y_hor_coeff0": 0,
"y_ver_coeff4": 0,
"y_ver_coeff3": 1,
"y_ver_coeff2": 1,
"y_ver_coeff1": 0,
"y_ver_coeff0": 0,
"c_hor_coeff4": 0,
"c_hor_coeff3": 1,
"c_hor_coeff2": 1,
"c_hor_coeff1": 0,
"c_hor_coeff0": 0,
"c_ver_coeff4": 0,
"c_ver_coeff3": 1,
"c_ver_coeff2": 1,
"c_ver_coeff1": 0,
"c_ver_coeff0": 0,
"y_right_shift": 2,
"c_right_shift": 2
},
"pym_ctrl": {
"source_en": 1,
"src_uv_bypass": 0,
"src_in_width": 1936,
"src_in_height": 1080,
"src_in_stride_y": 1936,
"src_in_stride_uv": 1936,
"src_start_top": 0,
"src_start_left": 0,
"src_region_width": 1936,
"src_region_height": 1080,
"src_out_stride_y": 1936,
"src_out_stride_uv": 1936,
"suffix_hb_val": 68,
"prefix_hb_val": 2,
"suffix_vb_val": 20,
"prefix_vb_val": 2,
"pixel_num_before_sol": 16,
"gs_max_layer_en": 5,
"gs_en": 1,
"gs_uv_bypass": 0,
"gauss_info": [
{
"gs_start_top": 0,
"gs_start_left": 0,
"gs_region_width": 960,
"gs_region_height": 512,
"gs_stride_y": 960,
"gs_stride_uv": 960
},
{
"gs_start_top": 10,
"gs_start_left": 40,
"gs_region_width": 240,
"gs_region_height": 130,
"gs_stride_y": 240,
"gs_stride_uv": 240
},
{
"gs_start_top": 0,
"gs_start_left": 0,
"gs_region_width": 130,
"gs_region_height": 70,
"gs_stride_y": 130,
"gs_stride_uv": 130
},
{
"gs_start_top": 10,
"gs_start_left": 0,
"gs_region_width": 64,
"gs_region_height": 32,
"gs_stride_y": 64,
"gs_stride_uv": 64
},
{
"gs_start_top": 0,
"gs_start_left": 0,
"gs_region_width": 0,
"gs_region_height": 0,
"gs_stride_y": 0,
"gs_stride_uv": 0
}
],
"bl_max_layer_en": 5,
"bl_en": 0,
"bl_uv_bypass": 0,
"bilinear_info": [
{
"bl_start_top": 0,
"bl_start_left": 0,
"bl_region_width": 960,
"bl_region_height": 512,
"bl_stride_y": 968,
"bl_stride_uv": 968
},
{
"bl_start_top": 6,
"bl_start_left": 64,
"bl_region_width": 240,
"bl_region_height": 80,
"bl_stride_y": 240,
"bl_stride_uv": 240
},
{
"bl_start_top": 16,
"bl_start_left": 8,
"bl_region_width": 120,
"bl_region_height": 60,
"bl_stride_y": 120,
"bl_stride_uv": 120
},
{
"bl_start_top": 0,
"bl_start_left": 12,
"bl_region_width": 48,
"bl_region_height": 32,
"bl_stride_y":48,
"bl_stride_uv": 48
},
{
"bl_start_top": 0,
"bl_start_left": 0,
"bl_region_width": 0,
"bl_region_height": 0,
"bl_stride_y": 0,
"bl_stride_uv": 0
}
],
"upscale_roi_en": 0,
"us_roi_uv_bypass": 0,
"us_roi_start_left": 0,
"us_roi_start_top": 0,
"us_roi_region_width": 1920,
"us_roi_region_height": 1080,
"us_roi_stride_y": 1920,
"us_roi_stride_uv": 1920,
"us_roi_out_width": 1920,
"us_roi_out_height": 1080,
"ds_roi_en": 1,
"ds_roi_uv_bypass": 0,
"ds_roi": [
{
"ds_roi_layer": 0,
"ds_roi_sel": 2,
"ds_roi_start_top": 0,
"ds_roi_start_left": 0,
"ds_roi_region_width": 960,
"ds_roi_region_height": 512,
"ds_roi_stride_y": 512,
"ds_roi_stride_uv": 512,
"ds_roi_out_width": 512, #模型输入尺寸
"ds_roi_out_height": 512
},
{
"ds_roi_layer": 0,
"ds_roi_sel": 0,
"ds_roi_start_top": 20,
"ds_roi_start_left": 16,
"ds_roi_region_width": 900,
"ds_roi_region_height": 600,
"ds_roi_stride_y": 700,
"ds_roi_stride_uv": 700,
"ds_roi_out_width": 700,
"ds_roi_out_height": 500
},
{
"ds_roi_layer": 0,
"ds_roi_sel": 0,
"ds_roi_start_top": 8,
"ds_roi_start_left": 48,
"ds_roi_region_width": 720,
"ds_roi_region_height": 480,
"ds_roi_stride_y": 640,
"ds_roi_stride_uv": 640,
"ds_roi_out_width": 640,
"ds_roi_out_height": 320
},
{
"ds_roi_layer": 0,
"ds_roi_sel": 0,
"ds_roi_start_top": 18,
"ds_roi_start_left": 24,
"ds_roi_region_width": 520,
"ds_roi_region_height": 450,
"ds_roi_stride_y": 320,
"ds_roi_stride_uv": 320,
"ds_roi_out_width": 320,
"ds_roi_out_height": 160
},
{
"ds_roi_layer": 0,
"ds_roi_sel": 0,
"ds_roi_start_top": 0,
"ds_roi_start_left": 0,
"ds_roi_region_width": 520,
"ds_roi_region_height": 450,
"ds_roi_stride_y": 512,
"ds_roi_stride_uv": 512,
"ds_roi_out_width": 512,
"ds_roi_out_height": 240
},
{
"ds_roi_layer": 0,
"ds_roi_sel": 0,
"ds_roi_start_top": 0,
"ds_roi_start_left": 10,
"ds_roi_region_width": 520,
"ds_roi_region_height": 450,
"ds_roi_stride_y": 122,
"ds_roi_stride_uv": 122,
"ds_roi_out_width": 122,
"ds_roi_out_height": 32
}
],
"pre_line_int_0_set": 0,
"pre_line_int_1_set": 0,
"pre_line_int_2_set": 0,
"pre_line_int_3_set": 0,
"pre_line_int_4_set": 0,
"pre_line_int_5_set": 0,
"pre_line_int_6_set": 0,
"pre_line_int_7_set": 0
}
},
"gdc": {
"input_width": 1936,
"input_height": 1080,
"output_width": 1920,
"output_height": 1080,
"buf_num": 8,
"fb_buf_num": 8
}
}
}
下面的配置文件就是模式选择用的,配置选择网路回灌还是摄像头数据作为输入,显然我这里"config_index": 2,就是选择imx390c摄像头的配置。
j5_vio_config.json
{
"config_index": 2,
"board_name": "j5_som",
"config_0": {
"cam_en": 0,
"data_source": "network_feedback",
"data_source_num": 1,
"channel_id": [0],
"max_vio_buffer": 3,
"source_cfg_file": "configs/vio/vin/network/j5_network_source.json",
"vpm_cfg_file": "configs/vio/vpm/ddr_pym0_1080p/vpm_config.json"
},
"config_1": {
"cam_en": 1,
"data_source": "mipi_camera",
"data_source_num": 1,
"channel_id": [0],
"max_vio_buffer": 3,
"source_cfg_file": "./configs/vio/vin/camera/j5_camera_source.json",
"vpm_cfg_file": "./configs/vio/vpm/sen_cim_isp0_pym0_1080p_ar0233_max9296/vpm_config.json"
},
"config_2": {
"cam_en": 1,
"data_source": "mipi_camera",
"data_source_num": 1,
"channel_id": [0],
"max_vio_buffer": 3,
"source_cfg_file": "./configs/vio/vin/camera/j5_camera_source.json",
"vpm_cfg_file": "./configs/vio/vpm/sen_cimdma_pym2_1080p_imx390c_fpc/vpm_config.json"
}
}
以上的配置文件简单介绍一下,起一个引导的左右,要是每个参数都去介绍,那篇幅就大了。
三、效果展示
测试效果如下:
四、参考文件
1.参考 视频教程
2.社区培训视频第1011期
3.地平线征程5 算法工具链
技术交流
**查看专栏文章:
https://blog.csdn.net/weixin_41896321/article/details/130744325?spm=1001.2014.3001.5501