当前位置:网站首页>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);
}
#endif
5、 ... 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
边栏推荐
- SCM career development: those who can continue to do it have become great people. If they can't endure it, they will resign or change their careers
- Application of external interrupts
- Project scope management__ Scope management plan and scope specification
- It is difficult to quantify the extent to which a single-chip computer can find a job
- Stm32f04 clock configuration
- Adaptiveavgpool1d internal implementation
- (1) 什么是Lambda表达式
- 4G module initialization of charge point design
- [combinatorics] Introduction to Combinatorics (combinatorial idea 3: upper and lower bound approximation | upper and lower bound approximation example Remsey number)
- Timer and counter of 51 single chip microcomputer
猜你喜欢
How does the memory database give full play to the advantages of memory?
03 FastJson 解决循环引用
Getting started with JMX, MBean, mxbean, mbeanserver
[Li Kou brush question notes (II)] special skills, module breakthroughs, classification and summary of 45 classic questions, and refinement in continuous consolidation
学习开发没有捷径,也几乎不存在带路会学的快一些的情况
要選擇那種語言為單片機編寫程序呢
Yocto technology sharing phase IV: customize and add software package support
LeetCode 面试题 17.20. 连续中值(大顶堆+小顶堆)
2021-10-28
Embedded systems are inherently flawed. Compared with the Internet, there are so many holes that it is simply difficult to walk away from
随机推荐
MySQL root user needs sudo login
LeetCode - 508. 出现次数最多的子树元素和 (二叉树的遍历)
Exception handling of arm
01 business structure of imitation station B project
Blue Bridge Cup for migrant workers majoring in electronic information engineering
4G module initialization of charge point design
Fundamentals of Electronic Technology (III)__ Chapter 6 combinational logic circuit
4G module designed by charging pile obtains signal strength and quality
在三线城市、在县城,很难毕业就拿到10K
STM32 running lantern experiment - library function version
is_ power_ of_ 2 judge whether it is a multiple of 2
Yocto Technology Sharing Phase 4: Custom add package support
Embedded systems are inherently flawed. Compared with the Internet, there are so many holes that it is simply difficult to walk away from
03 fastjason solves circular references
03 fastjason solves circular references
【力扣刷题笔记(二)】特别技巧,模块突破,45道经典题目分类总结,在不断巩固中精进
Oracle数据库 SQL语句执行计划、语句跟踪与优化实例
单片机学到什么程度能找到工作,这个标准不好量化
Serial port programming
2020-08-23