当前位置:网站首页>Opencv note 21 frequency domain filtering
Opencv note 21 frequency domain filtering
2022-07-03 10:03:00 【Σίσυφος one thousand and nine hundred】
One 、 summary
Two 、 step




Step four : The complex matrix is obtained by using the fast algorithm of Fourier transform F.


3、 ... and 、 Low pass filtering

2、 Butterworth low pass filter

3、 Gaussian low pass filter
remember glpFilter=[glpFilter(r,c)]H×W;
effect :
Four 、 Low pass filter code implementation
// The fast Fourier transform
void fft2Image(InputArray image, OutputArray F)
{
// To the Mat The type of
Mat Image = image.getMat();
int rows = Image.rows;
int cols = Image.cols;
// Get the best two columns
int r = getOptimalDFTSize(rows);
int c = getOptimalDFTSize(cols);
// Enter on the left and below 10
Mat f;
copyMakeBorder(Image, f, 0, r - rows, 0, c - cols, BORDER_CONSTANT,Scalar::all(0));
// Two channels , The first channel stores the real part The second channel is for storing imaginary parts
dft(f, F, DFT_COMPLEX_OUTPUT);
// Inverse Fourier transform
//dft(f, F, DFT_INVERSE+DFT_REAL_OUTPUT+DFT_SCALE);// Return only the real part
}
// Amplitude spectrum
void amplitudeSpectrum(InputArray _srcfft, OutputArray _dstSpectrum)
{
if (_srcfft.channels() != 2) return ;
// If there are two channels, start to separate channels
vector<Mat> FFT2Channels;
split(_srcfft, FFT2Channels);
// Calculate the Fourier transform amplitude value sqrt(pow(r,2)+pow(L,2))
magnitude(FFT2Channels[0], FFT2Channels[1], _dstSpectrum);
}
// Gray level display of Fourier spectrum
Mat graySpectrum(Mat s)
{
Mat dst;
log(s + 1, dst);
// normalization
normalize(dst,dst,0,1,NORM_MINMAX);
// To show Gray scale
dst.convertTo(dst,CV_8UC1,255,0);
return dst;
}
// Calculate the phase angle of Fourier transform ==phase operator
Mat phaseS(Mat sfft)
{
// Phase spectrum
Mat phase;
phase.create(sfft.size(), CV_64FC1);
// The separation channel
vector<Mat> fft2Channels;
split(sfft,fft2Channels);
// Start calculating the phase spectrum
for (int r = 0; r < phase.rows;r++) {
for (int c = 0; c < phase.cols; c++) {
// Real component Imaginary part
double real = fft2Channels[0].at<double>(r,c);
double img = fft2Channels[1].at<double>(r,c);
// atan2 The return value of 【0,180】,【-180,0】
phase.at<double>(r, c) = atan2(img,real);
}
}
return phase;
}
// -----------------------------------------------------------
#if 1 // Low pass filtering
enum typeFilter
{
ILPFILTER,
BLPFILTER,
GLPFILTER,
};
Mat createFilter(Size size, Point center,float radius, int type, int n = 2)
{
Mat ilpFilter = Mat::zeros(size,CV_32FC1); // Define a size Size filter
int rows = size.height;
int cols = size.width;
if (radius <= 0)return ilpFilter;
// Build an ideal low-pass filter
if (type== ILPFILTER)
{
for (int r=0;r< rows;r++)
{
for (int c = 0; c < cols;c++)
{
// Calculated distance
float norm2 = pow(abs(float(r - center.y)), 2)+ pow(abs(float(r - center.y)), 2);
if (norm2 < radius)
{
ilpFilter.at<float>(r, c) = 1;
}
else
{
ilpFilter.at<float>(r, c) = 0;
}
}
}
}
//
else if(type == BLPFILTER)
{
for (int r = 0; r < rows; r++)
{
for (int c = 0; c < cols; c++)
{
/* float m = sqrt(pow(r - center.y, 2.0) + pow(c - center.x, 2.0));
float n = m / radius;
float o = pow(n,2*n);
float s = 1.0 + o;
float i = 1.0 / s;*/
ilpFilter.at<float>(r, c) = float(1.0 / (1.0 + (pow(sqrt(pow(r - center.y, 2.0) + pow(c - center.x, 2.0)) / radius, 2 * n))));
}
}
}
// Gauss filtering
else if (type == GLPFILTER)
{
for (int r = 0; r < rows; r++)
{
for (int c = 0; c < cols; c++)
{
ilpFilter.at<float>(r, c) = float(exp(-(pow(c-center.x,2.0)+pow(r-center.y,2.0))/(2*pow(radius,2.0))));
}
}
}
return ilpFilter;
}
Mat src;// Input image
Mat F;// Fast Fourier transform of image
Point maxLocation;// The coordinates of the maximum of the Fourier spectrum
int radius = 20; // Truncation frequency
const int max_Radius = 100;// Maximum cutoff frequency
Mat ilpFilter;// low pass filter
int filterType=0;//
int max_FilterType = 2;
Mat F_ilpFilter;// Low pass Fourier transform
Mat FlpSpetrum;// Gray level of Fourier spectrum of low-pass Fourier transform
Mat result;// The filtered image
string lpFilterSpectrum = " Low pass Fourier spectrum ";//
void callback_lpFilter(int ,void *);
int main()
{
src = imread("C:\\Users\\19473\\Desktop\\opencv_images\\611.png",CV_LOAD_IMAGE_GRAYSCALE);
if (!src.data)
{
cout << " Failed to read the original graph " << endl;
return -1;
}
imshow(" Original picture ",src);
// Data conversion Convert data to double
Mat f1;
src.convertTo(f1,CV_32FC1,1.0,0.0);
// 2 Number of each x pow(-1,c+r);
for (int r = 0; r < f1.rows; r++)
{
for (int c = 0; c < f1.cols; c++)
{
// Judge parity
if (r+c%2)
{
f1.at<float>(r, c) *= -1;
}
}
}
// Start Fourier transform
fft2Image(f1,F);// F After Fourier transform
Mat as;
// Get the Fourier spectrum
amplitudeSpectrum(F,as);
// Gray level display of Fourier spectrum
Mat s = graySpectrum(as);
imshow(" Gray level display of original Fourier spectrum ",s);
// Find the coordinates of the maximum value of the Fourier spectrum
minMaxLoc(s,NULL,NULL,NULL,&maxLocation);
//------------------------------------ Low pass filtering ----------------------------------------------
namedWindow(lpFilterSpectrum,WINDOW_AUTOSIZE);
createTrackbar(" Low pass filtering :", lpFilterSpectrum,&filterType, max_FilterType, callback_lpFilter);
createTrackbar(" radius :", lpFilterSpectrum, &radius, max_Radius, callback_lpFilter);
callback_lpFilter(0,0);
waitKey(0);
return 0;
}
// Callback function
void callback_lpFilter(int, void*)
{
// ----------------- Build a low-pass filter ----------------------------------
ilpFilter = createFilter(F.size(),maxLocation,radius, filterType,2);
// -------------------- Low pass filter and Fourier transform of image start point multiplication =====================================
F_ilpFilter.create(F.size(),F.type());
for (int r = 0; r < F_ilpFilter.rows; r++)
{
for (int c = 0; c < F_ilpFilter.cols; c++)
{
// Take out the values of the fast Fourier transform and the ideal low-pass filter of the current position respectively
Vec2f f_rc = F.at<Vec2f>(r,c);
float lpFilter_rc = ilpFilter.at<float>(r,c);
// The low-pass filter is multiplied by the corresponding position of the fast Fourier transform of the image
F_ilpFilter.at<Vec2f>(r, c) = f_rc * lpFilter_rc;
}
}
// Fourier spectrum of low-pass Fourier transform
amplitudeSpectrum(F_ilpFilter, FlpSpetrum);
FlpSpetrum = graySpectrum(FlpSpetrum);
imshow(lpFilterSpectrum, FlpSpetrum);
// Inverse Fourier transform And as long as the real part
dft(F_ilpFilter,result,DFT_SCALE+DFT_INVERSE+DFT_REAL_OUTPUT);
// multiply (-1) Of (r+c) Power
for (int r = 0; r < result.rows; r++)
{
for (int c = 0; c < result.cols; c++)
{
if ((c + r) % 2) result.at<float>(r, c) *= -1;
}
}
// An important step Convert the result to CV_8u
result.convertTo(result, CV_8UC1, 1.0, 0);
result = result(Rect(0,0,src.cols,src.rows)).clone();
imshow(" The image after low-pass filtering ",result);
}
#endif5、 ... and 、 High pass filtering

