四目(四摄像头)视频拼接智能处理案例-全景图像 扩展视野

本篇文章的目的是因为针对目前开源内容并没有找到太多相关知识内容,自己对于这部分也在学习,来针对这些技术栈展开一些探讨和提升。

首先来引入一下拼接图像过程的一些思想以及方法,如下:
主要的拼接思想是通过整合多个重叠的图像区域来创建一个无缝的、全景的图像。

1. 图像重叠与拼接区域

  • 重叠区域:不同摄像头拍摄的图像通常会有一定的重叠区域,这部分重叠区域用于拼接时的图像融合。拼接算法需要识别和处理这些重叠区域,以便能够无缝地将它们组合成一个完整的图像。

  • 拼接区域的划分:图像被划分为多个拼接区域,每个区域包括重叠部分和非重叠部分。每个重叠区域都需要处理,以确保最终拼接效果的平滑和自然。

2. 图像融合

  • 融合算法:为了将重叠的区域平滑地结合起来,通常使用一些融合算法。这些算法可以基于颜色、亮度、纹理等特征来处理重叠区域,以减少接缝和视觉不连续性。

  • 融合宽度和高度:在处理图像时,需要计算每个拼接区域的融合宽度和高度。这些参数决定了图像重叠的多少,以及如何在重叠区域进行平滑处理。

3. 生成和应用 LUT

  • 2D LUT(查找表):在图像拼接中,2D LUT 是一种用于调整图像颜色和亮度的工具。拼接算法可以生成这些 LUT,并将其应用于图像处理模块中,以确保拼接后的图像颜色和亮度的一致性。

  • LUT 更新:生成的 LUT 需要更新到视频处理引擎(VPE)或其他相关模块中,以便在显示或进一步处理图像时应用这些调整。

4. 拼接处理步骤

以下是具体的拼接处理步骤:

  1. 解析拼接参数:从输入图像或视频帧中提取拼接参数,如重叠区域的宽度、高度等。

  2. 计算图像偏移:计算每个图像的虚拟内存地址,以便在内存中正确定位各个拼接区域。

  3. 处理拼接输入:将计算得到的拼接信息传递给智能拼接模块,并执行拼接操作。这通常包括调用特定的拼接处理函数,并传递图像数据和拼接参数。

  4. 获取拼接结果:从拼接模块获取处理后的结果,如 LUT,并将其应用到图像处理模块中。

  5. 更新处理模块:将获取到的 LUT 更新到视频处理引擎(VPE)或其他处理模块中,以确保最终图像的拼接效果。

重复帧的处理

  • 重复帧:在某些情况下,摄像头可能会生成重复的帧或相似的帧,这些帧可以通过拼接算法进行处理。处理重复帧的目标是确保拼接图像的连续性和一致性,避免视觉上的不连贯。

图像融合拼接方法是将来自不同视角或不同摄像头的图像合并成一个无缝的全景图像。通过这种方法,可以扩展视野或合成更大范围的图像。

综上所述,编程思维如下所示的流程:

初始化:初始化拼接信息结构体和状态数据。

解析参数:从视频帧的 reserved 数据中提取拼接相关的参数,如当前帧编号、重叠区域的宽度和高度等。

计算地址:计算每个拼接区域的 Y 和 UV 图像内存的虚拟地址。

处理拼接:将拼接信息传递给智能拼接处理模块,并获取处理结果。

更新 LUT:获取 2D LUT 结果并更新 DRE 融合映射。

缓存刷新:刷新缓存并取消映射虚拟内存。

设置 VPE 参数:设置 VPE 的 2D LUT 参数并返回操作结果。

