OpenCV CUDA 模块中的矩阵算术运算-----在频域中执行两个复数频谱的逐元素乘法的函数mulSpectrums()
- 操作系统:ubuntu22.04
- OpenCV版本:OpenCV4.9
- IDE:Visual Studio Code
- 编程语言:C++11
算法描述
mulSpectrums()是OpenCV CUDA 模块中用于在频域中执行两个复数频谱的逐元素乘法的函数。
该函数实现了以下运算:
d s t = s r c 1 ⋅ ( c o n j B ? c o n j ( s r c 2 ) : s r c 2 ) dst=src1⋅(conjB ? conj(src2) : src2) dst=src1⋅(conjB?conj(src2):src2)
即:
- 对两个复数频谱(CV_32FC2)进行逐元素相乘
- 可选地对 src2 进行共轭,用于图像配准、互相关等操作
与 mulAndScaleSpectrums 的区别
函数名 | 是否支持缩放因子 scale | 典型用途 |
---|---|---|
cv::cuda::mulSpectrums | ❌ 不带缩放 | 简单频域乘法 |
cv::cuda::mulAndScaleSpectrums | ✅ 带缩放 | 更通用,适合需要归一化或缩放的场景 |
参数
参数名 | 类型 | 是否必需 | 默认值 | 描述 |
---|---|---|---|---|
src1 | InputArray | 是 | 无 | 第一个输入频谱(复数形式,CV_32FC2 ) |
src2 | InputArray | 是 | 无 | 第二个输入频谱(复数形式,CV_32FC2 ) |
dst | OutputArray | 是 | 无 | 输出结果,也是复数形式(CV_32FC2 ) |
flags | int | 是 | 无 | 标志位,通常设为 0 ,也可与 DFT 标志一致 |
conjB | bool | 否 | false | 是否对 src2 取共轭(用于相关计算或匹配) |
stream | Stream& | 否 | Stream::Null() | CUDA 流对象,用于异步执行 |
代码示例
#include <opencv2/opencv.hpp>
#include <opencv2/cudaarithm.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.0), h_imgB.size());// 上传到 GPUcv::cuda::GpuMat d_imgA, d_imgB;d_imgA.upload(h_imgA);d_imgB.upload(h_imgB);// 执行 DFT(使用 OpenCV 4.9 推荐的命名空间)cv::cuda::GpuMat d_fftA, d_fftB;cv::cuda::dft(d_imgA, d_fftA, d_imgA.size(), 0);cv::cuda::dft(d_imgB, d_fftB, d_imgB.size(), 0);// 频域乘法 + 共轭(用于图像配准 / 互相关)cv::cuda::GpuMat d_corr;cv::cuda::mulSpectrums(d_fftA, d_fftB, d_corr, 0, true); // conjB=true for correlation// 逆变换得到空间域互相关图cv::cuda::GpuMat d_icorr;cv::cuda::dft(d_corr, d_icorr, d_corr.size(), cv::DFT_INVERSE | cv::DFT_SCALE);// 下载并显示结果cv::Mat h_icorr;d_icorr.download(h_icorr);// 处理逆变换后的结果std::vector<cv::Mat> planes;cv::split(h_icorr, planes); // 分离出实部和虚部// 计算幅度谱(sqrt(real^2 + imag^2))cv::Mat magnitude;cv::magnitude(planes[0], planes[1], magnitude);// 归一化幅度谱以便可视化cv::normalize(magnitude, magnitude, 0, 1, cv::NORM_MINMAX);cv::imshow("Cross Correlation", magnitude);cv::waitKey(0);return 0;
}