opencv/samples/cpp/snippets/dft.cpp

110 lines
3.5 KiB
C++
Raw Normal View History

#include "opencv2/core.hpp"
#include "opencv2/core/utility.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include <iostream>
#include <stdio.h>
using namespace cv;
using namespace std;
static void convolveDFT(InputArray A, InputArray B, OutputArray C) {
// Calculate the size of the output array
int outputRows = A.rows() + B.rows() - 1;
int outputCols = A.cols() + B.cols() - 1;
// Reallocate the output array if needed
C.create(outputRows, outputCols, A.type());
Size dftSize;
// Calculate the size of DFT transform
dftSize.width = getOptimalDFTSize(A.cols() + B.cols() - 1);
dftSize.height = getOptimalDFTSize(A.rows() + B.rows() - 1);
// Allocate temporary buffers and initialize them with 0's
Mat tempA(dftSize, A.type(), Scalar::all(0));
Mat tempB(dftSize, B.type(), Scalar::all(0));
// Copy A and B to the top-left corners of tempA and tempB, respectively
Mat roiA(tempA, Rect(0, 0, A.cols(), A.rows()));
A.copyTo(roiA);
Mat roiB(tempB, Rect(0, 0, B.cols(), B.rows()));
B.copyTo(roiB);
// Now transform the padded A & B in-place;
// use "nonzeroRows" hint for faster processing
dft(tempA, tempA, 0, A.rows());
dft(tempB, tempB, 0, B.rows());
// Multiply the spectrums;
// the function handles packed spectrum representations well
mulSpectrums(tempA, tempB, tempA, 0);
// Transform the product back from the frequency domain.
// Even though all the result rows will be non-zero,
// you need only the first C.rows of them, and thus you
// pass nonzeroRows == C.rows
dft(tempA, tempA, DFT_INVERSE + DFT_SCALE, C.rows());
// Now copy the result back to C.
tempA(Rect(0, 0, C.cols(), C.rows())).copyTo(C);
// All the temporary buffers will be deallocated automatically
}
static void help(const char ** argv)
{
printf("\nThis program demonstrates the use of convolution using discrete Fourier transform (DFT)\n"
"An image is convolved with kernel filter using DFT.\n"
"Usage:\n %s [input -- default lena.jpg]\n", argv[0]);
}
const char* keys =
{
"{help h||}{@input|lena.jpg|input image file}"
};
int main(int argc, const char** argv) {
// Load the image in grayscale
help(argv);
CommandLineParser parser(argc, argv, keys);
if (parser.has("help"))
{
help(argv);
return 0;
}
string filename = parser.get<string>(0);
Mat img = imread(samples::findFile(filename), IMREAD_GRAYSCALE);
// Check if the image is loaded successfully
if (img.empty()) {
std::cerr << "Error: Image not loaded!" << std::endl;
return -1;
}
// Convert the image to CV_32F
Mat img_32f;
img.convertTo(img_32f, CV_32F);
float kernelData[9] = { 1.0f/9, 1.0f/9, 1.0f/9, 1.0f/9, 1.0f/9, 1.0f/9, 1.0f/9, 1.0f/9, 1.0f/9 }; // example of blur filter, can be changed to other filter as well.
Mat kernel(3, 3, CV_32F, kernelData);
// Perform convolution of the image with the sharpening kernel
Mat result;
convolveDFT(img_32f, kernel, result);
// Normalize the result for better visualization
normalize(result, result, 0, 255, NORM_MINMAX);
// Convert result back to 8-bit for display
Mat result_8u;
result.convertTo(result_8u, CV_8U);
// Display the images
imshow("Original Image", img);
imshow("Output Image", result_8u);
waitKey(0); // Wait for a key press to close the windows
return 0;
}