OpenCV CUDA 模块中的矩阵算术运算-----在频域(复数频谱)中执行逐元素乘法并缩放的函数mulAndScaleSpectrums()

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

算法描述

mulAndScaleSpectrums()是OpenCV CUDA模块中用于在频域(复数频谱)中执行逐元素乘法并缩放 的函数。

这个函数主要用于在 傅里叶变换后的频域空间中进行滤波、卷积、图像配准等操作。它实现了以下运算:
d s t = s c a l e ⋅ s r c 1 ⋅ ( c o n j B ? c o n j ( s r c 2 ) : s r c 2 ) dst=scale⋅src1⋅(conjB ? conj(src2) : src2) dst=scale⋅src1⋅(conjB?conj(src2):src2)

其中:

  • src1 和 src2 是两个复数格式的频谱(CV_32FC2)
  • conjB 控制是否对 src2 进行共轭
  • scale 是一个可选的缩放因子
  • flags 可控制额外的操作(如零填充、频谱重排)

函数原型

cpp 复制代码
void cv::cuda::mulAndScaleSpectrums
(
    InputArray src1,
    InputArray src2,
    OutputArray dst,
    int flags,
    float scale,
    bool conjB = false,
    Stream& stream = Stream::Null()
)

参数

参数说明

参数名 类型 是否必需 默认值 描述
src1 InputArray 第一个输入频谱(复数形式,CV_32FC2
src2 InputArray 第二个输入频谱(复数形式,CV_32FC2
dst OutputArray 输出结果,也是复数形式(CV_32FC2
flags int 标志位,通常与 dft() 中一致(如 cv::DFT_ROWS, cv::DFT_COMPLEX_OUTPUT
scale float 缩放因子(常用于归一化)
conjB bool false 是否对 src2 取共轭(用于相关计算或匹配)
stream Stream& Stream::Null() CUDA 流对象,用于异步执行

代码示例

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

int main()
{
    // 创建测试图像(单通道浮点型)
    cv::Mat h_imgA = cv::Mat::zeros(512, 512, CV_32F);
    cv::rectangle(h_imgA, cv::Rect(100, 100, 100, 100), cv::Scalar(255), -1);

    cv::Mat h_imgB = h_imgA.clone();
    cv::warpAffine(h_imgB, h_imgB, cv::getRotationMatrix2D(cv::Point2f(256, 256), 10, 1), h_imgB.size());

    // 上传到 GPU
    cv::cuda::GpuMat d_imgA, d_imgB;
    d_imgA.upload(h_imgA);
    d_imgB.upload(h_imgB);

    // 扩展图像至最优 DFT 尺寸(提高计算效率)
    cv::cuda::GpuMat d_imgA_padded, d_imgB_padded;
    cv::cuda::copyMakeBorder(d_imgA, d_imgA_padded, 0, 0, 0, 0, cv::BORDER_CONSTANT, cv::Scalar::all(0));
    cv::cuda::copyMakeBorder(d_imgB, d_imgB_padded, 0, 0, 0, 0, cv::BORDER_CONSTANT, cv::Scalar::all(0));

    // 执行 DFT(输出复数,2通道)
    cv::cuda::GpuMat d_fftA, d_fftB;
    cv::cuda::dft(d_imgA_padded, d_fftA, d_imgA_padded.size(), 0);
    cv::cuda::dft(d_imgB_padded, d_fftB, d_imgB_padded.size(), 0);

    // 频域乘法 + 共轭(互相关)
    cv::cuda::GpuMat d_corr;
    cv::cuda::mulSpectrums(d_fftA, d_fftB, d_corr, cv::DFT_ROWS, true); // 使用共轭

    // 逆变换得到空间域互相关图(复数)
    cv::cuda::GpuMat d_icorr;
    cv::cuda::dft(d_corr, d_icorr, d_corr.size(), cv::DFT_INVERSE | cv::DFT_SCALE);

    // 提取实部(互相关结果是实数)
    std::vector<cv::cuda::GpuMat> planes;
    cv::cuda::split(d_icorr, planes); // 分离复数结果的实部和虚部
    cv::cuda::GpuMat d_icorr_real = planes[0]; // 提取实部

    // 下载并归一化
    cv::Mat h_icorr;
    d_icorr_real.download(h_icorr);
    cv::normalize(h_icorr, h_icorr, 0, 1, cv::NORM_MINMAX);

    // 找到峰值位置(匹配点)
    cv::Point max_loc;
    cv::minMaxLoc(h_icorr, nullptr, nullptr, nullptr, &max_loc);
    std::cout << "Peak at: " << max_loc << std::endl;

    // 可视化(绘制峰值)
    cv::Mat h_icorr_display;
    h_icorr.convertTo(h_icorr_display, CV_8UC1, 255.0);
    cv::cvtColor(h_icorr_display, h_icorr_display, cv::COLOR_GRAY2BGR);
    cv::circle(h_icorr_display, max_loc, 5, cv::Scalar(0, 0, 255), 2);

    cv::imshow("Cross Correlation", h_icorr_display);
    cv::waitKey(0);

    return 0;
}

运行结果

bash 复制代码
Peak at: [8, 492]
相关推荐
蹦蹦跳跳真可爱58911 小时前
Python----神经网络发(神经网络发展历程)
人工智能·python·深度学习·神经网络·计算机视觉
学步_技术11 小时前
增强现实—Flame: Learning to navigate with multimodal llm in urban environments
人工智能·机器学习·计算机视觉·语言模型·自然语言处理·ar
有Li13 小时前
分割任意组织:用于医学图像分割的单样本参考引导免训练自动点提示方法|文献速递-深度学习医疗AI最新文献
论文阅读·深度学习·计算机视觉
云云32113 小时前
亚矩阵云手机针对AdMob广告平台怎么进行多账号的广告风控
大数据·网络·线性代数·游戏·智能手机·矩阵
余=1853816280013 小时前
矩阵系统源码开发技术难题与应对策略
线性代数·矩阵
終不似少年遊*13 小时前
机器学习方法实现数独矩阵识别器
人工智能·python·opencv·机器学习·计算机视觉·矩阵
心动啊12113 小时前
Numpy7——数学2(矩阵基础(矩阵的逆和行列式),线性方程基础)
线性代数·矩阵·numpy
硅谷秋水15 小时前
TASTE-Rob:推进面向任务的手-目标交互视频生成,实现可通用的机器人操作
人工智能·深度学习·机器学习·计算机视觉·机器人·交互
孚为智能科技16 小时前
集装箱残损识别系统如何检测残损?它的识别率能达到多少?
大数据·图像处理·人工智能·计算机视觉·视觉检测
jndingxin17 小时前
OpenCV CUDA模块图像变形------对图像进行 尺寸缩放(Resize)操作函数resize()
人工智能·opencv·计算机视觉