当前位置: 首页 > news >正文

OpenCV CUDA模块设备层-----双曲正弦函数sinh()

  • 操作系统:ubuntu22.04
  • OpenCV版本:OpenCV4.9
  • IDE:Visual Studio Code
  • 编程语言:C++11

算法描述

OpenCV的CUDA 模块(cv::cudev)中的一个设备端数学函数,用于在 GPU 上对 uchar3 类型的像素值(如RGB图像中的一个像素)逐通道计算双曲正弦函数(hyperbolic sine),并将结果转换为float3类型返回。

函数原型

__device__ __forceinline__ float3 cv::cudev::sinh 	( 	const uchar3 &  	a	) 	

参数

  • a const uchar3& 输入的 3 通道无符号字符向量(如 RGB 图像中的一个像素)。

返回值

  • 返回一个新的 float3 值;
  • 每个通道的值为 sinh((float)a.x), sinh((float)a.y), sinh((float)a.z);
  • 使用的是 CUDA 内建函数 sinhf(…) 来计算双曲正弦。

代码


#include <opencv2/cudaimgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/cudev/util/vec_math.hpp>using namespace cv;
using namespace cv::cudev;// CUDA 核函数:对 uchar3 像素计算 sinh,并确保输出在 [0,1]
template <typename SrcPtr, typename DstPtr>
__global__ void sinhKernel(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) {// 获取原始像素值uchar3 val = src(y, x);// Step 1: 将 uchar3 归一化到 [0,1]float scale = 1.0f / 255.0f;float fx = val.x * scale;float fy = val.y * scale;float fz = val.z * scale;// Step 2: 构造一个 "fake" uchar3 输入,表示 [0,1] 区间uchar3 fake_input;fake_input.x = static_cast<unsigned char>(fx * 255.0f);fake_input.y = static_cast<unsigned char>(fy * 255.0f);fake_input.z = static_cast<unsigned char>(fz * 255.0f);// Step 3: 调用 OpenCV 提供的 sinh 函数(唯一一次调用)float3 sinhVal = sinh(fake_input);  // ←←← 这里才是你想要的 cv::cudev::sinh(...)// Step 4: 将 sinh 输出压缩到 [0,1]const float inv_sinh1 = 1.0f / sinhf(1.0f);  // sinh([0,1]) ∈ [0, ~1.175]sinhVal.x *= inv_sinh1;sinhVal.y *= inv_sinh1;sinhVal.z *= inv_sinh1;// Step 5: 写入输出图像dst(y, x) = sinhVal;}
}int main() {// 加载图像Mat h_img = imread("/media/dingxin/data/study/OpenCV/sources/images/img0.jpg", IMREAD_COLOR);if (h_img.empty()) {std::cerr << "Failed to load image!" << std::endl;return -1;}// 上传到 GPUcuda::GpuMat d_img, d_result;d_img.upload(h_img);d_result.create(d_img.size(), CV_32FC3);  // float3 对应 CV_32FC3// 构造 PtrStepSz 访问器auto ptr = PtrStepSz<uchar3>(d_img);auto dptr = PtrStepSz<float3>(d_result);// 设置核函数参数dim3 block(16, 16);dim3 grid((d_img.cols + block.x - 1) / block.x,(d_img.rows + block.y - 1) / block.y);// 启动核函数sinhKernel<<<grid, block>>>(ptr, dptr, d_img.cols, d_img.rows);cudaDeviceSynchronize();// 下载并显示结果Mat h_result;d_result.download(h_result);imshow("Sinh Image", h_result);            // 已经是 [0,1] 浮点图像imwrite("output_sinh_image.png", h_result * 255);  // 保存为 PNGwaitKey(0);return 0;
}

运行结果

在这里插入图片描述

相关文章:

  • 【linux】程序地址空间
  • AI聊天多分支对话的纯前端实现
  • 19、RocketMQ核⼼编程模型
  • Nestjs框架: nestjs-schedule模块中的三类定时任务
  • 同样是synthesis(综合) HLS和Vivado里面是有什么区别
  • 商品中心—15.库存分桶扣减的技术文档
  • Hyperledger Fabric 入门笔记(二十)Fabric V2.5 测试网络进阶之Tape性能测试
  • 3.Stable Diffusion WebUI本地部署和实践
  • 论分布式设计
  • 基于Redis分布式的限流
  • springboot整合微信App支付以及支付宝App支付
  • opensuse安装rabbitmq
  • 使用 Azure 创建虚拟机所涉及的各项资源和设置
  • 探秘 VR 逃生救援技术的奇妙世界​
  • 鸿蒙HarmonyOS 5小游戏实践:记忆翻牌(附:源代码)
  • docker stats和/proc/pid/status内存统计的差异问题
  • 生成式人工智能实战 | WGAN(Wasserstein Generative Adversarial Network, GAN)
  • GO 语言学习 之 变量和常量
  • 【git学习】学习目标及课程安排
  • React Native 如何实现拉起App