使用NVIDIA VPI做鱼眼矫正

NVIDIA 视觉编程接口 (VPI) 是一个软件库,可提供一组计算机视觉和图像处理算法。这些算法的实现在 NVIDIA Jetson 嵌入式计算机或独立 GPU 上可用的不同硬件引擎上得到加速。硬件引擎在 VPI 中被命名为后端。这些后端使您能够卸载可并行处理阶段并通过使用 Jetson 设备固有的可用系统级并行性来加速应用程序。后端是 CPU、CUDA (GPU)、PVA 和 VIC。特定后端引擎的确切可用性取决于部署应用程序的 Jetson 平台。

官方的demo里提供了很多的图像处理算法,用VPI的好处在于,Nvidia又给你造了一个库(泥坑),让你更方便地使用GPU和VIC来做图像处理。直接运行官方的demo就可以实际看效果。

对应上文,我在nvidia 平台,做了一个简单封装,使用VPI来做鱼眼矫正,一张1080P的图像,鱼眼矫正大概耗时1ms,整个处理过程大概3-5ms,基本满足工程的需求,看了一下大部分时间应该是在色彩空间转换上,需要更好的性能需要再深入细调。

void FishEyeCorrect::init(const cv::Mat &kMat, const cv::Mat &dMat, int width, int height) {
     // Allocate a dense map.
    VPIWarpMap map            = {};
    map.grid.numHorizRegions  = 1;
    map.grid.numVertRegions   = 1;
    map.grid.regionWidth[0]   = width;
    map.grid.regionHeight[0]  = height;
    map.grid.horizInterval[0] = 1;
    map.grid.vertInterval[0]  = 1;
    CHECK_STATUS(vpiWarpMapAllocData(&map));

    // Initialize the fisheye lens model with the coefficients given by calibration procedure.
    VPIFisheyeLensDistortionModel distModel = {};
    distModel.mapping                       = VPI_FISHEYE_EQUIDISTANT;
    distModel.k1                            = dMat.at<double>(0, 0);
    distModel.k2                            = dMat.at<double>(0, 1);
    distModel.k3                            = dMat.at<double>(0, 2);
    distModel.k4                            = dMat.at<double>(0, 3);

    // Fill up the camera intrinsic parameters given by camera calibration procedure.
    VPICameraIntrinsic K;
    for (int i = 0; i < 2; ++i)
    {
        for (int j = 0; j < 3; ++j)
        {
            K[i][j] = kMat.at<double>(i, j);
        }
    }

    // Camera extrinsics is be identity.
    VPICameraExtrinsic X = {};
    X[0][0] = X[1][1] = X[2][2] = 1;

    // Generate a warp map to undistort an image taken from fisheye lens with
    // given parameters calculated above.
    vpiWarpMapGenerateFromFisheyeLensDistortionModel(K, X, K, &distModel, &map);

    // Create the Remap payload for undistortion given the map generated above.
    CHECK_STATUS(vpiCreateRemap(VPI_BACKEND_CUDA, &map, &remap));

    // Now that the remap payload is created, we can destroy the warp map.
    vpiWarpMapFreeData(&map);

    // Create a stream where operations will take place. We're using CUDA
    // processing.
    CHECK_STATUS(vpiStreamCreate(VPI_BACKEND_CUDA, &stream));

    CHECK_STATUS(vpiImageCreate(width, height, VPI_IMAGE_FORMAT_NV12_ER, 0, &tmpIn));
    CHECK_STATUS(vpiImageCreate(width, height, VPI_IMAGE_FORMAT_NV12_ER, 0, &tmpOut));
}

void FishEyeCorrect::correctImage(cv::Mat &cvImage) {
    if (vimg == nullptr) {
        // Now create a VPIImage that wraps it.
        CHECK_STATUS(vpiImageCreateWrapperOpenCVMat(cvImage, 0, &vimg));
    } else {
        CHECK_STATUS(vpiImageSetWrappedOpenCVMat(vimg, cvImage));
    }

    CHECK_STATUS(vpiSubmitConvertImageFormat(stream, VPI_BACKEND_CUDA, vimg, tmpIn, NULL));
    CHECK_STATUS(vpiSubmitRemap(stream, VPI_BACKEND_CUDA, remap, tmpIn, tmpOut, VPI_INTERP_CATMULL_ROM, VPI_BORDER_ZERO, 0));
    CHECK_STATUS(vpiSubmitConvertImageFormat(stream, VPI_BACKEND_CUDA, tmpOut, vimg, NULL));
    CHECK_STATUS(vpiStreamSync(stream));
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值