1、 Ideal high pass filtering

2. Butterworth high pass filter

3. Gaussian high pass filter

6、 ... and 、 Bandpass Band stop filter


2. Butterworth bandpass filter and Butterworth bandstop filter


3. Gaussian bandpass filter and Gaussian bandstop filter


belt Resistance The filter is just the opposite of the above
7、 ... and 、 Custom filter

#if 1 // Custom filter
Mat image;// Input image
Mat ImageFFT;// Fast Fourier transform of image
Point maxLocation;// The coordinates of the maximum of the Fourier spectrum
Mat ilpFilter;// low pass filter
Mat F_ImageSpetrum;// Fourier spectrum of Fourier transform
Mat result;// The filtered image
string windowName = " Gray level of Fourier amplitude spectrum ";//
bool drawing_box = false;// Mouse events
Point drawPoint;
Rect rectFilter;
bool gotRectFilter = false;
void mouseRectHandler(int event,int x,int y,int,void* )
{
switch (event)
{
case CV_EVENT_LBUTTONDOWN:// The mouse click
drawing_box = true;
// Record the starting point
drawPoint = Point(x, y);
break;
case CV_EVENT_MOUSEMOVE:
if (drawing_box)
{
// Move the mouse to the lower right corner
if (x> drawPoint.x&&y>= drawPoint.y)
{
rectFilter.x = drawPoint.x;
rectFilter.y = drawPoint.y;
rectFilter.width = x - drawPoint.x;
rectFilter.height= y - drawPoint.y;
}
// Move the mouse to the upper right corner
if (x >= drawPoint.x && y <= drawPoint.y)
{
rectFilter.x = drawPoint.x;
rectFilter.y = y;
rectFilter.width = x - drawPoint.x;
rectFilter.height = drawPoint.y- y ;
}
// Move the mouse to the upper left corner
if (x >= drawPoint.x && y <= drawPoint.y)
{
rectFilter.x = x;
rectFilter.y = y;
rectFilter.width = drawPoint.x - x;
rectFilter.height = drawPoint.y - y;
}
// Move the mouse to the lower left corner
if (x >= drawPoint.x && y <= drawPoint.y)
{
rectFilter.x = x;
rectFilter.y = drawPoint.y;
rectFilter.width = drawPoint.x-x;
rectFilter.height = y- drawPoint.y ;
}
}
break;
case CV_EVENT_LBUTTONUP:
drawing_box = false;
gotRectFilter = true;
break;
default:
break;
}
}
int main()
{
image = imread("C:\\Users\\19473\\Desktop\\opencv_images\\612.png",CV_LOAD_IMAGE_GRAYSCALE);
if (!image.data)
{
cout << " Failed to read the original graph " << endl;
return -1;
}
imshow(" Original picture ", image);
// Data conversion Convert data to double
Mat f1;
image.convertTo(f1,CV_32FC1,1.0,0.0);
// 2 Number of each x pow(-1,c+r);
for (int r = 0; r < f1.rows; r++)
{
for (int c = 0; c < f1.cols; c++)
{
// Judge parity
if (r+c%2)
{
f1.at<float>(r, c) *= -1;
}
}
}
// Start Fourier transform
fft2Image(f1,ImageFFT);// F After Fourier transform
Mat amplSpec;
// Get the Fourier spectrum
amplitudeSpectrum(ImageFFT, amplSpec);
// Gray level display of Fourier spectrum
Mat spectrum = graySpectrum(amplSpec);
// Find the coordinates of the maximum value of the Fourier spectrum
minMaxLoc(amplSpec,NULL,NULL,NULL,&maxLocation);
//------------------------------------ Customize wave filtering ----------------------------------------------
namedWindow(windowName,WINDOW_AUTOSIZE);
setMouseCallback(windowName, mouseRectHandler,NULL);
for (;;)
{
spectrum(rectFilter).setTo(0);
// Customize Filter and Fourier transform point multiplication
ImageFFT(rectFilter).setTo(Scalar::all(0));
imshow(windowName, spectrum);
// Press esc See exit editing
if (waitKey(10)==27)
{
break;
}
}
Mat result;
// Inverse Fourier transform And as long as the real part
dft(ImageFFT, result, DFT_SCALE + DFT_INVERSE + DFT_REAL_OUTPUT);
// multiply (-1) Of (r+c) Power
for (int r = 0; r < result.rows; r++)
{
for (int c = 0; c < result.cols; c++)
{
if ((c + r) % 2) result.at<float>(r, c) *= -1;
}
}
// An important step Convert the result to CV_8u
result.convertTo(result, CV_8UC1, 1.0, 0);
result = result(Rect(0, 0, image.cols, image.rows)).clone();
imshow(" Image after custom filtering ", result);
waitKey(0);
return 0;
}
// Callback function
#endif
边栏推荐
- 內存數據庫究竟是如何發揮內存優勢的?
- 2.Elment Ui 日期选择器 格式化问题
- After clicking the Save button, you can only click it once
- 2021-10-27
- Mobile phones are a kind of MCU, but the hardware it uses is not 51 chip
- Application of external interrupts
- Blue Bridge Cup for migrant workers majoring in electronic information engineering
- Gpiof6, 7, 8 configuration
- Timer and counter of 51 single chip microcomputer
- Windows下MySQL的安装和删除
猜你喜欢

