首页 > 编程知识 正文

数字图像处理贾永红,巴特沃斯低通滤波器设计matlab

时间:2023-05-04 08:15:40 阅读:134973 作者:3558

前言一、jzdrjb低通滤波器(BLPF )二、代码三、说明

前言数字图像处理copencv(vs2019opencv4.53 )持续更新

一. jzdrjb低通滤波器(BLPF ) )。

d2(u,v )为距中心点距离的平方,D 0为设置半径,根据n的值滤波器d(2) u,v )为距中心点的距离的平方,D_0为设置半径,根据n的值滤波器d2 ) u,v )为设置半径,D 0为设置半径,n为n

二.代码主代码:

# include iostream # include opencv2/opencv.HPP # include ' my _ DFT.h ' # include ' salt.h ' # include math.husingname int main () { Mat image,image_gray,image_output,image_transform; //输入图像,定义灰度图像,输出图像image=imread(Lena.png ); //读取图像的if(image.empty () ) {cout读取错误) endl; 返回- 1; }imshow('image ',image ); cvtcolor(image,image_gray,COLOR_BGR2GRAY ); //转换为灰度imshow(image_gray )、image_gray; //显示灰度salt (image _ gray,1000 ); imshow(image_gray ),image_gray ); //显示噪声图//1、傅立叶变换、image_output是可显示频谱图,image_transform是傅立叶变换的复数结果my_DFT(image_gray,image _ ou oft ) //2,jzdrjb低通滤波器mat planes [ ]={ mat _ float (image _ output ),mat:3360zeros ) image_output.size,cv, slit(image_transform,planes ); //分离通道,并输入实部虚部matimage _ transform _ real=planes [0]; matimage _ transform _ imag=planes [1]; int core _ x=image _ transform _ real.rows/2; //谱图中心坐标int core _ y=image _ transform _ real.cols/2; int r=60; //滤波器半径float h; float n=2; //jzdrjb系数float D; //与中心的距离for(intI=0; i image

_transform_real.rows; i++){for (int j = 0; j < image_transform_real.cols; j++){D = (i - core_x) * (i - core_x) + (j - core_y) * (j - core_y);h = 1/(1+pow((D/(r*r)) , n));image_transform_real.at<float>(i, j) = image_transform_real.at<float>(i, j) * h;image_transform_imag.at<float>(i, j) = image_transform_imag.at<float>(i, j) * h;}}planes[0] = image_transform_real;planes[1] = image_transform_imag;Mat image_transform_ilpf;//定义jzdrjb低通滤波结果merge(planes, 2, image_transform_ilpf);//3、傅里叶逆变换Mat iDft[] = { Mat_<float>(image_output), Mat::zeros(image_output.size(),CV_32F) };idft(image_transform_ilpf, image_transform_ilpf);//傅立叶逆变换split(image_transform_ilpf, iDft);//分离通道,主要获取0通道magnitude(iDft[0], iDft[1], iDft[0]); //计算复数的幅值,保存在iDft[0]normalize(iDft[0], iDft[0], 0, 1, NORM_MINMAX);//归一化处理imshow("idft", iDft[0]);//显示逆变换图像waitKey(0); //暂停,保持图像显示,等待按键结束return 0;}

噪声代码(.h文件):

#pragma once#include<iostream>#include<opencv2/opencv.hpp>#include <random>using namespace cv;using namespace std;void Salt(Mat image, int n);

噪声代码(.cpp文件):

#include "Salt.h"void Salt(Mat image, int n){default_random_engine generater;uniform_int_distribution<int>randomRow(0, image.rows - 1);uniform_int_distribution<int>randomCol(0, image.cols - 1);int i, j;for (int k = 0; k < n; k++){i = randomCol(generater);j = randomRow(generater);if (image.channels() == 1){image.at<uchar>(j, i) = 255;}else if (image.channels() == 3){image.at<Vec3b>(j, i)[0] = 255;image.at<Vec3b>(j, i)[1] = 255;image.at<Vec3b>(j, i)[2] = 255;}}}

傅里叶变换代码(.h文件):

