OpenCV CUDA模块中矩阵操作------范数(Norm)相关函数

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

算法描述

在 OpenCV 的 CUDA 模块中,与范数(Norm)相关的函数主要用于计算矩阵的范数或者两个矩阵之间的差值范数。

主要函数

1.计算单个 GPU 矩阵的范数:norm

原型
cpp 复制代码
double cv::cuda::norm
(
    InputArray src1,                // 输入 GPU 矩阵
    int normType = NORM_L2,         // 范数类型,默认为L2范数
    InputArray mask = noArray()     // 可选掩码,用于选择性地应用范数计算到src1的部分区域
);
参数
  • InputArray src1: 需要计算范数的输入 GPU 矩阵。
  • int normType: 指定使用的范数类型。常见的有:
    • NORM_INF: 无穷范数,等于绝对值最大的元素。
    • NORM_L1: L1范数,所有元素绝对值之和。
    • NORM_L2: L2范数,平方和的平方根。
  • InputArray mask: 可选参数,如果提供,则只对mask中非零元素对应的src1部分进行计算。

2.计算两个 GPU 矩阵之间的差值范数norm

原型
cpp 复制代码
double cv::cuda::norm
(
    InputArray src1,                // 第一个输入 GPU 矩阵
    InputArray src2,                // 第二个输入 GPU 矩阵,尺寸/类型相同
    int normType = NORM_L2          // 范数类型,默认为L2范数
);
参数
  • InputArray src2: 第二个输入 GPU 矩阵,要求与src1具有相同的尺寸和通道数。
  • 其余参数同上。

3.异步计算单个 GPU 矩阵的范数calcNorm

原型
cpp 复制代码
void cv::cuda::calcNorm
(
    InputArray src,                 // 输入 GPU 矩阵
    OutputArray dst,                // 输出结果,标量
    int normType,                   // 范数类型
    InputArray mask = noArray(),    // 可选掩码
    Stream& stream = Stream::Null() // 可选 CUDA 流
);
参数
  • OutputArray dst: 输出结果,通常是一个 GpuMat 或者 Scalar,表示计算出的范数值。
  • Stream& stream: 可选参数,指定执行此操作的CUDA流,默认为 Stream::Null() 表示使用默认流。

4.异步计算两个 GPU 矩阵之间的差值范数calcNormDiff

原型
cpp 复制代码
void cv::cuda::calcNormDiff
(
    InputArray src1,                // 第一个输入 GPU 矩阵
    InputArray src2,                // 第二个输入 GPU 矩阵,尺寸/类型相同
    OutputArray dst,                // 输出结果,标量
    int normType = NORM_L2,         // 范数类型,默认为L2范数
    Stream& stream = Stream::Null() // 可选 CUDA 流
);
参数
  • InputArray src2: 第二个输入 GPU 矩阵,要求与src1具有相同的尺寸和通道数。
  • 其余参数同上。

代码示例

cpp 复制代码
#include <opencv2/opencv.hpp>
#include <opencv2/cudaarithm.hpp>
#include <iostream>

