基于opencv 的 fftshift 函数的实现

Matlab 中的 fftshift 函数将信号频谱的零频分量移动到数组中心. fftshift函数的本质是分别对调一三象限, 二四象限的数据块.
OpenCV中没有实现此函数, 以下是我个人编写的基于OpenCVfftshift函数.

/**
 * @brief 将零频分量移动到矩阵中心
 * 
 * @param _src 源矩阵
 * @param _dst 目标矩阵
 * 
 * @note 源矩阵和目标矩阵相同时, 结果异常. 未找到原因
 */
void fftshift(cv::InputArray _src, cv::OutputArray _dst)
{
    cv::Mat src = _src.getMat();
    _dst.create(src.size(), src.type());
    cv::Mat dst = _dst.getMat();

    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, y0));
    cv::Mat src_b2(src, cv::Rect(0, y1, x0, y0));
    cv::Mat src_b3(src, cv::Rect(x0, y0, x1, y1));
    cv::Mat dst_b0(dst, cv::Rect(0, 0, x1, y1));
    cv::Mat dst_b1(dst, cv::Rect(x1, 0, x0, y0));
    cv::Mat dst_b2(dst, cv::Rect(0, y1, x0, y0));
    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);
}

以下是示例程序:

void fftshift_test()
{
    // (7,8)的全1矩阵
    auto img = cv::Mat::ones(7, 8, CV_32FC1);
    cv::Mat img_c2;
    cv::merge(std::vector<cv::Mat>{img, cv::Mat::zeros(img.size(), CV_32FC1)}, img_c2);
    cv::dft(img_c2, img_c2);
    cv::Mat temp;
    fftshift(img_c2, temp);
    cv::Mat plane[2];
    cv::split(temp, plane);
    std::cout << plane[0];
}

测试结果如下图所示:

基于opencv 的 fftshift 函数的实现_第1张图片

matlab的结果对比一致:

基于opencv 的 fftshift 函数的实现_第2张图片
希望以上内容对您有所帮助!!!

你可能感兴趣的:(opencv,opencv)