- 操作系统:ubuntu22.04
- OpenCV版本:OpenCV4.9
- IDE:Visual Studio Code
- 编程语言:C++11
算法描述
该函数接收一个 uchar1 类型的像素值(范围 [0, 255]),将其归一化到 [0, 1] 范围后映射到 [0, 1] 或 [-1, 1](根据实现),然后计算其 反双曲正弦值(asinh),并返回一个 float1 类型的结果。
函数原型
cpp
__device__ __forceinline__ float1 cv::cudev::asinh ( const uchar1 & a )
参数
- uchar1 CUDA 内建向量类型,等价于单通道无符号字符(即 unsigned char,取值范围 [0, 255])
示例代码
cpp
#include <opencv2/opencv.hpp>
#include <opencv2/cudaimgproc.hpp> // cuda::GpuMat
#include <opencv2/cudev/functional/functional.hpp> // cv::cudev::asinh
#include <iostream>
using namespace cv;
using namespace cudev;
// CUDA 核函数定义
__global__ void asinhKernel(const uchar* srcData, float* dstData,
int width, int height, size_t srcStep, size_t dstStep)
{
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
if (x < width && y < height)
{
// 手动计算偏移量
const uchar* rowSrc = reinterpret_cast<const uchar*>(reinterpret_cast<uintptr_t>(srcData) + y * srcStep);
float* rowDst = reinterpret_cast<float*>(reinterpret_cast<uintptr_t>(dstData) + y * dstStep);
uchar1 pixel;
pixel.x = rowSrc[x]; // 获取输入像素值
float1 result = cv::cudev::asinh(pixel); // 调用设备端 asinh 函数
rowDst[x] = result.x; // 存储输出结果
}
}
int main(int argc, char* argv[])
{
std::string imagePath = "/media/dingxin/data/study/OpenCV/sources/images/Lenna.png";
// 1. 加载图像(灰度图)
Mat h_src = imread(imagePath, IMREAD_GRAYSCALE);
if (h_src.empty())
{
std::cerr << "Failed to load image: " << imagePath << std::endl;
return -1;
}
// 2. 上传图像到 GPU
cuda::GpuMat d_src, d_dst;
d_src.upload(h_src);
// 创建输出图像(float 类型)
d_dst.create(h_src.size(), CV_32FC1);
// 3. 配置 CUDA 核函数参数
dim3 block(16, 16);
dim3 grid((h_src.cols + block.x - 1) / block.x,
(h_src.rows + block.y - 1) / block.y);
// 4. 启动核函数
asinhKernel<<<grid, block>>>(
d_src.ptr<uchar>(), d_dst.ptr<float>(),
h_src.cols, h_src.rows,
d_src.step, d_dst.step
);
cudaDeviceSynchronize(); // 确保核函数执行完成
// 5. 下载结果并归一化显示
Mat h_result;
d_dst.download(h_result);
// 归一化到 [0, 255] 显示
Mat h_display;
normalize(h_result, h_display, 0, 255, NORM_MINMAX, CV_8UC1);
// 显示结果
imshow("Original Image", h_src);
imshow("Asinh Transformed", h_display);
std::cout << "Press any key to exit..." << std::endl;
waitKey(0);
return 0;
}
运行结果