int main() {
    // 创建两个 float 类型的 3x3 测试矩阵
    cv::Mat h_mat1 = (cv::Mat_<float>(3, 3) <<
                      1.0f, -2.0f,  3.0f,
                     -4.0f,  5.0f, -6.0f,
                      7.0f, -8.0f,  9.0f);

    cv::Mat h_mat2 = cv::Mat::zeros(h_mat1.size(), h_mat1.type());

    // 创建一个 mask 矩阵(只允许中心区域参与计算)
    cv::Mat h_mask = cv::Mat::zeros(h_mat1.size(), CV_8UC1);
    cv::rectangle(h_mask, cv::Rect(1, 1, 1, 1), cv::Scalar(255), cv::FILLED); // 中心像素

    // 将数据转换为 CV_8UC1 类型
    cv::Mat h_mat1_8u, h_mat2_8u;
    h_mat1.convertTo(h_mat1_8u, CV_8UC1);
    h_mat2.convertTo(h_mat2_8u, CV_8UC1);

    // 上传到 GPU
    cv::cuda::GpuMat d_mat1, d_mat2, d_mask;
    d_mat1.upload(h_mat1_8u);
    d_mat2.upload(h_mat2_8u);
    d_mask.upload(h_mask);

    // 存储异步结果的 GpuMat
    cv::cuda::GpuMat d_norm_result;

    // 创建 CUDA 流
    cv::cuda::Stream stream;

    // 1️⃣ 同步:单矩阵 L2 范数(带 mask)
    double l2_norm = cv::cuda::norm(d_mat1, cv::NORM_L2, d_mask);
    std::cout << "Sync L2 Norm of mat1 (with mask): " << l2_norm << std::endl;

    // 2️⃣ 同步:两矩阵之间的 L2 差值范数
    double diff_norm = cv::cuda::norm(d_mat1, d_mat2, cv::NORM_L2);
    std::cout << "Sync L2 Diff Norm between mat1 and mat2: " << diff_norm << std::endl;

    // 3️⃣ 异步:单矩阵 L1 范数
    cv::cuda::calcNorm(d_mat1, d_norm_result, cv::NORM_L1, cv::noArray(), stream);
    stream.waitForCompletion();

    cv::Mat host_norm;
    d_norm_result.download(host_norm);
    double async_l1_norm = host_norm.at<double>(0, 0);
    std::cout << "Async L1 Norm of mat1: " << async_l1_norm << std::endl;

    // 4️⃣ ✅ 异步:两个矩阵之间的 L2 差值范数(必须调用 calcNormDiff)
    cv::cuda::calcNormDiff(d_mat1, d_mat2, d_norm_result, cv::NORM_L2, stream);
    stream.waitForCompletion();

    d_norm_result.download(host_norm);
    double async_diff_norm = host_norm.at<double>(0, 0);
    std::cout << "Async L2 Diff Norm between mat1 and mat2: " << async_diff_norm << std::endl;

    return 0;
}

运行结果

bash 复制代码
Sync L2 Norm of mat1 (with mask): 5
Sync L2 Diff Norm between mat1 and mat2: 12.8452
Async L1 Norm of mat1: 25
Async L2 Diff Norm between mat1 and mat2: 12.8452
相关推荐
美狐美颜sdk33 分钟前
跨平台直播美颜SDK集成实录:Android/iOS如何适配贴纸功能
android·人工智能·ios·架构·音视频·美颜sdk·第三方美颜sdk
DeepSeek-大模型系统教程1 小时前
推荐 7 个本周 yyds 的 GitHub 项目。
人工智能·ai·语言模型·大模型·github·ai大模型·大模型学习
郭庆汝1 小时前
pytorch、torchvision与python版本对应关系
人工智能·pytorch·python
小雷FansUnion3 小时前
深入理解MCP架构:智能服务编排、上下文管理与动态路由实战
人工智能·架构·大模型·mcp
资讯分享周3 小时前
扣子空间PPT生产力升级:AI智能生成与多模态创作新时代
人工智能·powerpoint
叶子爱分享4 小时前
计算机视觉与图像处理的关系
图像处理·人工智能·计算机视觉
鱼摆摆拜拜4 小时前
第 3 章:神经网络如何学习
人工智能·神经网络·学习
一只鹿鹿鹿4 小时前
信息化项目验收,软件工程评审和检查表单
大数据·人工智能·后端·智慧城市·软件工程
张较瘦_4 小时前
[论文阅读] 人工智能 | 深度学习系统崩溃恢复新方案:DaiFu框架的原位修复技术
论文阅读·人工智能·深度学习
cver1234 小时前
野生动物检测数据集介绍-5,138张图片 野生动物保护监测 智能狩猎相机系统 生态研究与调查
人工智能·pytorch·深度学习·目标检测·计算机视觉·目标跟踪