OpenCV CUDA模块设备层-----逐通道的正弦运算函数sin()
- 操作系统:ubuntu22.04
- OpenCV版本:OpenCV4.9
- IDE:Visual Studio Code
- 编程语言:C++11
算法描述
OpenCV 的 CUDA 模块(cv::cudev) 中的一个设备端数学函数,用于在 CUDA 核函数中对 uchar4 类型(即 4 通道无符号字符类型)进行 逐通道的正弦运算,并将结果转换为 float4 类型输出。
将一个 uchar4 类型像素值(每个通道取值范围 [0, 255])逐通道转换为浮点数,并计算其正弦值(单位:弧度),返回 float4 类型结果。
这在图像处理、颜色空间变换或 GPU 数学计算中有一定用途,尤其是在需要对图像像素进行三角函数变换时。
函数原型
__device__ __forceinline__ float4 cv::cudev::sin ( const uchar4 & a )
参数
- a const uchar4& 输入的 4 通道无符号字符向量(如 RGBA 图像中的一个像素)
返回值
- 返回一个新的 float4 值;
- 每个通道的值为 sin((float)a.x), sin((float)a.y), sin((float)a.z), sin((float)a.w);
- 输入会先被转换为浮点数,再调用 CUDA 的 sinf(…) 函数计算正弦值。
代码
#include <opencv2/cudaimgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/cudev/util/vec_math.hpp>using namespace cv;
using namespace cv::cudev;// CUDA 核函数:将 uchar4 像素转换为 float4 并计算正弦值
template <typename SrcPtr, typename DstPtr>
__global__ void sinKernel(SrcPtr src, DstPtr dst, int width, int height) {int x = blockIdx.x * blockDim.x + threadIdx.x;int y = blockIdx.y * blockDim.y + threadIdx.y;if (x < width && y < height) {// 获取输入像素uchar4 val = src(y, x);// 将每个通道转换为浮点数,并除以 255,映射到 [0,1]float4 normalized = make_float4(static_cast<float>(val.x) / 255.0f,static_cast<float>(val.y) / 255.0f,static_cast<float>(val.z) / 255.0f,static_cast<float>(val.w) / 255.0f);// 计算正弦值(弧度制)float4 sinVal = make_float4(sinf(normalized.x * 2.0f * (float)CV_PI), // 映射到 [0, 2π]sinf(normalized.y * 2.0f * (float)CV_PI),sinf(normalized.z * 2.0f * (float)CV_PI),sinf(normalized.w * 2.0f * (float)CV_PI));// 写入输出图像dst(y, x) = sinVal;}
}int main() {// 加载图像(RGBA 或 RGB)Mat h_img = imread("/media/dingxin/data/study/OpenCV/sources/images/img0.jpg", IMREAD_UNCHANGED);if (h_img.empty()) {std::cerr << "Failed to load image!" << std::endl;return -1;}// 转换为 4 通道 RGBA 格式Mat h_rgba;if (h_img.channels() == 3) {cv::cvtColor(h_img, h_rgba, COLOR_BGR2BGRA);} else if (h_img.channels() == 1) {cv::cvtColor(h_img, h_rgba, COLOR_GRAY2BGRA);} else {h_rgba = h_img.clone();}// 上传到 GPUcuda::GpuMat d_rgba, d_result;d_rgba.upload(h_rgba);d_result.create(d_rgba.size(), CV_32FC4); // float4 对应 CV_32FC4// 构造 PtrStepSz 访问器auto ptr = PtrStepSz<uchar4>(d_rgba);auto dptr = PtrStepSz<float4>(d_result);// 设置核函数参数dim3 block(16, 16);dim3 grid((d_rgba.cols + block.x - 1) / block.x,(d_rgba.rows + block.y - 1) / block.y);// 调用核函数sinKernel<<<grid, block>>>(ptr, dptr, d_rgba.cols, d_rgba.rows);cudaDeviceSynchronize();// 下载结果Mat h_result;d_result.download(h_result);// 归一化到 [0, 1] 用于显示Mat display;normalize(h_result, display, 0, 1, NORM_MINMAX, CV_32FC4);// 显示图像imshow("Sin Image", display);imwrite("output_sin_image.png", display * 255); // 保存为 PNGwaitKey(0);return 0;
}