Matlab 中的 fftshift 函数将信号频谱的零频分量移动到数组中心, ifftshift完成相反的操作. fftshift 和 ifftshift 函数的本质是分别对调一三象限, 二四象限的数据块.
OpenCV中没有实现此函数, 以下是我个人编写的基于OpenCV的fftshift 和 ifftshift函数.
/**
* @brief Shift zero-frequency component to center of spectrum
*
* @param src
* @return cv::Mat
*/
cv::Mat fftshift(cv::Mat src)
{
cv::Mat dst(src.size(), src.type());
int x0 = src.cols / 2;
int x1 = src.cols - x0;
int y0 = src.rows / 2;
int y1 = src.rows - y0;
cv::Mat src_b0(src, cv::Rect(0, 0, x1, y1));
cv::Mat src_b1(src, cv::Rect(x1, 0, x0, y1));
cv::Mat src_b2(src, cv::Rect(0, y1, x1, y0));
cv::Mat src_b3(src, cv::Rect(x1, y1, x0, y0));
cv::Mat dst_b0(dst, cv::Rect(0, 0, x0, y0));
cv::Mat dst_b1(dst, cv::Rect(x0, 0, x1, y0));
cv::Mat dst_b2(dst, cv::Rect(0, y0, x0, y1));
cv::Mat dst_b3(dst, cv::Rect(x0, y0, x1, y1));
src_b1.copyTo(dst_b2);
src_b2.copyTo(dst_b1);
src_b0.copyTo(dst_b3);
src_b3.copyTo(dst_b0);
return dst;
}
/**
* @brief Inverse zero-frequency shift
*
* @param src
* @return cv::Mat
*/
cv::Mat ifftshift(cv::Mat src)
{
cv::Mat dst(src.size(), src.type());
int x1 = src.cols / 2;
int x0 = src.cols - x1;
int y1 = src.rows / 2;
int y0 = src.rows - y1;
cv::Mat src_b0(src, cv::Rect(0, 0, x1, y1));
cv::Mat src_b1(src, cv::Rect(x1, 0, x0, y1));
cv::Mat src_b2(src, cv::Rect(0, y1, x1, y0));
cv::Mat src_b3(src, cv::Rect(x1, y1, x0, y0));
cv::Mat dst_b0(dst, cv::Rect(0, 0, x0, y0));
cv::Mat dst_b1(dst, cv::Rect(x0, 0, x1, y0));
cv::Mat dst_b2(dst, cv::Rect(0, y0, x0, y1));
cv::Mat dst_b3(dst, cv::Rect(x0, y0, x1, y1));
src_b1.copyTo(dst_b2);
src_b2.copyTo(dst_b1);
src_b0.copyTo(dst_b3);
src_b3.copyTo(dst_b0);
return dst;
}
以下是示例程序:
void test_fftshift()
{
cv::Mat1d x({2,2}, {1,2,3,4});
cv::Mat1d y = fftshift(x);
std::cout << y << std::endl;
cv::Mat1d x1({3,3}, {1,2,3,4,5,6,7,8,9});
cv::Mat1d y1 = fftshift(x1);
std::cout << y1 << std::endl;
}
void test_ifftshift()
{
cv::Mat1d x({2,2}, {1,2,3,4});
cv::Mat1d y = ifftshift(x);
std::cout << y << std::endl;
cv::Mat1d x1({3,3}, {1,2,3,4,5,6,7,8,9});
cv::Mat1d y1 = ifftshift(x1);
std::cout << y1 << std::endl;
}
fftshift()测试结果如下图所示:

ifftshift()测试结果如下图所示:

与matlab的结果对比一致:


希望以上内容对您有所帮助!!!

本文介绍如何在 OpenCV 中实现 Matlab 的 fftshift 和 ifftshift 功能,用于处理信号频谱的零频分量位置调整。提供了详细的代码示例,并验证了其正确性。

1371

被折叠的 条评论
为什么被折叠?