#if SMART_STITCH
static HD_RESULT smart_stitch_trig(HD_VIDEO_FRAME* p_video_frame, VIDEO_RECORD *p_stream)
{
    SMART_STITCH_INFO smart_stitch_info = {0};
    UINT32 overlap_idx, current_frame_num;
    UINT32 blend_width[MAX_VSP_BLEND_FRAME_NUM] = {0};
    UINT32 blend_height[MAX_VSP_BLEND_FRAME_NUM] = {0};
    ULONG y_addr_l[VSP_MAX_BLEND_FRAME_NUM] = {0};
    ULONG y_addr_r[VSP_MAX_BLEND_FRAME_NUM] = {0};
    ULONG uv_addr_l[VSP_MAX_BLEND_FRAME_NUM] = {0};
    ULONG uv_addr_r[VSP_MAX_BLEND_FRAME_NUM] = {0};

    // Parsing stitch parameters
    current_frame_num = ((p_video_frame->reserved[6] >> 16) & 0xF);
    for (overlap_idx = 0; overlap_idx < MAX_VSP_BLEND_FRAME_NUM; overlap_idx++) {
        blend_width[overlap_idx] = (p_video_frame->reserved[2] >> (16 * overlap_idx)) & 0xFFFF;
        blend_height[overlap_idx] = p_video_frame->ph[0];
    }

    // Calculate line offsets
    UINT32 y_lofs = 0;
    UINT32 uv_lofs = 0;
    for (overlap_idx = 0; overlap_idx < vsp_overlap_num; overlap_idx++) {
        y_lofs += blend_width[overlap_idx] << 1;
        uv_lofs += blend_width[overlap_idx] << 1;
    }

    // Memory address calculations
    UINTPTR phy_addr_frame = hd_common_mem_blk2pa(p_video_frame->blk);
    if (phy_addr_frame == 0) return HD_ERR_SYS;
    ULONG vir_addr_frame = (ULONG)hd_common_mem_mmap(HD_COMMON_MEM_MEM_TYPE_CACHE, phy_addr_frame, DBGINFO_BUFSIZE() + VDO_YUV_BUFSIZE(y_lofs, blend_height[0], HD_VIDEO_PXLFMT_YUV420));
    if (vir_addr_frame == 0) return HD_ERR_SYS;
    ULONG y_va = PHY2VIRT_YUV(p_video_frame->phy_addr[0]);
    ULONG uv_va = PHY2VIRT_YUV(p_video_frame->phy_addr[1]);

    // Calculate virtual memory addresses for overlapping images
    UINT32 anchorX = (vsp_overlap_num == vsp_blend_frame_num) ? blend_width[vsp_overlap_num - 1] : 0;
    for (overlap_idx = 0; overlap_idx < vsp_overlap_num; overlap_idx++) {
        y_addr_l[overlap_idx] = y_va + anchorX;
        y_addr_r[overlap_idx] = y_va + anchorX + blend_width[overlap_idx];
        uv_addr_l[overlap_idx] = uv_va + anchorX;
        uv_addr_r[overlap_idx] = uv_va + anchorX + blend_width[overlap_idx];
        anchorX += blend_width[overlap_idx] << 1;
    }

    // Process input for smart stitching
    for (overlap_idx = 0; overlap_idx < vsp_overlap_num; overlap_idx++) {
        smart_stitch_info.frame_num = current_frame_num;
        smart_stitch_info.y_lofs_l = y_lofs;
        smart_stitch_info.y_lofs_r = y_lofs;
        smart_stitch_info.uv_lofs_l = uv_lofs;
        smart_stitch_info.uv_lofs_r = uv_lofs;
        smart_stitch_info.blend_height = blend_height[overlap_idx];
        smart_stitch_info.blend_width = blend_width[overlap_idx];
        smart_stitch_info.y_addr_l = y_addr_l[overlap_idx];
        smart_stitch_info.y_addr_r = y_addr_r[overlap_idx];
        smart_stitch_info.uv_addr_l = uv_addr_l[overlap_idx];
        smart_stitch_info.uv_addr_r = uv_addr_r[overlap_idx];

        if (smart_stitch2_process_input((void *)My_stitchers[overlap_idx], &smart_stitch_info) != HD_OK) {
            return HD_ERR_SYS;
        }
    }

    // Obtain and update LUT
    g_lut2d_buf_idx = (g_lut2d_buf_idx + 1) % LUT2D_BUFNUM;
    for (overlap_idx = 0; overlap_idx < vsp_overlap_num; overlap_idx++) {
        if (smart_stitch2_process_output((void *)My_stitchers[overlap_idx], g_lut2d_lbuf_pool[overlap_idx][g_lut2d_buf_idx], g_lut2d_rbuf_pool[overlap_idx][g_lut2d_buf_idx]) != HD_OK) {
            return HD_ERR_SYS;
        }
        g_lut2d_l_addr[overlap_idx] = g_lut2d_lbuf_pool[overlap_idx][g_lut2d_buf_idx];
        g_lut2d_r_addr[overlap_idx] = g_lut2d_rbuf_pool[overlap_idx][g_lut2d_buf_idx];
    }

    hd_common_mem_flush_cache((void*)g_lut2d_va, g_smart_stitch_LUT_mem_size);

    // Update DRE fusion map
    for (overlap_idx = 0; overlap_idx < vsp_overlap_num; overlap_idx++) {
        UINT32 blk_size = VDO_YUV_BUFSIZE(blend_width[overlap_idx], blend_height[overlap_idx], HD_VIDEO_PXLFMT_Y8);
        hd_common_mem_flush_cache((void*)(p_stream->fusion_va[overlap_idx]), blk_size);
    }

    if (hd_common_mem_munmap((void *)vir_addr_frame, DBGINFO_BUFSIZE() + VDO_YUV_BUFSIZE(y_lofs, blend_height[0], HD_VIDEO_PXLFMT_YUV420)) != HD_OK) {
        return HD_ERR_SYS;
    }

    // Set VPE parameters
    for (overlap_idx = 0; overlap_idx < vsp_blend_frame_num; overlap_idx++) {
        if (vendor_vpe_set_cmd(VPET_ITEM_2DLUT_PARAM, &lut2d[overlap_idx]) != HD_OK) {
            return HD_ERR_SYS;
        }
    }

    return HD_OK;
}
#endif

