CUDA系列二、CUDA图像标准化
CUDA系列二、CUDA图像标准化
一、概述
在上一篇文章CUDA系列一、CUDA简介 中我们对CUDA进行了介绍,了解到CUDA能让开发者利用GPU的强大算力进行大规模的并行计算,在本篇文章中将介绍如何使用cuda进行图像标准化。
图像标准化在视觉领域内有广泛的应用,通过标准化能使图像数据有更稳定的分布,从而提高模型的训练效果和泛化能力,所以在图像相关的模型部署过程中,图像标化通是模型预处理的第一步,本篇通过图像标准化代码详细介绍并行带来的优势。
二、图像标准化原理
图像标准化,是将图像像素值调整到特定分布范围的操作,通常是把图像均值调整为0,标准差调整为1 。对于一幅图像,其标准化公式为:
[
I_{norm}(x,y) = \frac{I(x,y) - \mu}{\sigma}
]
其中,(I(x,y)) 是原始图像在坐标 ((x,y)) 处的像素值,(\mu) 是图像的均值,(\sigma) 是图像的标准差。通俗的讲就是每个像素需要减去均值再除以标准差。
三、代码及解析
3.1 头文件
下面代码是 cu_standardization.hpp头文件 ,使用OpenCV读取和存储图像,所以需要加载OpenCV相关的库,然后声明了一个 standardizationRGB函数用于图像的标准化调用。
1
2
3
4
5
6
7
8
9
10
11
12 #pragma once
#include <array>
#include <memory>
#include <string>
#include <vector>
#include <opencv2/highgui/highgui.hpp>
#include <chrono>
#include <opencv2/opencv.hpp>
#include <device_launch_parameters.h>
#include "opencv2/core/cuda/common.hpp"
//标准化
void standardizationRGB(const cv::cuda::GpuMat cu_src, cv::cuda::GpuMat cu_dst);
3.2 标准化核心文件
下面代码是 cu_standardization.cu文件,的首先通过 cpp__constant__ 常量内存定义了RGB图像的均值和方差,常量内存在核函数执行期间不会发生变化,且数据在所有线程共享。然后__global__ void kenlStandardizationRGB 核函数中,根据均值和标准差对每个像素进行标准差处理,由于是RGB图像,所以每个个线程独立负责某一坐标下的RGB三个像素值的计算 。void standardizationRGB 函数定义了线程块的大小为BLOCK_SIZExBLOCK_SIZE=1024,cv::cuda::device::divUp用于向上取整的除法运算,所以开辟的总线程数量是≥图像的宽x高的。``cv::cuda::PtrStepSz```是 OpenCV 中用于在 CUDA 设备上处理二维数组的类,它封装了二维数组的行数、列数、数据指针以及每行的步长信息,我们将图像传入到这个类中便于核函数的调用。
1 | |
3.3 主函数
下面代码是执行的主函数,main.cpp,这个文件加载cu_standardization.hpp头文件,并使用OpenCV读取一张彩色图像,并使用 cv::cuda::GpuMat 将图像将主机的图像传入到设备的图像,也就是cpu中的Mat到GPU中的Mat,然后定义一个和输入图像一样大小的GPU图像作为输出值,调用standardizationRGB对图像进行标准化,最后将标准化的图像从GPU中拷贝到CPU中。
1 | |
这就是整个GPU处理图像标准化的全过程,希望这篇文章能带你正式走进CUDA的开发之路。
注。1
本文仅供学习参考,未经允许,拒绝转载或者用作他用。