OpenCV CUDA模块设备层-----欧几里得距离函数hypot()

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

算法描述

该函数用于计算两个无符号字符向量(uchar1)的欧几里得距离(即直角三角形的斜边长度),公式为 d = a 2 + b 2 d = \sqrt{a^2 + b^2} % d=a2+b2

​,结果以单精度浮点向量(float1)返回。
主要应用于图像处理中的像素距离计算、特征匹配等场景,通过GPU并行加速提升性能.

函数原型‌

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

参数

参数 类型 描述
a const uchar1& 输入的无符号字符向量(单通道,值域0-255)。
b const uchar1& 输入的无符号字符向量(单通道,值域0-255)。

‌注意‌:输入值超出0-255范围可能导致浮点溢出。

返回值‌

  • ‌类型‌:float1
  • 返回单精度浮点向量,值为 a 2 + b 2 \sqrt{a^2 + b^2} a2+b2 ​ 的计算结果。

代码示例



#include <opencv2/opencv.hpp>
#include <opencv2/cudev/common.hpp>
#include <opencv2/cudev/util/vec_math.hpp>

__global__ void kernel_hypot(const cv::cudev::PtrStepSz<uchar1> src1, 
                            const cv::cudev::PtrStepSz<uchar1> src2,
                            cv::cudev::PtrStepSz<float1> dst) {
    int x = blockIdx.x * blockDim.x + threadIdx.x;
    int y = blockIdx.y * blockDim.y + threadIdx.y;
    
    if (x < src1.cols && y < src1.rows) {
        dst(y, x) = cv::cudev::hypot(src1(y, x), src2(y, x));
    }
}

int main() {
    // 1. 准备测试数据
    cv::Mat h_src1(512, 512, CV_8UC1);
    cv::Mat h_src2(512, 512, CV_8UC1);
    cv::randu(h_src1, 0, 255);
    cv::randu(h_src2, 0, 255);

    // 2. 上传数据到GPU
    cv::cuda::GpuMat d_src1, d_src2, d_dst;
    d_src1.upload(h_src1);
    d_src2.upload(h_src2);
    d_dst.create(h_src1.size(), CV_32FC1);

    // 3. 调用核函数
    dim3 block(16, 16);
    dim3 grid((h_src1.cols + block.x - 1) / block.x, 
              (h_src1.rows + block.y - 1) / block.y);
    
    kernel_hypot<<<grid, block>>>(
        cv::cudev::PtrStepSz<uchar1>(d_src1),
        cv::cudev::PtrStepSz<uchar1>(d_src2),
        cv::cudev::PtrStepSz<float1>(d_dst)
    );

    // 4. 验证结果
    cv::Mat h_dst;
    d_dst.download(h_dst);
    std::cout << "Sample result: " << h_dst.at<float>(0,0) << std::endl;

    return 0;
}

运行结果

Sample result: 199.023

网站公告

今日签到

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