2019-10-24 22:10:00 wujuxKkoolerter 阅读数 71

梯形低通滤波器

梯形低通滤波器(TLPF)的传递函数如下:

H(u,v)={1D(u,v)<D0D(u,v)D1D0D1D0<D(u,v)D10D(u,v)>D1(10-1) H(u,v) = \begin{cases} 1 & D(u,v) \lt D_0 \\\\ \frac{D(u,v) - D_1}{D_0-D_1} & D_0 \lt D(u,v) \leq D_1 \\\\ 0 &D(u,v) > D_1 \end{cases} \tag{10-1}

其中,D0D_0称为梯形低通滤波器的截止频率。D0D_0D1D_1按要求指定D0<D1D_0 < D_1,它的性能介于理想低通滤波与巴特沃斯低通滤波器之间,对图像具有一定的模糊和振铃效应。

在这里插入图片描述

Python语言实现代码如下:

def trapezoidal_low_pass_kernel(img,D0=5,D1=10):
    assert img.ndim == 2
    r,c = img.shape[1],img.shape[0]
    u = np.arange(r)
    v = np.arange(c)
    u, v = np.meshgrid(u, v)
    low_pass = np.sqrt( (u-r/2)**2 + (v-c/2)**2 )

    idx = low_pass < D0
    idx2 = (low_pass >= D0) & (low_pass <= D1)
    idx3 = low_pass > D1

    low_pass[idx] = 1
    low_pass[idx2] = (low_pass[idx2] - D1) / (D1 - D0)
    low_pass[idx3] = 0

    return low_pass

def trapezoidal_low_pass_filter(img,D0=5,D1=15):
    assert img.ndim == 2
    gray = np.float64(img)
    kernel = trapezoidal_low_pass_kernel(img,D0,D1)
    gray_fft = np.fft.fft2(gray)
    gray_fftshift = np.fft.fftshift(gray_fft)
    dst = np.zeros_like(gray_fftshift)
    dst_filtered = kernel * gray_fftshift
    dst_ifftshift = np.fft.ifftshift(dst_filtered)
    dst_ifft = np.fft.ifft2(dst_ifftshift)
    dst = np.abs(np.real(dst_ifft))
    dst = np.clip(dst,0,255)
    return np.uint8(dst)

程序运行结果
在这里插入图片描述

2019-10-26 17:34:40 wujuxKkoolerter 阅读数 134

梯形高通滤波

梯形高通滤波器(TLPF)的传递函数如下:

$$
H(u,v) = 1 - \begin{cases}
1 & D(u,v) \lt D_0 \\
\frac{D(u,v) - D_1}{D_0-D_1} & D_0 \lt D(u,v) \leq D_1 \\
0 &D(u,v) > D_1
\end{cases}

\tag{18-1}

$$

Python语言实现的代码如下:

def trapezoidal_low_pass_kernel(img,D0=5,D1=10):
    assert img.ndim == 2
    r,c = img.shape[1],img.shape[0]
    u = np.arange(r)
    v = np.arange(c)
    u, v = np.meshgrid(u, v)
    low_pass = np.sqrt( (u-r/2)**2 + (v-c/2)**2 )

    idx = low_pass < D0
    idx2 = (low_pass >= D0) & (low_pass <= D1)
    idx3 = low_pass > D1

    low_pass[idx] = 1
    low_pass[idx2] = (low_pass[idx2] - D1) / (D1 - D0)
    low_pass[idx3] = 0

    return low_pass

def trapezoidal_high_pass_filter(img,D0=5,D1=15):
    assert img.ndim == 2
    gray = np.float64(img)
    kernel = 1 - trapezoidal_low_pass_kernel(img,D0,D1)
    gray_fft = np.fft.fft2(gray)
    gray_fftshift = np.fft.fftshift(gray_fft)
    dst = np.zeros_like(gray_fftshift)
    dst_filtered = kernel * gray_fftshift
    dst_ifftshift = np.fft.ifftshift(dst_filtered)
    dst_ifft = np.fft.ifft2(dst_ifftshift)
    dst = np.abs(np.real(dst_ifft))
    dst = np.clip(dst,0,255)
    return np.uint8(dst)

程序运行结果:

在这里插入图片描述

2018-12-09 11:54:16 Dear_Jia 阅读数 1198

算法基本原理:把原区间分为一系列小期间(n份),在每个小区间上都用小的梯形面积来近似代替原函数的积分,当小区间足够小时,就可以得到原来积分的近似值。但是这个过程中有一个问题是步长的取值,步长太大精度难以保证,步长太小会导致计算量的增加,所以,实际计算中常常采用变步长的方法,使得在步长逐次减小的过程中,求得的积分结果满足要求的精度为止。

       首先,给出两个计算公式

              (1) //计算步长为h的积分

              (2) //将步长h二分,计算以h/2为步长的积分

步骤:

  • 取n=1,利用公式(1)计算积分值
  • 进行二分,利用新的公式(2)计算新的积分值
  • 进行判断,如果两次计算积分值的差在给定的误差范围之内,二分后的积分值就是所需的结果,计算结束,否则返回第二步继续运行

因此,主要计算的问题有两个

一. 被积函数值的运算(设置Function类)

二. 变步长梯形积分的实现(设置Trapz类)

#ifndef _TRAPZINT_H_
#define _TRAPZINT_H_

class Function{
public:
	virtual double operator()(double x) const = 0;//纯虚函数重载运算符()
	virtual ~Function(){}//析构函数
};

class MyFunction :public Function{
public:
	virtual double operator()(double x) const;//覆盖虚函数
};

class Integration{//抽象类Integration的定义
public:
	virtual double operator()(double a, double b, double eps) const = 0;
	virtual ~Integration(){}
};

class Trapz :public Integration{//公有派生类Trapz的定义
public:
	Trapz(const Function &f) :f(f){}//构造函数
	virtual double operator()(double a, double b, double eps) const;//覆盖虚函数
private:
	const Function &f;//私有成员,Function类对象的指针
};

#endif
#include"Trapzint.h"
#include<iostream>
#include<cmath>
using namespace std;

//计算被积函数的函数值
double MyFunction::operator()(double x) const{
	return log(1.0 + x) / (1.0 + x*x);
}

//积分运算过程,重载为运算符()
double Trapz::operator()(double a, double b, double eps) const{
	//计算区间[a,b]之间误差在eps之内的积分值
	bool done = false;//Trapz类的虚函数成员
	int n = 1;
	double h = b - a;
	double tn = h*(f(a) + f(b)) / 2;//计算n=1时的积分
	double t2n;//步长为一半的时候的积分值
	do{
		double sum = 0;
		for (int k = 0; k < n; k++){
			double x = a + (k + 0.5)*h;
			sum += f(x);
		}
		t2n = (tn + h*sum) / 2.0;//利用公式(2)计算积分
		if (fabs(tn - t2n) < eps)
			done = true;//判断积分误差
		else{
			tn = t2n;
			n *= 2;
			h /= 2;
		}
	} while (!done);
	return t2n;
}
#include"Trapzint.h"
#include<iostream>
#include<iomanip>
using namespace std;
int main(){
	MyFunction f;//定义MyFunction类的对象
	Trapz trapz(f);//定义Trapz类的对象
	//计算并输出结果
	cout << "Trapz Int:" << setprecision(7) << trapz(0, 2, 1e-7) << endl;
	return 0;
}

结果

2017-06-07 10:29:37 qq_22520215 阅读数 1716

先上梯形积分的算法公式;


对于积分环节的PID控制,其实就是为了消除系统的静差,为了减少这个,我们必须提高积分环节的精度也就是每一次偏差的调节变小,因为在系统稳定的状态下,偏差调节越小,就是精度越高,为此我们用梯形的积分代替第六章中的矩形积分来提高积分调节精度!
代码请参考第六篇中的代码,只需讲第六篇中的这段代码:
pid.Voltage       = pid.Kp*pid.Err +index*pid.Ki*pid.Integral + pid.Kd*(pid.Err - pid.Err_Last);  
改成
pid.Voltage       = pid.Kp*pid.Err +index*pid.Ki*pid.Integral/2 + pid.Kd*(pid.Err - pid.Err_Last); 



最后运行的稳定结果为199.999878,相对第六篇的运行结果199.999939而言,精度提高了!


没有更多推荐了,返回首页