LeetCode 面试题 17.20. 连续中值(大顶堆+小顶堆)

There is no shortcut to learning and development, and there is almost no situation that you can learn faster by leading the way

万字手撕七大排序(代码+动图演示)

Adaptiveavgpool1d internal implementation

【力扣刷题笔记(二)】特别技巧,模块突破,45道经典题目分类总结,在不断巩固中精进

內存數據庫究竟是如何發揮內存優勢的?

新系列单片机还延续了STM32产品家族的低电压和节能两大优势

单片机学到什么程度能找到工作,这个标准不好量化

uniapp 实现微信小程序全局分享及自定义分享按钮样式

单片机现在可谓是铺天盖地,种类繁多,让开发者们应接不暇
随机推荐
4G module at command communication package interface designed by charging pile
Liquid crystal display
03 FastJson 解决循环引用
QT detection card reader analog keyboard input
Vscode markdown export PDF error
(1) 什么是Lambda表达式
Fundamentals of Electronic Technology (III)__ Chapter 6 combinational logic circuit
01仿B站项目业务架构
Leetcode 300 最长上升子序列
MySQL root user needs sudo login
Stm32f04 clock configuration
Yocto Technology Sharing Phase 4: Custom add package support
没有多少人能够最终把自己的兴趣带到大学毕业上
LeetCode 面试题 17.20. 连续中值(大顶堆+小顶堆)
QT qcombobox QSS style settings
Wireshark use
There is no specific definition of embedded system
Swing transformer details-2
The data read by pandas is saved to the MySQL database
STM32 running lantern experiment - library function version
