解读opencv->tensorrt的数据排列方式

 更新时间:2023年02月02日 10:21:26   作者:永力  
这篇文章主要介绍了解读opencv->tensorrt的数据排列方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

opencv->tensorrt的数据排列

在使用tensorrt的时候,将opencv的Mat格式处理成tensorrt输入方式。

中间还有图像预处理,包括通道的变换、图像尺寸变形,最重要的是如何将Mat格式处理成tensorrt 可接受的输入形式。

opencv的Mat中BGR形式的数据排列是这样的:

b(0,0), g(0,0), r(0,0), b(0,1), g(0,1), r(0,1),......, b(h-1,w-1), g(h-1,w-1), r(h-1,w-1)

tensorrt所需要的数据排列是这样的:

b(0,0), b(0,1),..., b(h-1,w-1), g(0,0), g(0,1)..., g(h-1,w-1), r(0,0),r(0,1), ..., r(h-1,w-1)

可见,需要将Mat的数据通道分离,重新排列,才能为tensorrt所用。

下面摘录两种常见的处理方法。

1.使用split函数分离通道

std::vector<float> prepareImage(std::vector<cv::Mat> &vec_img) {
    std::vector<float> result(BATCH_SIZE * IMAGE_WIDTH * IMAGE_HEIGHT * INPUT_CHANNEL);
    float *data = result.data();
    int index = 0;
    for (const cv::Mat &src_img : vec_img)
    {
        if (!src_img.data)
            continue;
        float ratio = float(IMAGE_WIDTH) / float(src_img.cols) < float(IMAGE_HEIGHT) / float(src_img.rows) ? float(IMAGE_WIDTH) / float(src_img.cols) : float(IMAGE_HEIGHT) / float(src_img.rows);
        cv::Mat flt_img = cv::Mat::zeros(cv::Size(IMAGE_WIDTH, IMAGE_HEIGHT), CV_8UC3);
        cv::Mat rsz_img;
        cv::resize(src_img, rsz_img, cv::Size(), ratio, ratio);
        rsz_img.copyTo(flt_img(cv::Rect(0, 0, rsz_img.cols, rsz_img.rows)));
        flt_img.convertTo(flt_img, CV_32FC3, 1.0 / 255);

        //HWC TO CHW
        int channelLength = IMAGE_WIDTH * IMAGE_HEIGHT;
        std::vector<cv::Mat> split_img = {
                cv::Mat(IMAGE_HEIGHT, IMAGE_WIDTH, CV_32FC1, data + channelLength * (index + 2)),     // Mat与result数据区域共享
                cv::Mat(IMAGE_HEIGHT, IMAGE_WIDTH, CV_32FC1, data + channelLength * (index + 1)),
                cv::Mat(IMAGE_HEIGHT, IMAGE_WIDTH, CV_32FC1, data + channelLength * index)
        };
        index += 3;
        cv::split(flt_img, split_img);		// 通道分离
    }
    return result;	// result与split_img的数据共享
}

2.手撕通道,暴力直接

std::vector<float> prepareImage(std::vector<cv::Mat> &vec_img) {
    std::vector<float> result(BATCH_SIZE * INPUT_CHANNEL * IMAGE_HEIGHT * IMAGE_WIDTH);
    float* data = result.data();
    int index = 0;
    int offset = IMAGE_WIDTH * IMAGE_HEIGHT;
    // 数据预处理
    for(const auto &img:vec_img){
        float ratio = IMAGE_WIDTH/float(img.cols) < IMAGE_HEIGHT/float(img.rows) ? IMAGE_WIDTH/float(img.cols) : IMAGE_HEIGHT/float(img.rows);
        cv::Mat rsz_img;
        cv::resize(img, rsz_img, cv::Size(), ratio, ratio, 0);
        cv::Mat flt_img(IMAGE_HEIGHT, IMAGE_WIDTH, CV_8UC3, cv::Scalar(128, 128, 128));
        rsz_img.copyTo(flt_img(cv::Rect(0, 0, rsz_img.cols, rsz_img.rows)));
        
        // 手撕三通道,填入data
        int i = 0;
        for (int row = 0; row < IMAGE_HEIGHT; ++row) {
            uchar* uc_pixel = flt_img.data + row * flt_img.step;
            for (int col = 0; col < IMAGE_WIDTH; ++col) {
                data[index * 3 * IMAGE_HEIGHT * IMAGE_WIDTH + i] = (float)uc_pixel[2]/255.;
                data[index * 3 * IMAGE_HEIGHT * IMAGE_WIDTH + i + IMAGE_HEIGHT * IMAGE_WIDTH] = (float)uc_pixel[1]/255.;
                data[index * 3 * IMAGE_HEIGHT * IMAGE_WIDTH+ i + 2 * IMAGE_HEIGHT * IMAGE_WIDTH] = (float)uc_pixel[0]/255.;
                uc_pixel += 3;
                ++i;
            }
        }
        index++;
    }
    return result;
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • django富文本编辑器的实现示例

    django富文本编辑器的实现示例

    这篇文章主要介绍了django富文本编辑器的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • django实现将后台model对象转换成json对象并传递给前端jquery

    django实现将后台model对象转换成json对象并传递给前端jquery

    这篇文章主要介绍了django实现将后台model对象转换成json对象并传递给前端jquery,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-03-03
  • Python实现提取和去除数据中包含关键词的行

    Python实现提取和去除数据中包含关键词的行

    这篇文章主要介绍了Python如何提取数据中包含关键词的行已经如何去除数据中包含关键词的行,文中的示例代码讲解详细,需要的可以参考一下
    2023-08-08
  • Python中ValueError报错的原因和解决办法

    Python中ValueError报错的原因和解决办法

    在Python编程中,ValueError是一种非常常见的异常类型,它通常发生在函数接收到一个有效类型但不适合该函数操作的值时,本文将深入探讨ValueError的报错原因、提供详细的解决办法,并通过丰富的代码示例来加深理解,需要的朋友可以参考下
    2024-07-07
  • python自定义时钟类、定时任务类

    python自定义时钟类、定时任务类

    这篇文章主要为大家详细介绍了Python自定义时钟类、定时任务类,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-07-07
  • python密码学Base64编码和解码教程

    python密码学Base64编码和解码教程

    这篇文章主要为大家介绍了python密码学Base64编码和解码教程详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-05-05
  • Python破解网站登录密码脚本

    Python破解网站登录密码脚本

    这篇文章主要为大家介绍一个简单的Python暴力破解网站登录密码脚本,文中的过程讲解详细,对我们学习Python有一定的帮助,感兴趣的可以学习一下
    2022-01-01
  • Python IDE Pycharm中的快捷键列表用法

    Python IDE Pycharm中的快捷键列表用法

    在本篇文章里小编给大家整理的是关于Python IDE Pycharm中的快捷键列表用法,需要的朋友们收藏下
    2019-08-08
  • 将python运行结果保存至本地文件中的示例讲解

    将python运行结果保存至本地文件中的示例讲解

    今天小编就为大家分享一篇将python运行结果保存至本地文件中的示例讲解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-07-07
  • Python中的引用与copy介绍

    Python中的引用与copy介绍

    这篇文章主要以整型数据类型及列表为例,详细的介绍了再Python中的引用与copy的相关资料,需要的朋友可以参考下面文章内容
    2021-09-09

最新评论