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
的结果对比一致:
希望以上内容对您有所帮助!!!