【问题标题】:OpenCV C++, trouble understanding starter code for DFTOpenCV C++,难以理解 DFT 的入门代码
【发布时间】:2018-09-28 01:44:48
【问题描述】:

不太明白为什么这段代码有效:

cv::Mat img = cv::imread('pic.jpg', -1);
cv::Mat padded;                            
std::uint16_t m = cv::getOptimalDFTSize(img.rows);  // This will be 256
std::uint16_t n = cv::getOptimalDFTSize(img.cols);  // This will be 256
cv::copyMakeBorder(img, padded, 0, m - img.rows, 0, n - img.cols, 
cv::BORDER_CONSTANT, cv::Scalar::all(0));           // With my inputs, this effectively just copies img into padded

cv::Mat planes[] = { cv::Mat_<float>(padded),cv:: Mat::zeros(padded.size(), CV_32F) };

cv::Mat dft_img;  
cv::merge(planes, 2, dft_img);         
cv::dft(dft_img, dft_img);

cv::split(dft_img, planes);                   

但这会因内存中的异常而中断:

cv::Mat img = cv::imread('pic.jpg', -1);    // I know this image is 256x256
cv::Mat dft_img = cv::Mat::zeros(256,256,CV_32F);  // Hard coding for simplicity atm
cv::dft(img,dft_img);

我无法理解 dft() https://docs.opencv.org/2.4/modules/core/doc/operations_on_arrays.html#dft 的文档, 以及与此相关的其他函数和类。

我认为这与 dft_img 不是第二段中的多通道数组有关,但我不知道如何初始化这样的数组而不是复制第一段代码。

其次,当尝试访问 planes[0] 或 planes[1] 并修改它们的值时:

planes[0].at<double>(indexi,indexj) = 0;

我在内存中遇到另一个异常,但我还看到一个新页面显示 mat.inl.hpp 未找到。使用 Visual Studio,OpenCV 3.4.3,C++ 新手,信号处理中级,不胜感激。

【问题讨论】:

    标签: c++ opencv signal-processing


    【解决方案1】:

    你没有具体说明你得到了什么异常,但重要的一点是 dft 函数的输入必须是一个浮点数,可以是 32 位或 64 位浮点数。另一点是,如果您对 c++ 不满意,请尽量不要使用原始数组。我什至会建议,如果使用 c++ 不是强制性的,那么更喜欢 python 用于 OpenCV。这是一个工作示例 dft 代码:

    //  read your image
    cv::Mat img = cv::imread("a2.jpg", CV_LOAD_IMAGE_GRAYSCALE);    // I know this image is 256x256
    
    //  convert it to floating point
    //normalization is optional(depends on library and you I guess?)
    cv::Mat floatImage;
    img.convertTo(floatImage, CV_32FC1, 1.0/255.0);
    
    //  create a placeholder Mat variable to hold output of dft
    std::vector<cv::Mat> dftOutputs;
    dftOutputs.push_back(floatImage);
    dftOutputs.push_back(cv::Mat::zeros(floatImage.size(), CV_32F));
    cv::Mat dftOutput;
    cv::merge(dftOutputs, dftOutput);
    
    //  perform dft
    cv::dft(dftOutput, dftOutput);
    
    //  separate real and complex outputs back
    cv::split(dftOutput, dftOutputs);
    

    我对@9​​87654321@ 的代码进行了一些更改,以使其更易于理解。如果你想得到震级图像等,你可以按照分割函数后的教程。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-06-05
      • 1970-01-01
      • 2023-03-08
      • 2022-01-05
      • 2014-07-12
      • 2021-11-19
      • 1970-01-01
      相关资源
      最近更新 更多