opencv dft работает правильно только для размеров изображения со степенью 2
В настоящее время я испытываю странное поведение с функцией dft в opencv. Я пересылаю некоторые матрицы opencv и выполняю некоторые вычисления в частотной области, а затем снова преобразовываю их.
Результат выглядит, как и ожидалось, для изображений с размером в степени 2 (например, 256x256, 512x512), но я получаю полную чушь за любые другие измерения.
Мой код выглядит примерно так:
cv::Mat Z(Pgrads.rows, Pgrads.cols, CV_32FC2, cv::Scalar::all(0));
cv::dft(Pgrads, P, cv::DFT_SCALE | cv::DFT_COMPLEX_OUTPUT);
cv::dft(Qgrads, Q, cv::DFT_SCALE | cv::DFT_COMPLEX_OUTPUT);
/* doing some calculations */
cv::dft(Z, Z, cv::DFT_INVERSE | cv::DFT_REAL_OUTPUT);
Операция, которую я делаю, называется фотометрической стерео, поэтому вкратце я делаю глобальную интеграцию по некоторым градиентам. Кто-нибудь еще испытывал эту проблему с opencv и может дать мне несколько советов?
заранее спасибо
2 ответа
БПФ работает только с наборами данных размера 2
Нормально расширять изображения и дополнять их постоянным значением (которое не влияет на результат Фурье), см. http://docs.opencv.org/doc/tutorials/core/discrete_fourier_transform/discrete_fourier_transform.html
Совсем не правда, что БПФ работают только с мощностью двух наборов данных. С конкретной реализацией OCV, они утверждают (по состоянию на 2.4.9), что он работает с другими размерами, но что сила 2 отступов просто рекомендуется для эффективности. Вы найдете очень старые библиотеки FFT с ограничением 2^N, но я их давно не видел. Вы можете убедиться, что используете текущую версию (я знаю, что на дату запроса у OCV была более или менее текущая реализация FFT), а не какой-то действительно старый код. Я не знаю, как вы оцениваете вывод, но, скорее всего, проблема в том, что вы даете ему сложный ввод CV_32FC2, используя флаг, который говорит ему ожидать реального ввода, DFT_COMPLEX_OUTPUT. DFT_COMPLEX_OUTPUT означает "принять реальный вклад и дать мне полный, распакованный сложный вывод, а не форму CSS". Я понятия не имею, что пытается сделать код, если вы смешаете этот флаг со сложным вводом. Вы также можете убедиться, что вы инициализируете мнимую часть вашего ввода в 0, так как вы используете реальные данные изображения. В любом случае, вы, вероятно, должны использовать входы CV_32FC1 для изображений вместо CV_32FC2.