[英]How to use the OpenCV CUDA Fourier Transform
相反的OpenCV的正常的dft
,我想使用cuda::dft
。 作為開始,我嘗試執行正向和逆向變換,但結果看起來與輸入完全不同。 這是一個使用 OpenCV 示例圖像的最小示例:
// Load 8bit test image (https://raw.githubusercontent.com/opencv/opencv/master/samples/data/basketball1.png)
Mat testImg;
testImg = imread("basketball1.png", CV_LOAD_IMAGE_GRAYSCALE);
// Convert input to complex float image
Mat_<float> imgReal;
testImg.convertTo(imgReal, CV_32F, 1.0/255.0);
Mat imgImag = Mat(imgReal.rows, imgReal.cols, CV_32F, float(0));
vector<Mat> channels;
channels.push_back(imgReal);
channels.push_back(imgImag);
Mat imgComplex;
merge(channels,imgComplex);
imshow("Img real", imgReal);
waitKey(0);
//Perform a Fourier transform
cuda::GpuMat imgGpu, fftGpu;
imgGpu.upload(imgComplex);
cuda::dft(imgGpu, fftGpu, imgGpu.size());
//Performs an inverse Fourier transform
cuda::GpuMat propGpu, convFftGpu;
cuda::dft(fftGpu, propGpu, imgGpu.size(), DFT_REAL_OUTPUT | DFT_SCALE);
Mat output(propGpu);
output.convertTo(output, CV_8U, 255, 0);
imshow("Output", output);
waitKey(0);
我玩過這些標志,但output
看起來從來不像輸入。 使用上面的代碼我得到作為輸出:
雖然它應該是這樣的:
我在這里找到了答案。 顯然,當從復雜的輸入圖像開始時,不可能使用標志DFT_REAL_OUTPUT
。
要么使用單通道浮點輸入進行正向變換,然后從逆變換中獲得與輸出相同的輸出,要么從兩通道復合輸入圖像開始並獲得該類型作為輸出。 使用復雜輸入圖像的好處是正向變換提供完整大小的復雜字段以進行處理,例如執行卷積(有關詳細信息,請參閱鏈接的答案)。
我要補充一點,為了從逆變換中獲得 8 位圖像,請自己計算幅度,如下所示:
Mat output(propGpu);
Mat planes[2];
split(output,planes);
Mat mag;
magnitude(planes[0],planes[1],mag);
mag.convertTo(mag, CV_8U, 255, 0);
要使用OpenCV Cuda FFT
進入傅立葉域並返回空間域,您可以簡單地按照以下示例進行操作(要了解更多信息,您可以參考cufft documentation
, OpenCV Cuda FFT source code
基於該cufft documentation
)。
Mat test_im;
test_im = imread("frame.png", IMREAD_GRAYSCALE);
// Convert input input to real value type (CV_64F for double precision)
Mat im_real;
test_im.convertTo(im_real, CV_32F, 1.0/255.0);
imshow("Input Image", im_real);
waitKey(0);
// Perform The Fourier Transform
cuda::GpuMat in_im_gpu, fft_im;
in_im_gpu.upload(im_real);
cuda::dft(in_im_gpu, fft_im, in_im_gpu.size(), 0);
// Performs an inverse Fourier transform
cuda::GpuMat ifft_im_gpu;
//! int odd_size = imgGpu.size().width % 2;
//! cv::Size dest_size((fftGpu.size().width-1)*2 + (odd_size ? 1 : 0), fftGpu.size().height);
cv::Size dest_size = in_im_gpu.size();
int flag = (DFT_SCALE + DFT_REAL_OUTPUT) | DFT_INVERSE;
cuda::dft(fft_im, ifft_im_gpu, dest_size, flag);
Mat ifft_im(ifft_im_gpu);
ifft_im.convertTo(ifft_im, CV_8U, 255, 0);
imshow("Inverse FFT", ifft_im);
waitKey(0);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.