#pragma once#include<iostream>#include<opencv2/opencv.hpp>#include<cmath>using namespace cv;using namespace std;void My_DFT(Mat input_image, Mat& output_image, Mat& transform_array);

傅里叶变换代码(.cpp文件):

#include "MY_DFT.h"//傅里叶变换得到频谱图和复数域结果void My_DFT(Mat input_image, Mat& output_image, Mat& transform_image){//1.扩展图像矩阵,为2,3,5的倍数时运算速度快int m = getOptimalDFTSize(input_image.rows);int n = getOptimalDFTSize(input_image.cols);copyMakeBorder(input_image, input_image, 0, m - input_image.rows, 0, n - input_image.cols, BORDER_CONSTANT, Scalar::all(0));//2.创建一个双通道矩阵planes,用来储存复数的实部与虚部Mat planes[] = { Mat_<float>(input_image), Mat::zeros(input_image.size(), CV_32F) };//3.从多个单通道数组中创建一个多通道数组:transform_image。函数Merge将几个数组合并为一个多通道阵列,即输出数组的每个元素将是输入数组元素的级联merge(planes, 2, transform_image);//4.进行傅立叶变换dft(transform_image, transform_image);//5.计算复数的幅值,保存在output_image(频谱图)split(transform_image, planes); // 将双通道分为两个单通道,一个表示实部,一个表示虚部Mat transform_image_real = planes[0];Mat transform_image_imag = planes[1];magnitude(planes[0], planes[1], output_image); //计算复数的幅值,保存在output_image(频谱图)//6.前面得到的频谱图数级过大,不好显示,因此转换output_image += Scalar(1); // 取对数前将所有的像素都加1,防止log0log(output_image, output_image); // 取对数normalize(output_image, output_image, 0, 1, NORM_MINMAX); //归一化//7.剪切和重分布幅度图像限output_image = output_image(Rect(0, 0, output_image.cols & -2, output_image.rows & -2));// 重新排列傅里叶图像中的象限,使原点位于图像中心int cx = output_image.cols / 2;int cy = output_image.rows / 2;Mat q0(output_image, Rect(0, 0, cx, cy)); // 左上区域Mat q1(output_image, Rect(cx, 0, cx, cy)); // 右上区域Mat q2(output_image, Rect(0, cy, cx, cy)); // 左下区域Mat q3(output_image, Rect(cx, cy, cx, cy)); // 右下区域 //交换象限中心化Mat tmp;q0.copyTo(tmp); q3.copyTo(q0); tmp.copyTo(q3);//左上与右下进行交换q1.copyTo(tmp); q2.copyTo(q1); tmp.copyTo(q2);//右上与左下进行交换Mat q00(transform_image_real, Rect(0, 0, cx, cy)); // 左上区域Mat q01(transform_image_real, Rect(cx, 0, cx, cy)); // 右上区域Mat q02(transform_image_real, Rect(0, cy, cx, cy)); // 左下区域Mat q03(transform_image_real, Rect(cx, cy, cx, cy)); // 右下区域q00.copyTo(tmp); q03.copyTo(q00); tmp.copyTo(q03);//左上与右下进行交换q01.copyTo(tmp); q02.copyTo(q01); tmp.copyTo(q02);//右上与左下进行交换Mat q10(transform_image_imag, Rect(0, 0, cx, cy)); // 左上区域Mat q11(transform_image_imag, Rect(cx, 0, cx, cy)); // 右上区域Mat q12(transform_image_imag, Rect(0, cy, cx, cy)); // 左下区域Mat q13(transform_image_imag, Rect(cx, cy, cx, cy)); // 右下区域q10.copyTo(tmp); q13.copyTo(q10); tmp.copyTo(q13);//左上与右下进行交换q11.copyTo(tmp); q12.copyTo(q11); tmp.copyTo(q12);//右上与左下进行交换planes[0] = transform_image_real;planes[1] = transform_image_imag;merge(planes, 2, transform_image);//将傅里叶变换结果中心化}

结果:


三、说明

理想低通滤波会导致振铃效应,整齐的蜗牛低通滤波则没有。但是整齐的蜗牛低通滤波不好控制低与高频的过度部分。jzdrjb低通滤波器可以通过调整系数进行控制。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。