- 操作系统: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());
// 上传到 GPU
cv::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;
}