CV-CUDA高性能图像处理加速库

开源地址:https://github.com/CVCUDA/CV-CUDA
CV-CUDA 可以集成到 C/C++、Python 应用程序中,也可以集成到 PyTorch 等现有的深度学习框架中。
以图像背景模糊算法为例,将CV-CUDA替换 OpenCV作为图像预/后处理的后端,整个推理过程吞吐量能加20 多倍。
CV-CUDA Beta 版预计将在 2023 年 3 月发布,6 月份发布 v1.0 正式版。

CV-CUDA特点

图像分类是最常见的 AI 图像算法之一,通常可以用于物体识别,以图搜图等场景,几乎是所有 AI 图像算法的基础。图像分类的 pipeline 大体可以分为 2 个部分:前处理部分和 DNN 部分。其中前处理部分,在训练和推理过程中最常见的 4 种操作包括:图片解码、Resize、Padding、Normalize。DNN 部分已经有了 GPU 的加速,而前处理部分通常都会使用 CPU 上的库函数进行处理。如果能够把前处理部分也移植到 GPU 上,那么一方面可以释放 CPU 资源,另一方面也可以进一步提升 GPU 利用率,从而可以对整个 pipeline 进行加速。

传统的图像预处理操作一般在 CPU 上进行,一方面会占用大量的 CPU 资源,使得 CPU 和 GPU 的负载不均衡;另一方面由于基于 CPU 的图像加速库不支持 batch 操作,导致预处理的效率低下。为了解决当前主流的图像处理库所存在的一些问题,NVIDIA 和字节跳动的机器学习团队联合开发了基于 GPU 的图像处理加速库 CV-CUDA,并拥有以下特点:

(1)Batch

支持 batch 操作,可以充分利用 GPU 高并发、高吞吐的并行加速特性,提升计算效率和吞吐率。

(2)Variable Shape

支持同一 batch 中图片尺寸各不相同,保证了使用上的灵活性。此外,在对图片进行处理时,可以对每张图片指定不同的参数。例如调用 RotateVarShape 算子时,可以对 batch 中每张图片指定不同的旋转角度。

(3)C / C++/Python 接口

在部署机器学习算法时需要对齐训练和推理流程。一般来说,训练时利用 python 进行快速验证,推理时利用 C++ 进行高性能部署,然而一些图像处理库仅支持 python,这给部署带来了极大的不便。如果在训练和推理采用不同的图像处理库,则又需要在推理端重新实现一遍逻辑,过程会非常繁琐。

CV-CUDA 提供了 C、C++ 和 Python 接口,可以同时服务于训练和推理场景。从训练迁移到推理场景时,也可免去繁琐的对齐流程,提高部署效率。

(4)独立算子设计

CV-CUDA 作为基础图像处理库,采用了独立算子设计,不需要预先定义流水线。独立算子的设计具有更高的灵活性,使调试变得更加的容易,而且可以使其与其他的图像处理交互,或者将其集成在用户自己的图像处理上层框架中。

(5)结果对齐 OpenCV

不同的图像处理库由于对一些算子的实现方式不一致导致计算结果难以对齐。例如常见的 Resize 操作,OpenCV、OpenCV-gpu 以及 torchvision 的实现方式都不一样,计算结果存在差异。因此如果在训练时用 OpenCV CPU 版本而推理时若要采用 GPU 版本或其他图像处理库,就会面临结果存在误差的问题。

在设计之初,我们考虑到当前图像处理库中,很多用户习惯使用 OpenCV 的 CPU 版本,因此在设计算子时,不管是函数参数还是图像处理结果上,尽可能对齐 OpenCV CPU 版本的算子。当用户从 OpenCV 迁移到 CV-CUDA 时,只需做少许改动便可使用,且图片处理结果和 OpenCV 一致,不需要重新训练模型。

(6)易用性

CV-CUDA 提供了 Image、ImageBatchVarShape 等结构体,方便用户的使用。同时还提供了 Allocator 类,用户可以自定义显存分配策略(例如用户可以设计显存池分配策略来提高显存分配速度),方便上层框架集成和管理资源。目前 CV-CUDA 提供了 PyTorch、OpenCV 和 Pillow 的数据转化接口,方便用户进行算子替换和进行不同图像库之间的混用。

(7)针对不同 GPU 架构的性能高度优化

CV-CUDA 可以支持 Volta、Turing、Ampere 等 GPU 架构,并针对不同架构 GPU 的特点,在 CUDA kernel 层面进行了性能上的高度优化,可在云服务场景中规模化部署。

为什么 OpenCV 仍不够好?

在 CV 中,应用最广泛的图像处理库当然就是长久维护的OpenCV 了,它拥有非常广泛的图像处理操作,基本能满足各种视觉任务的预/后处理所需。但是随着图像任务负载的加大,它的速度已经有点慢慢跟不上了,因为OpenCV 绝大多数图像操作都是 CPU 实现,缺少 GPU 实现,或者 GPU 实现本来就存在一些问题。

在NVIDIA与字节跳动算法同学的研发经验中,他们发现OpenCV 中那些少数有 GPU 实现的算子存在三大问题:

部分算子的 CPU 和 GPU 结果精度无法对齐;

部分算子 GPU 性能比 CPU 性能还弱;

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
首先,你需要安装并配置好 OpenCVCUDA。 接下来,你可以使用以下代码实现 MSR 图像增强: ```cpp #include <iostream> #include <opencv2/opencv.hpp> #include <opencv2/cudaarithm.hpp> #include <opencv2/cudafilters.hpp> using namespace std; using namespace cv; int main() { // 读取图像 Mat src = imread("test.jpg", IMREAD_COLOR); if (src.empty()) { cerr << "Failed to read image!" << endl; return -1; } // 将图像转换为 CUDA 格式 cuda::GpuMat d_src(src); cuda::GpuMat d_dst; // 计算图像的均值和标准差 Scalar mean, stddev; cuda::cvtColor(d_src, d_dst, COLOR_BGR2GRAY); cuda::meanStdDev(d_dst, mean, stddev); // 对图像进行 MSR 增强 cuda::subtract(d_src, mean, d_dst); cuda::multiply(d_dst, 128.0 / stddev.val[0], d_dst); cuda::add(d_dst, Scalar(128, 128, 128), d_dst); // 将 CUDA 格式的图像转换为 Mat 格式 Mat dst(d_dst); // 显示原图和增强后的图像 namedWindow("Original Image", WINDOW_NORMAL); namedWindow("Enhanced Image", WINDOW_NORMAL); imshow("Original Image", src); imshow("Enhanced Image", dst); waitKey(); return 0; } ``` 在这个代码中,我们首先读取了一张测试图片,然后将其转换为 CUDA 格式。接下来,我们使用 `cuda::cvtColor` 函数将图像转换为灰度图。然后,我们使用 `cuda::meanStdDev` 函数计算图像的均值和标准差。最后,我们使用 `cuda::subtract`、`cuda::multiply` 和 `cuda::add` 函数对图像进行 MSR 增强。最后,我们将增强后的 CUDA 格式的图像转换为 Mat 格式,并显示原图和增强后的图像。 需要注意的是,由于 MSR 图像增强是一种比较耗时的操作,因此在处理大型图像时可能会出现性能问题。为了解决这个问题,可以考虑将图像分成多个小块进行处理,或者使用更高级的算法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值