mirror of https://github.com/opencv/opencv.git
Open Source Computer Vision Library
https://opencv.org/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
109 lines
3.5 KiB
109 lines
3.5 KiB
#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; |
|
}
|
|
|