视频监控应用中,如何有效实现宽视场范围视频的完整获取,是视频监控系统的关键功能之一。本文针对多摄像头硬件平台,重点研究 360 度全景视频拼接的实现技术。在保证高质量的拼接图像的前提下,满足实际应用场景的实时性要求是本文算法设计的主要目标。针对全景拼接视频监控领域这一应用背景,本文对多摄像头系统全景拼接存在的一些优势和约束进行详细分析,并在此基础上,采用多个广角镜头进行视频图像采集,实现摄像头个数和单个镜头视角之间的合理折中。在控制成本的前提下,有效实现水平方向 360 度无盲区监控。 针对全景视频拼接算法的实时性能和拼接效果,本文重点在以下几个方面开展了研究工作: 1、本文采用普通的监控 CCD 单板机和广角镜头组装摄像单元,对多个摄像单元通道采用多线程同步视频采集。针对普通监控镜头采集图像质量不高的问题,提出基于颜色校正板的颜色校正方法,对输入图像进行预处理,有效改善图像质量。并采用基于灰度均值的方法,对相邻图像的重叠区域进行亮度调整。 2、本文基于经典的直线标定法思想,提出两步法镜头矫正方案。通过所提出的直线标定法对镜头进行一次矫正,然后通过手动设置并调节畸变参数,对矫正后的图像进行二次矫正,所提出的算法能保证良好的镜头矫正效果。 3、研究了柱面投影模型的原理,提出将柱面映射的投影中心修正为镜头畸变中心,克服了由于畸变和透视失真等因素造成的重叠区物体成像尺寸不一致的问题。然后,利用所提出的坐标映射表的方式,一次性实现镜头畸变矫正和柱面映射,有效提高了算法执行速度。 4、分析了基于 Harris 特征和 SIFT 特征的配准算法原理。SIFT 特征配准算法鲁棒性高,但难以满足硬件系统的实时性要求;基于 Harris 特征的配准算法复杂度低,但难以应对广角镜头畸变引起的图像质量差的问题,匹配性能较差。最后采用了基于积分图像的快速归一化互相关配准方案,实验验证了算法的可行性和有效性。 5、此外,在图像融合方面,基于经典的多频带融合算法,结合线性融合的思想,优化了一种简单的多分辨率线性融合方法。在保证融合质量的基础上,提升了速度。 关键字:多镜头多传感器;图像配准;全景拼接;实时监控;广角镜头
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

7yewh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值