OpenCV CUDA模块设备层-----像素值进行逐通道的最大值比较函数max()

发布于:2025-06-29 ⋅ 阅读:(18) ⋅ 点赞:(0)
  • 操作系统:ubuntu22.04
  • OpenCV版本:OpenCV4.9
  • IDE:Visual Studio Code
  • 编程语言:C++11

算法描述

是 OpenCV 的 CUDA 模块(cv::cudev) 中的一个 设备端内联函数(device function),用于在 CUDA 核函数中对两个 uchar1 类型像素值进行逐通道的最大值比较。
对两个 uchar1 类型变量(即单通道无符号字符类型)进行逐通道比较,返回每个通道中的最大值。
由于 uchar1 是单通道数据类型(等价于 unsigned char),因此这个函数实际上就是返回 a 和 b 中较大的那个值。
它通常用于图像处理中实现 像素级最大值滤波、图像融合、阈值操作等 GPU 加速场景。

函数原型

__device__ __forceinline__ uchar1 cv::cudev::max 	( 	const uchar1 &  	a,
		const uchar1 &  	b 
	) 		

参数

  • a const uchar1& 第一个输入像素值
  • b const uchar1& 第二个输入像素值

返回值

  • 返回一个新的 uchar1 值,表示 a 和 b 的最大值。
  • 因为是单通道类型,所以直接返回 max(a.x, b.x)。

代码


#include <opencv2/cudaimgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/cudev/util/vec_math.hpp>

using namespace cv;
using namespace cv::cudev;

// CUDA 核函数:取两个图像像素的最大值
template <typename Ptr1, typename Ptr2, typename DstPtr>
__global__ void maxKernel(Ptr1 src1, Ptr2 src2, 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) {
        // 获取两个图像的像素值
        uchar1 val1 = src1(y, x);
        uchar1 val2 = src2(y, x);

        // 取最大值并写入输出图像
        dst(y, x) = max(val1, val2);
    }
}

int main() {
    // 加载两张图像(假设尺寸相同)
    Mat h_img1 = imread("/media/dingxin/data/study/OpenCV/sources/images/img0.jpg", IMREAD_GRAYSCALE);
    Mat h_img2 = imread("/media/dingxin/data/study/OpenCV/sources/images/img1.jpg", IMREAD_GRAYSCALE);

    if (h_img1.empty() || h_img2.empty()) {
        std::cerr << "Failed to load images!" << std::endl;
        return -1;
    }

    // 上传到 GPU
    cuda::GpuMat d_img1, d_img2, d_result;
    d_img1.upload(h_img1);
    d_img2.upload(h_img2);
    d_result.create(d_img1.size(), d_img1.type());

    // 构造 PtrStepSz 访问器
    auto ptr1 = PtrStepSz<uchar1>(d_img1);
    auto ptr2 = PtrStepSz<uchar1>(d_img2);
    auto dptr = PtrStepSz<uchar1>(d_result);

    // 设置核函数参数
    dim3 block(16, 16);
    dim3 grid((d_img1.cols + block.x - 1) / block.x,
              (d_img1.rows + block.y - 1) / block.y);

    // 调用核函数
    maxKernel<<<grid, block>>>(ptr1, ptr2, dptr, d_img1.cols, d_img1.rows);
    cudaDeviceSynchronize();

    // 下载结果并显示
    Mat h_result;
    d_result.download(h_result);
    imshow("Max Image", h_result);
    waitKey(0);

    return 0;
}

运行结果

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到