mirror of
https://github.com/opencv/opencv.git
synced 2024-12-13 07:59:27 +08:00
110 lines
3.5 KiB
C++
110 lines
3.5 KiB
C++
|
#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;
|
||
|
}
|