已屏蔽 原因:{{ notice.reason }}已屏蔽
{{notice.noticeContent}}
~~空空如也

今天需要对测试数据进行滤波处理 没有matlab工具箱 本来想用scipy写代码 忽然想起以前做的东西有这部分 干脆修改提取出来 做成独立的 可从文件读取一列数据 查看fft 进行IIR滤波(可选择多种滤波方式) 然后有绘图 可以保存滤波后的数据 就一个独立文件 保存为bat文件可以直接运行 (当然要装python 及numpy scipy matplotlib tk等部件

---------------2023/10/16-------------

修改 加上FIR滤波设计 这下程序里做点滤波 就不用局限在平滑滤波了 有更高效的 对数据点预先实验 实验好了 直接采用系数就可以了 

0<0# : ^
''' 
@python %~f0 %* 
@goto :eof
'''

import tkinter as tk
from tkinter import ttk 
import tkinter.messagebox
import tkinter.filedialog
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
from matplotlib.figure import Figure
from matplotlib import pyplot
import numpy
from scipy import signal, fft

# main window
win = tk.Tk()
# data values
data=None

# main window
validate_float=win.register(lambda v: (v:=v.replace('.','',1))=='' or (v:=v[1:] if v[0]=='-' else v)=='' or v.isdigit())
validate_int=win.register(lambda v:  v=='' or (v:=v[1:] if v[0]=='-' else v)=='' or v.isdigit())
win.geometry('+%d+100'%((win.winfo_screenwidth()-900)/2))
win.title('Data Filter')
control_bar=tk.Frame(win)
control_bar.pack(side='left', anchor='n', fill='y', expand=True)
btn_trim=tk.Button(control_bar, text="Load Data", command=lambda : load())
btn_trim.pack(side='top', anchor='s', fill='x', pady=(0, 5))
btn_trim=tk.Button(control_bar, text="Trim/Invert", state="disabled", command=lambda : trim())
btn_trim.pack(side='top', anchor='s', fill='x', pady=(0, 5))
btn_fft=tk.Button(control_bar, text="FFT", state="disabled", command=lambda : plot_fft())
btn_fft.pack(side='top', anchor='s', fill='x', pady=(0, 5))
btn_filter=tk.Button(control_bar, text="Filter (IIR)", command=lambda : filter_iir())
btn_filter.pack(side='top', anchor='s', fill='x', pady=(0, 5))
btn_filter=tk.Button(control_bar, text="Filter (FIR)", command=lambda : filter_fir())
btn_filter.pack(side='top', anchor='s', fill='x', pady=(0, 5))
tkvar_msg=tk.StringVar(value='')
tk.Label(control_bar, textvariable=tkvar_msg, anchor='nw', justify='left', wraplength=150).pack(side='top', anchor='nw', fill='y', expand=True)
win.protocol("WM_DELETE_WINDOW", lambda: pyplot.close('all') is win.destroy())

# matplotlib plot in tk
def on_scroll(evt):
	if thread is None and (axe:=evt.inaxes) is not None and (evt.button=='up' or evt.button=='down'):
		xmin,xmax=axe.get_xlim()
		ymin,ymax=axe.get_ylim()
		scale=0.9 if evt.button=='up' else 1.1
		axe.set(xlim=(evt.xdata-(evt.xdata-xmin)*scale, evt.xdata+(xmax-evt.xdata)*scale),
		            ylim=(evt.ydata-(evt.ydata-ymin)*scale, evt.ydata+(ymax-evt.ydata)*scale))
		evt.canvas.draw_idle()
figure=Figure(figsize=(6, 5), dpi=100)
figure.subplots_adjust(left=0.2, top=0.95, right=0.95)
canvas=FigureCanvasTkAgg(figure, master=win)
canvas.get_tk_widget().pack(side='top', anchor='ne', fill='x', expand=True)
canvas.mpl_connect('scroll_event', on_scroll)
navbar=NavigationToolbar2Tk(canvas, win, pack_toolbar=False)
tk.Frame(navbar, bd=1, width=2, highlightthickness=0, relief='groove').pack(side='left', anchor='w', padx=5, pady=3, fill='y')
btn_save=tk.Button(navbar, text="SAVE DATA", state="disabled", command=lambda : save())
btn_save.pack(side='left')
navbar.update()
navbar.pack(side='bottom', anchor='nw', fill='x')
axe1=figure.add_subplot(111) # only 1 plot in 1x1 table now

# when 'load' button clicked, load data from file
def load():
	global data
	try:
		if (file:=tk.filedialog.askopenfilename(title='Load Data File', defaultextension='.txt', filetypes=[('Text','*.txt'),('All files','*')])):
			data=numpy.loadtxt(file, dtype=numpy.float64)
			btn_save['state']='normal' if len(data)>0 else 'disabled'
			btn_trim['state']='normal' if len(data)>0 else 'disabled'
			btn_fft['state']='normal' if len(data)>0 else 'disabled'
			btn_filter['state']='normal' if len(data)>0 else 'disabled'
			plot()
	except Exception as e:
		tk.messagebox.showerror(title='Error', message=e)
	
#when 'save' button clicked
def save():
	try:
		if (file:=tk.filedialog.asksaveasfile(title='Save Data File', defaultextension='.txt', filetypes=[('Text','*.txt'),('All files','*')])):
			with file:
				for t in data:
					file.write(str(t)+'\n')
	except Exception as e:
		tk.messagebox.showerror(title='Error', message=e)

# wait for complete and render the canvas
_last_draw=None
def plot():
	axe1.cla()
	axe1.set_ylabel("Data Value")
	axe1.set_xlabel("Points : Total "+str(len(data)))
	axe1.grid(True)
	global _last_draw
	if _last_draw is not None:
		_last_draw.remove()
	_last_draw, =axe1.plot(data, color='orange', linewidth=1)
	canvas.draw_idle()
	navbar.update()
	navbar.push_current() 

#when trim button is clicked
def trim():
	def _trim():
		global data
		try:
			h=ctrl_head.get().strip()
			t=ctrl_tail.get().strip()
			h=0 if h=='' else max(0, min(len(data)-1, int(h)))
			t=len(data) if t=='' else min(max(int(t)+1, h+1), len(data))
			invt=var_invt.get()
		except ValueError as e:
			tk.messagebox.showerror(title='Error', message=e, parent=dlg)
		else:
			if h>0 or t<len(data):
				data=data[h:t]
			if invt:
				data=data*-1.0
			plot()
			dlg.destroy()
	dlg=tk.Toplevel(win)
	wingeo=win.geometry().split('+')
	dlg.geometry('+'+str(int(wingeo[1])+250)+'+'+str(int(wingeo[2])+200))
	dlg.grab_set()
	dlg.title('Trim')
	tbl=tk.Frame(dlg)
	tbl.pack(side='top', fill='x', padx=10, pady=10, ipadx=10)
	tk.Label(tbl, anchor='e', text='   Keep data from index').grid(row=0, column=0, sticky='we')
	ctrl_head=tk.Entry(tbl, width=5, validate='key', validatecommand=(validate_int,'%P'))
	ctrl_head.grid(row=0, column=1, sticky='we')
	tk.Label(tbl, anchor='e', text='   Keep data to index').grid(row=1, column=0, sticky='we')
	ctrl_tail=tk.Entry(tbl, width=5, validate='key', validatecommand=(validate_int,'%P'))
	ctrl_tail.grid(row=1, column=1, sticky='we')
	tk.Label(tbl, anchor='e', text='   Invert').grid(row=2, column=0, sticky='we')
	var_invt=tk.BooleanVar(value=False)
	tk.Checkbutton(tbl, variable=var_invt, onvalue=True, offvalue=False).grid(row=2, column=1, sticky='w')
	tk.Button(dlg, text="  OK  ", command=_trim).pack(side='right', padx=5, anchor='n', pady=5)
	tk.Button(dlg, text="CANCEL", command=dlg.destroy).pack(side='right', anchor='n', pady=5)

#plot fft
def plot_fft():
	pyplot.close('all')
	yf = fft.rfft(data)
	xf = fft.rfftfreq(len(data), 1)
	fig, ax1=pyplot.subplots()
	fig.subplots_adjust(right=0.85)
	ax1.set_title('FFT')
	ax1.set_xlabel('Freq. ')
	ax1.set_ylabel('Amplitude')
	ax1.grid()
	ax1.plot(xf, numpy.abs(yf), linewidth=1, color='orange')
	pyplot.show()

#when 'Filter (IIR)' button is clicked
def filter_iir():
	sr=1
	def dofilter():
		global data
		try:
			b=tuple(float(t.strip()) for t in var_coef_b.get().split(','))
			a=tuple(float(t.strip()) for t in var_coef_a.get().split(','))
			data=signal.filtfilt(b, a, data)
			plot()
			dlg.destroy()
		except Exception as e:
			tk.messagebox.showerror(title='Error', message=e, parent=dlg)
	def show_freq():
		try:
			b=tuple(float(t.strip()) for t in var_coef_b.get().split(','))
			a=tuple(float(t.strip()) for t in var_coef_a.get().split(','))
			w,h=signal.freqz(b, a, worN=250, fs=sr)
			pyplot.close('all')
			fig, ax1=pyplot.subplots()
			fig.subplots_adjust(right=0.85)
			ax1.set_title('Filter frequency response')
			ax1.set_xlabel('Freq. (Hz)')
			ax1.set_ylabel('Response', color='blue')
			ax1.grid()
			ax1.plot(w, numpy.abs(h), linewidth=1, color='blue')
			ax2=ax1.twinx()
			ax2.set_ylabel('Phase (degree)', color='orange')
			ax2.plot(w, numpy.unwrap(numpy.angle(h))*180/3.141592653589793, linewidth=1, color='orange')
			pyplot.show()
		except Exception as e:
			tk.messagebox.showerror(title='Error', message=e, parent=dlg)
	def choose_bessel():
		try:
			type=('lowpass','highpass','bandpass','bandstop')[ctrl_bessel_type.current()]
			order=int(ctrl_bessel_order.get().strip())
			freqs=tuple(float(f.strip()) for f in ctrl_bessel_freq.get().split(','))
			for f in freqs:
				assert f<sr/2 and f>0.0, f'frequency must be in (0,{sr/2})'
			b,a=signal.bessel(order, freqs, type, fs=sr)
			var_coef_b.set(','.join(str(x) for x in b))
			var_coef_a.set(','.join(str(x) for x in a))
		except Exception as e:
			tk.messagebox.showerror(title='Error', message=e, parent=dlg)
	def choose_butt():
		try:
			type=('lowpass','highpass','bandpass','bandstop')[ctrl_butt_type.current()]
			order=int(ctrl_butt_order.get().strip())
			freqs=tuple(float(f.strip()) for f in ctrl_butt_freq.get().split(','))
			for f in freqs:
				assert f<sr/2 and f>0.0, f'frequency must be in (0,{sr/2})'
			b,a=signal.butter(order, freqs, type, fs=sr)
			var_coef_b.set(','.join(str(x) for x in b))
			var_coef_a.set(','.join(str(x) for x in a))
		except Exception as e:
			tk.messagebox.showerror(title='Error', message=e, parent=dlg)
	def choose_cheby1():
		try:
			type=('lowpass','highpass','bandpass','bandstop')[ctrl_cheby1_type.current()]
			order=int(ctrl_cheby1_order.get().strip())
			ripple=int(ctrl_cheby1_ripple.get().strip())
			freqs=tuple(float(f.strip()) for f in ctrl_cheby1_freq.get().split(','))
			for f in freqs:
				assert f<sr/2 and f>0.0, f'frequency must be in (0,{sr/2})'
			b,a=signal.cheby1(order, ripple, freqs, type, fs=sr)
			var_coef_b.set(','.join(str(x) for x in b))
			var_coef_a.set(','.join(str(x) for x in a))
		except Exception as e:
			tk.messagebox.showerror(title='Error', message=e, parent=dlg)
	def choose_cheby2():
		try:
			type=('lowpass','highpass','bandpass','bandstop')[ctrl_cheby2_type.current()]
			order=int(ctrl_cheby2_order.get().strip())
			attenuation=float(ctrl_cheby2_attenuation.get().strip())
			freqs=tuple(float(f.strip()) for f in ctrl_cheby2_freq.get().split(','))
			for f in freqs:
				assert f<sr/2 and f>0.0, f'frequency must be in (0,{sr/2})'
			b,a=signal.cheby2(order, attenuation, freqs, type, fs=sr)
			var_coef_b.set(','.join(str(x) for x in b))
			var_coef_a.set(','.join(str(x) for x in a))
		except Exception as e:
			tk.messagebox.showerror(title='Error', message=e, parent=dlg)			
	def choose_npc():
		try:
			type=ctrl_npc_type.current()
			assert type>=0 and type<=3
			q=float(ctrl_npc_q.get().strip())
			f=float(ctrl_npc_freq.get().strip())
			assert f<sr/2 and f>0.0, f'frequency must be in (0,{sr/2})'
			if type==0:
				b,a=signal.iirnotch(f, q, fs=sr)
			elif type==1:
				b,a=signal.iirpeak(f, q, fs=sr)
			elif type==2:
				b,a=signal.iircomb(f, q, ftype='notch', fs=sr)
			elif type==3:
				b,a=signal.iircomb(f, q, ftype='peak', fs=sr)
			var_coef_b.set(','.join(str(x) for x in b))
			var_coef_a.set(','.join(str(x) for x in a))
		except Exception as e:
			tk.messagebox.showerror(title='Error', message=e, parent=dlg)			
	dlg=tk.Toplevel(win)
	wingeo=win.geometry().split('+')
	dlg.geometry('+'+str(int(wingeo[1])+50)+'+'+str(int(wingeo[2])+50))
	dlg.grab_set()
	dlg.title('Filter')
	tk.Label(dlg, justify='left', text='''\
Choose filter needed with right parameters for it, to generation the appropriate coefficients,
then click 'OK' button. the coefficients are ',' separated, and the Z-domain transfer function is :
	Y(z)/X(z)=(b[0]+b[1]/z+b[2]/z^2+...)/(a[0]+a[1]/z+a[2]/z^2...)
''').pack(side='top', anchor='w')
	tbl_gen=tk.Frame(dlg)
	tbl_gen.pack(side='top', fill='x', ipadx=5, ipady=5)
	irow=0
	tk.Label(tbl_gen, text='Bessel/Thomson : for Band-Pass/Band-Stop, input 2 Freq. separated by ","').grid(columnspan=9, row=irow, column=0, sticky='w')
	tk.Label(tbl_gen, anchor='w', text='Type :').grid(row=(irow:=irow+1), column=0, sticky='we')
	ctrl_bessel_type=ttk.Combobox(tbl_gen, justify='left', values=('Low-Pass','High-Pass','Band-Pass','Band-Stop'), state='readonly')
	ctrl_bessel_type.current(0)
	ctrl_bessel_type.grid(row=irow, column=1, sticky='we')
	tk.Label(tbl_gen, anchor='e', text='  Freq. : ').grid(row=irow, column=2, sticky='we')
	ctrl_bessel_freq=tk.Entry(tbl_gen, width=10)
	ctrl_bessel_freq.grid(row=irow, column=3, sticky='w')
	tk.Label(tbl_gen, anchor='e', text='  Order : ').grid(row=irow, column=4, sticky='we')
	ctrl_bessel_order=tk.Entry(tbl_gen, width=5, validate='key', validatecommand=(validate_int,'%P'))
	ctrl_bessel_order.grid(row=irow, column=5, sticky='w')
	tk.Button(tbl_gen, text="CHOOSE", command=choose_bessel).grid(row=irow, column=8, padx=5, sticky='e')
	tk.Label(tbl_gen, text='Butterworth : for Band-Pass/Band-Stop, input 2 Freq. separated by ","').grid(columnspan=9, row=(irow:=irow+1), column=0, sticky='w')
	tk.Label(tbl_gen, anchor='w', text='Type :').grid(row=(irow:=irow+1), column=0, sticky='we')
	ctrl_butt_type=ttk.Combobox(tbl_gen, justify='left', values=('Low-Pass','High-Pass','Band-Pass','Band-Stop'), state='readonly')
	ctrl_butt_type.current(0)
	ctrl_butt_type.grid(row=irow, column=1, sticky='we')
	tk.Label(tbl_gen, anchor='e', text='  Freq. : ').grid(row=irow, column=2, sticky='we')
	ctrl_butt_freq=tk.Entry(tbl_gen, width=10)
	ctrl_butt_freq.grid(row=irow, column=3, sticky='w')
	tk.Label(tbl_gen, anchor='e', text='  Order : ').grid(row=irow, column=4, sticky='we')
	ctrl_butt_order=tk.Entry(tbl_gen, width=5, validate='key', validatecommand=(validate_int,'%P'))
	ctrl_butt_order.grid(row=irow, column=4, sticky='w')
	tk.Button(tbl_gen, text="CHOOSE", command=choose_butt).grid(row=irow, column=8, padx=5, sticky='e')
	tk.Label(tbl_gen, text='Chebyshev I : for Band-Pass/Band-Stop, input 2 Freq. separated by ","').grid(columnspan=9, row=(irow:=irow+1), column=0, sticky='w')
	tk.Label(tbl_gen, anchor='w', text='Type :').grid(row=(irow:=irow+1), column=0, sticky='we')
	ctrl_cheby1_type=ttk.Combobox(tbl_gen, justify='left', values=('Low-Pass','High-Pass','Band-Pass','Band-Stop'), state='readonly')
	ctrl_cheby1_type.current(0)
	ctrl_cheby1_type.grid(row=irow, column=1, sticky='we')
	tk.Label(tbl_gen, anchor='e', text='  Freq. : ').grid(row=irow, column=2, sticky='we')
	ctrl_cheby1_freq=tk.Entry(tbl_gen, width=10)
	ctrl_cheby1_freq.grid(row=irow, column=3, sticky='w')
	tk.Label(tbl_gen, anchor='e', text='  Order : ').grid(row=irow, column=4, sticky='we')
	ctrl_cheby1_order=tk.Entry(tbl_gen, width=5, validate='key', validatecommand=(validate_int,'%P'))
	ctrl_cheby1_order.grid(row=irow, column=5, sticky='w')
	tk.Label(tbl_gen, anchor='e', text=' Number of Ripples : ').grid(row=irow, column=6, sticky='we')
	ctrl_cheby1_ripple=tk.Entry(tbl_gen, width=5, validate='key', validatecommand=(validate_int,'%P'))
	ctrl_cheby1_ripple.grid(row=irow, column=7, sticky='w')
	tk.Button(tbl_gen, text="CHOOSE", command=choose_cheby1).grid(row=irow, column=8, padx=5, sticky='e')	
	tk.Label(tbl_gen, text='Chebyshev II : for Band-Pass/Band-Stop, input 2 Freq. separated by ","').grid(columnspan=9, row=(irow:=irow+1), column=0, sticky='w')
	tk.Label(tbl_gen, anchor='w', text='Type :').grid(row=(irow:=irow+1), column=0, sticky='we')
	ctrl_cheby2_type=ttk.Combobox(tbl_gen, justify='left', values=('Low-Pass','High-Pass','Band-Pass','Band-Stop'), state='readonly')
	ctrl_cheby2_type.current(0)
	ctrl_cheby2_type.grid(row=irow, column=1, sticky='we')
	tk.Label(tbl_gen, anchor='e', text='  Freq. : ').grid(row=irow, column=2, sticky='we')
	ctrl_cheby2_freq=tk.Entry(tbl_gen, width=10)
	ctrl_cheby2_freq.grid(row=irow, column=3, sticky='w')
	tk.Label(tbl_gen, anchor='e', text='  Order : ').grid(row=irow, column=4, sticky='we')
	ctrl_cheby2_order=tk.Entry(tbl_gen, width=5, validate='key', validatecommand=(validate_int,'%P'))
	ctrl_cheby2_order.grid(row=irow, column=5, sticky='w')
	tk.Label(tbl_gen, anchor='e', text='  Attenuation (dB) : ').grid(row=irow, column=6, sticky='we')
	ctrl_cheby2_attenuation=tk.Entry(tbl_gen, width=5, validate='key', validatecommand=(validate_float,'%P'))
	ctrl_cheby2_attenuation.grid(row=irow, column=7, sticky='w')
	tk.Button(tbl_gen, text="CHOOSE", command=choose_cheby2).grid(row=irow, column=8, padx=5, sticky='e')	
	tk.Label(tbl_gen, text='Notch/Peak/Comb : Q=Freq/Bandwidth(-3dB)').grid(columnspan=9, row=(irow:=irow+1), column=0, sticky='w')
	tk.Label(tbl_gen, anchor='w', text='Type :').grid(row=(irow:=irow+1), column=0, sticky='we')
	ctrl_npc_type=ttk.Combobox(tbl_gen, justify='left', values=('Notch','Peak','Comb-Notch','Comb-Peak'), state='readonly')
	ctrl_npc_type.current(0)
	ctrl_npc_type.grid(row=irow, column=1, sticky='we')
	tk.Label(tbl_gen, anchor='e', text='  Freq. : ').grid(row=irow, column=2, sticky='we')
	ctrl_npc_freq=tk.Entry(tbl_gen, width=10,  validate='key', validatecommand=(validate_float,'%P'))
	ctrl_npc_freq.grid(row=irow, column=3, sticky='w')
	tk.Label(tbl_gen, anchor='e', text='  Q value : ').grid(row=irow, column=4, sticky='we')
	ctrl_npc_q=tk.Entry(tbl_gen, width=5, validate='key', validatecommand=(validate_float,'%P'))
	ctrl_npc_q.grid(row=irow, column=5, sticky='w')
	tk.Button(tbl_gen, text="CHOOSE", command=choose_npc).grid(row=irow, column=8, padx=5, sticky='e')	
	tbl_coef=ttk.Frame(dlg, padding=(0,10,0,0))
	tbl_coef.pack(side='top', fill='x', ipadx=5, ipady=5)
	var_coef_b=tk.StringVar(value='')
	var_coef_a=tk.StringVar(value='')
	tk.Label(tbl_coef, anchor='w', text='Coef. B :').grid(row=0, column=0, sticky='we')
	tk.Entry(tbl_coef, width=100, textvariable=var_coef_b).grid(row=0, column=1, sticky='we')
	tk.Label(tbl_coef, anchor='w', text='Coef. A :').grid(row=1, column=0, sticky='we')
	tk.Entry(tbl_coef, width=100, textvariable=var_coef_a).grid(row=1, column=1, sticky='we')
	btn_ok=tk.Button(dlg, text="  OK  ", command=dofilter)
	btn_ok.pack(side='right', padx=5, anchor='n', pady=5)
	tk.Button(dlg, text="  Show Freq. Response  ", command=show_freq).pack(side='right', padx=(5,0), anchor='n', pady=5)
	tk.Button(dlg, text="CANCEL", command=lambda: pyplot.close('all') is dlg.destroy()).pack(side='right', anchor='n', pady=5)
	global data
	btn_ok['state']='normal' if data is not None and len(data)>0 else 'disabled'
	dlg.protocol("WM_DELETE_WINDOW", lambda: pyplot.close('all') is dlg.destroy())

#when 'Filter (IIR)' button is clicked
def filter_fir():
	sr=1
	def dofilter():
		global data
		try:
			c=tuple(float(t.strip()) for t in var_coef.get().split(','))
			data=signal.filtfilt(c, 1.0, data)
			plot()
			dlg.destroy()
		except Exception as e:
			tk.messagebox.showerror(title='Error', message=e, parent=dlg)
	def show_freq():
		try:
			c=tuple(float(t.strip()) for t in var_coef.get().split(','))
			w,h=signal.freqz(c, 1.0, worN=250, fs=sr)
			pyplot.close('all')
			fig, ax1=pyplot.subplots()
			fig.subplots_adjust(right=0.85)
			ax1.set_title('Filter frequency response')
			ax1.set_xlabel('Freq. (Hz)')
			ax1.set_ylabel('Response', color='blue')
			ax1.grid()
			ax1.plot(w, numpy.abs(h), linewidth=1, color='blue')
			ax2=ax1.twinx()
			ax2.set_ylabel('Phase (degree)', color='orange')
			ax2.plot(w, numpy.unwrap(numpy.angle(h))*180/3.141592653589793, linewidth=1, color='orange')
			pyplot.show()
		except Exception as e:
			tk.messagebox.showerror(title='Error', message=e, parent=dlg)
	def choose_win1a():
		try:
			type=('lowpass','highpass','bandpass','bandstop')[ctrl_win1a_type.current()]
			width=float(ctrl_win1a_width.get().strip())
			assert width<sr/2 and width>0.0, f'width must be in (0,{sr/2})'
			attenuation=float(ctrl_win1a_attenuation.get().strip())
			freqs=tuple(float(f.strip()) for f in ctrl_win1a_freq.get().split(','))
			for f in freqs:
				assert f<sr/2 and f>0.0, f'frequency must be in (0,{sr/2})'
			n, beta =signal.kaiserord(attenuation, width/0.5)
			if type!='lowpass' and n%2==0:
				n=n+1
			c = signal.firwin(n, freqs, window=('kaiser', beta), pass_zero=type, fs=sr)
			var_coef.set(','.join(str(x) for x in c))
		except Exception as e:
			tk.messagebox.showerror(title='Error', message=e, parent=dlg)
	def choose_win1b():
		try:
			type=('lowpass','highpass','bandpass','bandstop')[ctrl_win1b_type.current()]
			order=int(ctrl_win1b_order.get().strip())
			win=ctrl_win1b_win.get()
			freqs=tuple(float(f.strip()) for f in ctrl_win1b_freq.get().split(','))
			for f in freqs:
				assert f<sr/2 and f>0.0, f'frequency must be in (0,{sr/2})'
			c = signal.firwin(order+1, freqs, window=win, pass_zero=type, fs=sr)
			var_coef.set(','.join(str(x) for x in c))
		except Exception as e:
			tk.messagebox.showerror(title='Error', message=e, parent=dlg)
	def choose_win2():
		try:
			order=int(ctrl_win2_order.get().strip())
			win=ctrl_win2_win.get()
			freqs=tuple(float(f.strip()) for f in ctrl_win2_freq.get().split(','))
			for f in freqs:
				assert f<=sr/2 and f>=0.0, f'frequency must be in [0,{sr/2}]'
			gains=tuple(float(f.strip()) for f in ctrl_win2_gain.get().split(','))
			c = signal.firwin2(order+1, freqs, gains, window=win, fs=sr)
			var_coef.set(','.join(str(x) for x in c))
		except Exception as e:
			tk.messagebox.showerror(title='Error', message=e, parent=dlg)
	dlg=tk.Toplevel(win)
	wingeo=win.geometry().split('+')
	dlg.geometry('+'+str(int(wingeo[1])+50)+'+'+str(int(wingeo[2])+50))
	dlg.grab_set()
	dlg.title('Filter')
	tk.Label(dlg, justify='left', text='''\
Choose filter needed with right parameters for it, to generation the appropriate coefficients,
then click 'OK' button. the coefficients are ',' separated, and the Z-domain transfer function is :
	Y(z)/X(z)=c[0]+c[1]/z+c[2]/z^2+...
''').pack(side='top', anchor='w')
	tbl_gen=tk.Frame(dlg)
	tbl_gen.pack(side='top', fill='x', ipadx=5, ipady=5)
	irow=0
	tk.Label(tbl_gen, text='Win 1.a (Kaiser window) : input Freq. (separated by ",") , width and attenuation').grid(columnspan=9, row=irow, column=0, sticky='w')
	tk.Label(tbl_gen, anchor='w', text='Type :').grid(row=(irow:=irow+1), column=0, sticky='we')
	ctrl_win1a_type=ttk.Combobox(tbl_gen, justify='left', values=('Low-Pass','High-Pass','Band-Pass','Band-Stop'), state='readonly')
	ctrl_win1a_type.current(0)
	ctrl_win1a_type.grid(row=irow, column=1, sticky='we')
	tk.Label(tbl_gen, anchor='e', text='Freq :').grid(row=irow, column=2, sticky='we')
	ctrl_win1a_freq=tk.Entry(tbl_gen, width=10)
	ctrl_win1a_freq.grid(row=irow, column=3, sticky='w')
	tk.Label(tbl_gen, anchor='e', text='Width :').grid(row=irow, column=4, sticky='we')
	ctrl_win1a_width=tk.Entry(tbl_gen, width=10)
	ctrl_win1a_width.grid(row=irow, column=5, sticky='w')
	tk.Label(tbl_gen, anchor='e', text='  Attenuation (dB) : ').grid(row=irow, column=6, sticky='we')
	ctrl_win1a_attenuation=tk.Entry(tbl_gen, width=5, validate='key', validatecommand=(validate_float,'%P'))
	ctrl_win1a_attenuation.grid(row=irow, column=7, sticky='w')
	tk.Button(tbl_gen, text="CHOOSE", command=choose_win1a).grid(row=irow, column=8, padx=5, sticky='e')
	tk.Label(tbl_gen, text='Win 1.b : input Freq. (separated by ",") , order (even num. for other than Low-Pass), window').grid(columnspan=9, row=(irow:=irow+1), column=0, sticky='w')
	tk.Label(tbl_gen, anchor='w', text='Type :').grid(row=(irow:=irow+1), column=0, sticky='we')
	ctrl_win1b_type=ttk.Combobox(tbl_gen, justify='left', values=('Low-Pass','High-Pass','Band-Pass','Band-Stop'), state='readonly')
	ctrl_win1b_type.current(0)
	ctrl_win1b_type.grid(row=irow, column=1, sticky='we')
	tk.Label(tbl_gen, anchor='e', text='Freq :').grid(row=irow, column=2, sticky='we')
	ctrl_win1b_freq=tk.Entry(tbl_gen, width=10)
	ctrl_win1b_freq.grid(row=irow, column=3, sticky='w')
	tk.Label(tbl_gen, anchor='e', text='Order :').grid(row=irow, column=4, sticky='we')
	ctrl_win1b_order=tk.Entry(tbl_gen, width=10)
	ctrl_win1b_order.grid(row=irow, column=5, sticky='w')
	tk.Label(tbl_gen, anchor='e', text=' Window : ').grid(row=irow, column=6, sticky='we')
	ctrl_win1b_win=ttk.Combobox(tbl_gen, justify='left', values=('boxcar','triang','blackman','hamming','hann','bartlett','flattop','parzen','bohman','blackmanharris','nuttall','barthann','cosine','exponential','tukey','taylor'), state='readonly')
	ctrl_win1b_win.current(3)
	ctrl_win1b_win.grid(row=irow, column=7, sticky='we')
	tk.Button(tbl_gen, text="CHOOSE", command=choose_win1b).grid(row=irow, column=8, padx=5, sticky='e')
	tk.Label(tbl_gen, text='Win 2 : input Freq. (0 and '+str(sr/2)+' must be included) and gain pairs (both are separated by ","), order , window').grid(columnspan=9, row=(irow:=irow+1), column=0, sticky='w')
	tk.Label(tbl_gen, anchor='w', text='Freq :').grid(row=(irow:=irow+1), column=0, sticky='we')
	ctrl_win2_freq=tk.Entry(tbl_gen, width=100)
	ctrl_win2_freq.grid(row=irow, column=1, columnspan=8, sticky='w')
	tk.Label(tbl_gen, anchor='w', text='Gain :').grid(row=(irow:=irow+1), column=0, sticky='we')
	ctrl_win2_gain=tk.Entry(tbl_gen, width=100)
	ctrl_win2_gain.grid(row=irow, column=1, columnspan=8, sticky='w')
	tk.Label(tbl_gen, anchor='e', text='Order :').grid(row=(irow:=irow+1), column=4, sticky='we')
	ctrl_win2_order=tk.Entry(tbl_gen, width=10)
	ctrl_win2_order.grid(row=irow, column=5, sticky='w')
	tk.Label(tbl_gen, anchor='e', text=' Window : ').grid(row=irow, column=6, sticky='we')
	ctrl_win2_win=ttk.Combobox(tbl_gen, justify='left', values=('boxcar','triang','blackman','hamming','hann','bartlett','flattop','parzen','bohman','blackmanharris','nuttall','barthann','cosine','exponential','tukey','taylor'), state='readonly')
	ctrl_win2_win.current(3)
	ctrl_win2_win.grid(row=irow, column=7, sticky='we')
	tk.Button(tbl_gen, text="CHOOSE", command=choose_win2).grid(row=irow, column=8, padx=5, sticky='e')
	tbl_coef=ttk.Frame(dlg, padding=(0,10,0,0))
	tbl_coef.pack(side='top', fill='x', ipadx=5, ipady=5)
	var_coef=tk.StringVar(value='')
	tk.Label(tbl_coef, anchor='w', text='Coef :').grid(row=0, column=0, sticky='we')
	tk.Entry(tbl_coef, width=100, textvariable=var_coef).grid(row=0, column=1, sticky='we')
	btn_ok=tk.Button(dlg, text="  OK  ", command=dofilter)
	btn_ok.pack(side='right', padx=5, anchor='n', pady=5)
	tk.Button(dlg, text="  Show Freq. Response  ", command=show_freq).pack(side='right', padx=(5,0), anchor='n', pady=5)
	tk.Button(dlg, text="CANCEL", command=lambda: pyplot.close('all') is dlg.destroy()).pack(side='right', anchor='n', pady=5)
	global data
	btn_ok['state']='normal' if data is not None and len(data)>0 else 'disabled'
	dlg.protocol("WM_DELETE_WINDOW", lambda: pyplot.close('all') is dlg.destroy())

if __name__=='__main__':
	win.mainloop()

aaa.png

文号 / 926256

千古风流
名片发私信
学术分 1
总主题 55 帖总回复 905 楼拥有证书:进士 学者 机友
注册于 2020-01-22 18:44最后登录 2024-12-21 23:01
主体类型:个人
所属领域:无
认证方式:手机号
IP归属地:上海

个人简介

个人开源项目: m24h.github.io

文件下载
加载中...
{{errorInfo}}
{{downloadWarning}}
你在 {{downloadTime}} 下载过当前文件。
文件名称:{{resource.defaultFile.name}}
下载次数:{{resource.hits}}
上传用户:{{uploader.username}}
所需积分:{{costScores}},{{holdScores}}下载当前附件免费{{description}}
积分不足,去充值
文件已丢失

当前账号的附件下载数量限制如下:
时段 个数
{{f.startingTime}}点 - {{f.endTime}}点 {{f.fileCount}}
视频暂不能访问,请登录试试
仅供内部学术交流或培训使用,请先保存到本地。本内容不代表科创观点,未经原作者同意,请勿转载。
音频暂不能访问,请登录试试
投诉或举报
加载中...
{{tip}}
请选择违规类型:
{{reason.type}}

空空如也

插入资源
全部
图片
视频
音频
附件
全部
未使用
已使用
正在上传
空空如也~
上传中..{{f.progress}}%
处理中..
上传失败,点击重试
等待中...
{{f.name}}
空空如也~
(视频){{r.oname}}
{{selectedResourcesId.indexOf(r.rid) + 1}}
处理中..
处理失败
插入表情
我的表情
共享表情
Emoji
上传
注意事项
最大尺寸100px,超过会被压缩。为保证效果,建议上传前自行处理。
建议上传自己DIY的表情,严禁上传侵权内容。
点击重试等待上传{{s.progress}}%处理中...已上传,正在处理中
空空如也~
处理中...
处理失败
加载中...
草稿箱
加载中...
此处只插入正文,如果要使用草稿中的其余内容,请点击继续创作。
{{fromNow(d.toc)}}
{{getDraftInfo(d)}}
标题:{{d.t}}
内容:{{d.c}}
继续创作
删除插入插入
插入公式
评论控制
加载中...
文号:{{pid}}
加载中...
详情
详情
推送到专栏从专栏移除
设为匿名取消匿名
查看作者
回复
只看作者
加入收藏取消收藏
收藏
取消收藏
折叠回复
置顶取消置顶
评学术分
鼓励
设为精选取消精选
管理提醒
编辑
通过审核
评论控制
退修或删除
历史版本
违规记录
投诉或举报
加入黑名单移除黑名单
查看IP
{{format('YYYY/MM/DD HH:mm:ss', toc)}}
ID: {{user.uid}}