OpenCV C ++,难以理解DFT的入门代码

时间:2018-09-28 01:44:48

标签: c++ opencv signal-processing

不太了解此代码为何起作用:

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 ++的新手,但在信号处理方面处于中级水平),我们将不胜感激。

1 个答案:

答案 0 :(得分:0)

您没有指定遇到的异常,但是重要的一点是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);

我将tutorial的代码做了一些改动,以使其更易于理解。如果要获取幅值图像等,可以在分割功能之后按照教程进行操作。