基于FPGA的任意点滑动平均(滑动窗长度和数据位宽参数化,例化时参数可设置)

目录

  • 1.前言
  • 2.原理
  • 3.举例说明
  • 4.Matlab实现
  • 5.FPGA实现滑动平均

微信公众号获取更多FPGA相关源码:
在这里插入图片描述

1.前言

对于一维信号,我们可以使用类似移动平均滤波(Moving Average Filtering)实现denoising。Moving Average Filtering 是一种简单的信号滤波算法,用于减小信号中的噪声或去除高频成分,从而平滑信号。它基于对信号中一定窗口内数据的平均值进行计算。移动平均滤波可以平滑信号,但对快速变化的信号可能响应较慢。

2.原理

给定一个包含 N 个样本的信号序列$ x [ n ] $,其中 n 是样本的索引(从 0 到 N-1)。移动平均滤波通过在信号序列上滑动一个固定长度为 M 的窗口,并计算窗口内样本的平均值来进行滤波。

对于滑动窗口的每个位置 k,滤波后的输出 y[k] 可以通过以下公式计算:
y [ k ] = x [ k ] + x [ k − 1 ] + x [ k − 2 ] + . . . + x [ k − M + 1 ] M y[k]= x[k]+x[k−1]+x[k−2]+...+x[k−M+1] \over M My[k]=x[k]+x[k1]+x[k2]+...+x[kM+1]

其中,$x [ k ] $表示信号序列中索引为 k 的样本值。公式中的 $1 / M $ 是归一化因子,用于平均化窗口内的样本值。

移动平均滤波的核心思想是利用窗口内多个样本的平均值来代表当前样本的值,从而减小随机噪声或高频成分对信号的影响。滑动窗口的大小 M 决定了平滑的程度,较大的窗口可以更有效地平滑信号,但可能会导致滞后响应;较小的窗口可以更快地响应信号的变化,但平滑效果可能较差。

需要注意的是,移动平均滤波是一种线性滤波方法,主要适用于平稳信号或缓慢变化的信号。对于包含快速变化的信号或脉冲信号,移动平均滤波可能导致平滑效果不佳或信号失真。在实际应用中,根据具体的信号特性和需求,可以选择不同的滤波方法以获得更好的结果。

3.举例说明

比方说,当我们有一个包含噪声的信号序列时,例如:
x = [ 2 , 4 , 3 , 7 , 6 , 5 , 10 , 8 , 9 , 12 ] x=[2,4,3,7,6,5,10,8,9,12] x=[2,4,3,7,6,5,10,8,9,12]
我们可以使用移动平均滤波来平滑信号并减小噪声的影响。假设我们选择一个窗口大小为3,即每次计算三个样本的平均值。
第一个输出样本为:
y [ 0 ] = ( 1 / 3 ) ∗ ( 2 + 4 + 3 ) = 3 y[0]=(1/3)∗(2+4+3)=3 y[0]=(1/3)(2+4+3)=3
第二个输出样本为:
y [ 1 ] = ( 1 / 3 ) ∗ ( 4 + 3 + 7 ) = 4.67 y[1]=(1/3)∗(4+3+7)=4.67 y[1]=(1/3)(4+3+7)=4.67
以此类推,我们可以继续计算后续输出样本。如果数学比较好的朋友,此刻大概能看出这其实就是卷积。
而卷机核函数,就是长度为N,元素值为 1 N \frac{1}{N} N1。所以,我们可以使用Matlab的filter函数来实现Moving Average Filtering(滑动平均)。

4.Matlab实现

网上找了一段别人采集的原始信号数据如下:

y0 =

  列 1 至 16

    0.0300   -1.4600   -0.2600   -0.4700   -1.4600   -0.0600   -0.4700   -1.2700    0.1500   -0.4700   -1.4700   -0.0100   -0.4700   -1.2700    0.1700   -0.6300

  列 17 至 32

   -1.3700    0.1500   -0.8800   -1.0700    0.2500   -0.8800   -1.2700    0.2500   -0.8800   -1.0700    0.4000   -1.0800   -1.0700    0.1100   -1.2800   -0.8700

  列 33 至 48

    0.2100   -1.2800   -0.9400    0.3600   -1.2800   -0.4600    0.2500   -1.2800   -0.4600    0.2300   -1.2300   -0.4600   -0.0700   -1.3100   -0.4600    0.2300

  列 49 至 64

   -1.3100   -0.4600    0.1300   -1.4900   -0.4600   -0.4700   -1.3900   -0.4600   -0.4700   -1.4400   -0.3600    0.0300   -1.4400   -0.2600    0.0300   -1.5600

  列 65 至 80

   -0.2600   -0.4700   -1.4100   -0.2600   -0.4700   -1.6000   -0.2600   -0.4700   -1.2700    0.0700   -0.4700   -1.4200    0.1500   -0.8800   -1.2700    0.3000

  列 81 至 96

   -1.0800   -1.0700    0.1800   -1.3400   -0.4600    1.8600    6.6500    9.0600    8.0300    7.1400    7.7900    4.7900    2.8800    3.0800    1.5500    1.2600

  列 97 至 112

    1.9600    0.4400    0.9600    1.4500   -0.0900    1.1600    0.9400   -0.2600    1.1600   -0.4700   -1.2700    0.1000   -1.2800   -0.4600    0.1800   -1.3100

  列 113 至 128

   -0.4600   -0.1200   -1.4900   -0.0100   -0.6800   -1.2700    0.0400   -1.0800   -0.4600    0.2300   -1.2800   -0.4600   -0.4700   -1.4600   -0.3100   -0.4700

  列 129 至 144

   -1.4500    0.1500   -0.5800   -1.4700    0.1500   -0.8800   -1.2700    0.2500   -0.8800   -1.2700    0.3500   -1.0800   -1.1700    0.2200   -1.0800   -1.0700

  列 145 至 160

    0.1100   -1.2800   -1.0700    0.4000   -1.2800   -2.4900   -7.3600  -11.0100   -9.9800   -7.3900   -9.1900   -6.9400   -4.0700   -4.6000   -3.7000   -1.9800

  列 161 至 176

   -3.3100   -2.6900   -1.3000   -2.7000   -2.4900   -1.1300   -2.5000   -2.0800   -0.6800   -1.6900   -0.4600    0.0300   -1.3900   -0.4600    0.2100   -1.3100

  列 177 至 192

   -0.4600    0.0800   -1.3900   -0.7700    0.1300   -1.4900   -0.4600    0.2300   -1.4900   -0.4600   -0.0200   -1.4900   -0.4100    0.1800   -1.4600   -0.4600

  列 193 至 208

   -0.4700   -1.4200   -0.2600   -0.4700   -1.4400   -0.2600   -0.4700   -1.5500   -0.0100   -0.5800   -1.4200   -0.4600   -0.4700   -1.4500   -0.0600   -0.5000

  列 209 至 224

   -1.2700    0.1500   -0.8800   -1.2700    0.3500   -1.2800    0.5500    7.4800    8.3300    8.7600    7.8300    6.8300    5.7200    3.4800    1.9700    2.5400

  列 225 至 240

    1.0200    1.3600    1.8600    0.3400    0.9600    0.9400   -0.0600    1.1600    0.3400   -0.0600    0.5100   -1.2800   -0.4600    0.1300   -1.4400   -0.2600

  列 241 至 256

   -0.4700   -1.4500    0.0600   -0.7000   -1.2200    0.3200   -1.1800   -0.4600    0.0700   -1.5400   -0.3100   -0.4700   -1.2700    0.1500   -0.9800   -1.1700

  列 257 至 272

    0.2600   -1.2300   -0.4600   -0.0700   -1.3400   -0.4600   -0.0700   -1.3000   -0.1600   -0.4700   -1.4900   -0.2600   -0.4700   -1.4500   -0.0600   -0.4700

  列 273 至 288

   -1.4700    0.0400   -0.6800   -1.4200    0.0700   -0.8800   -2.6100   -7.1500  -10.3000  -10.3400   -7.3000   -8.5800   -7.7500   -4.1100   -4.3200   -3.9100

  列 289 至 304

   -1.6300   -3.0100   -3.1000   -1.2100   -2.6000   -2.4900   -1.0600   -2.3000   -2.0800   -0.6600   -1.4900   -1.1700    0.1200   -1.2800   -0.4600    0.3100

  列 305 至 320

   -1.3400   -0.4600    0.0600   -1.4900   -0.4600   -0.0700   -1.3900   -0.4100   -0.4700   -1.4900   -0.4600   -0.4700   -1.4400   -0.3600   -0.1200   -1.4600

  列 321 至 331

   -0.0600   -0.4700   -1.4200   -0.2100   -0.4700   -1.4700   -0.0600   -0.5300   -1.2700    0.1700   -0.6800

为了直观,下面简单的画一下他的图:

y0=[0.03	-1.46	-0.26	-0.47	-1.46	-0.06	-0.47	-1.27	0.15	-0.47	-1.47	-0.01	-0.47	-1.27	0.17	-0.63	-1.37	0.15	-0.88	-1.07	0.25	-0.88	-1.27	0.25	-0.88	-1.07	0.4	-1.08	-1.07	0.11	-1.28	-0.87	0.21	-1.28	-0.94	0.36	-1.28	-0.46	0.25	-1.28	-0.46	0.23	-1.23	-0.46	-0.07	-1.31	-0.46	0.23	-1.31	-0.46	0.13	-1.49	-0.46	-0.47	-1.39	-0.46	-0.47	-1.44	-0.36	0.03	-1.44	-0.26	0.03	-1.56	-0.26	-0.47	-1.41	-0.26	-0.47	-1.6	-0.26	-0.47	-1.27	0.07	-0.47	-1.42	0.15	-0.88	-1.27	0.3	-1.08	-1.07	0.18	-1.34	-0.46	1.86	6.65	9.06	8.03	7.14	7.79	4.79	2.88	3.08	1.55	1.26	1.96	0.44	0.96	1.45	-0.09	1.16	0.94	-0.26	1.16	-0.47	-1.27	0.1	-1.28	-0.46	0.18	-1.31	-0.46	-0.12	-1.49	-0.01	-0.68	-1.27	0.04	-1.08	-0.46	0.23	-1.28	-0.46	-0.47	-1.46	-0.31	-0.47	-1.45	0.15	-0.58	-1.47	0.15	-0.88	-1.27	0.25	-0.88	-1.27	0.35	-1.08	-1.17	0.22	-1.08	-1.07	0.11	-1.28	-1.07	0.4	-1.28	-2.49	-7.36	-11.01	-9.98	-7.39	-9.19	-6.94	-4.07	-4.6	-3.7	-1.98	-3.31	-2.69	-1.3	-2.7	-2.49	-1.13	-2.5	-2.08	-0.68	-1.69	-0.46	0.03	-1.39	-0.46	0.21	-1.31	-0.46	0.08	-1.39	-0.77	0.13	-1.49	-0.46	0.23	-1.49	-0.46	-0.02	-1.49	-0.41	0.18	-1.46	-0.46	-0.47	-1.42	-0.26	-0.47	-1.44	-0.26	-0.47	-1.55	-0.01	-0.58	-1.42	-0.46	-0.47	-1.45	-0.06	-0.5	-1.27	0.15	-0.88	-1.27	0.35	-1.28	0.55	7.48	8.33	8.76	7.83	6.83	5.72	3.48	1.97	2.54	1.02	1.36	1.86	0.34	0.96	0.94	-0.06	1.16	0.34	-0.06	0.51	-1.28	-0.46	0.13	-1.44	-0.26	-0.47	-1.45	0.06	-0.7	-1.22	0.32	-1.18	-0.46	0.07	-1.54	-0.31	-0.47	-1.27	0.15	-0.98	-1.17	0.26	-1.23	-0.46	-0.07	-1.34	-0.46	-0.07	-1.3	-0.16	-0.47	-1.49	-0.26	-0.47	-1.45	-0.06	-0.47	-1.47	0.04	-0.68	-1.42	0.07	-0.88	-2.61	-7.15	-10.3	-10.34	-7.3	-8.58	-7.75	-4.11	-4.32	-3.91	-1.63	-3.01	-3.1	-1.21	-2.6	-2.49	-1.06	-2.3	-2.08	-0.66	-1.49	-1.17	0.12	-1.28	-0.46	0.31	-1.34	-0.46	0.06	-1.49	-0.46	-0.07	-1.39	-0.41	-0.47	-1.49	-0.46	-0.47	-1.44	-0.36	-0.12	-1.46	-0.06	-0.47	-1.42	-0.21	-0.47	-1.47	-0.06	-0.53	-1.27	0.17	-0.68];
figure
plot(y0)
title("原始信号")

采集的原始信号

使用Matlab的filter函数进行4点的滑动平均:

%% Matlab仿真
windowSize = 3; %滑动窗点数
b = (1/windowSize)*ones(1,windowSize);
a = 1;
y1 = filter(b,a,y0);
 
figure
subplot(3,1,1)
plot(y0)
title("原始信号")
 
subplot(3,1,2)
plot(y1)
title("滑动平均滤波后")
 
subplot(3,1,3)
plot(y0)
hold on
plot(y1)
title("对比")

Matlab仿真的滑动平均

5.FPGA实现滑动平均

模块的输入输出框图如下所示:

输入输出框图

模块功能:对输入信号取滑动平均值。例化调用格式如下:

MovAvg 
#(  .N(N),//滑动平均点数,2的n次方
    .WIDTH(WIDTH))数据位宽
u1(
       .clk     	(clk)           ,
       .rst_n   	(rst_n)         ,
	   .din_vaild	(din_vaild)		,	
       .din     	(din)           ,
       .dout  		(dout)			,
	   .dout_vaild	(dout_vaild)
);

参数N表示求N个点的平均值,参数WIDTH控制输入信号位宽,可以在例化调用的时候配置参数。

配置参数为16点滑动平均,位宽为8,使用依次递增1的数据进行测试:

16点滑动平均

配置参数为4点滑动平均,位宽为8,使用上面的数据输入进行测试,按照如下代码将数据存储到txt文件里面:

q = quantizer('fixed','round','saturate',[8,3]);%复数以8位定点数形式进行输出,格式为:1位符号位,4位整数位,3位小数位,负数以补码形式表示。
y0_q = num2hex(q,y0);%量化

fid= fopen([PATH,'test_data.txt'],'w');
fprintf(fid,'%c%c\r\n',y0_q');

整体仿真截图

局部仿真放大图

对上面第4小节,Matlab实现的4点滑动平均进行对比:

Matlab仿真和FPGA输出结果对比

测试激励代码(注释部分为配置参数为16点滑动平均,位宽为8,使用依次递增1的数据进行测试):

`timescale 1ns / 1ps

module MovAvg_tb;
parameter		T = 20;//仿真时钟周期
parameter		NUM  = 331			;//测试数据个数
parameter		N = 4				;//滑动平均点数,2的n次方
parameter		WIDTH = 8			;//数据位宽
parameter		PATH = "D:/FPGA/FPGA_university/gra_stu_FPGA_class/MovAvg/";//文件路径
reg             clk					;
reg             rst_n				;
reg				din_vaild			;
reg  signed[7:0]   din				;
wire signed[7:0]   dout				;
wire			dout_vaild			;
reg   	[7:0]	test_data [NUM-1:0]	;
integer			i					;
integer signed	data_out			;
MovAvg #(.N(N),.WIDTH(WIDTH))
u1(
       .clk     	(clk)           ,
       .rst_n   	(rst_n)         ,
	   .din_vaild	(din_vaild)		,	
       .din     	(din)           ,
       .dout  		(dout)			,
	   .dout_vaild	(dout_vaild)
);
always #(T/2) clk = ~clk;
initial begin
    rst_n = 1'b0;
	din_vaild = 1'b0;
    clk = 1'b1;
	
	$readmemh({PATH,"test_data.txt"},test_data,0,NUM-1);
	data_out  =  $fopen({PATH,"data_out.txt"});
	
    #(T*5)
    rst_n = 1'b1;
	din_vaild = 1'b1;
	//test_data测试数据输入
	for(i=0;i<NUM;i=i+1)begin
		din = test_data[i];
		#T;
	end
	din_vaild = 1'b0;
end

//数据存储,由于从第N个点开始有效,输出会少N-1个数据
always@(posedge clk)
begin
  if(dout_vaild)
    begin
      $fdisplay(data_out,"%d",dout);
    end
end

//输入为连续累加1数据的测试
/* always @(posedge clk or negedge rst_n)
    if (!rst_n)
        din <= 8'b0;
    else
        din <= din + 1'b1; */

endmodule

下载工程源码链接:https://mp.weixin.qq.com/s?__biz=MzkxNjM0NDk2Nw==&mid=2247486083&idx=1&sn=e942deb7b27b2b7a3231751f803b158c&chksm=c150136bf6279a7d90128972cda2b7075a63d25fa3ce839c31b68ec66731d07478f4555dd6e4#rd
也可以选择此跳转

微信公众号获取更多FPGA相关源码:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/685638.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

算法金 | 再见!!!KNN

大侠幸会&#xff0c;在下全网同名「算法金」 0 基础转 AI 上岸&#xff0c;多个算法赛 Top 「日更万日&#xff0c;让更多人享受智能乐趣」 KNN算法的工作原理简单直观&#xff0c;易于理解和实现&#xff0c;这使得它在各种应用场景中备受青睐。 我们将深入探讨KNN算法&…

微服务+分库分表的自增主键ID该如何设计?

一. 前言 分布式ID 是分布式系统里面非常重要的一个组成部分&#xff0c;那么我们在设计分布式ID的时候&#xff0c;需要考虑什么问题呢&#xff1f; ❓简单结构下是怎么实现 ID 的控制的&#xff1f; 单实例系统 &#xff1a;通过时间戳&#xff0c;系统内自增&#xff0c;上…

【高校科研前沿】新疆生地所陈亚宁研究员团队在GeoSus发文:在1.5°C和2°C全球升温情景下,中亚地区暴露于极端降水的人口增加

目录 文章简介 1.研究内容 2.相关图件 3.文章引用 文章简介 论文名称&#xff1a;Increased population exposures to extreme precipitation in Central Asia under 1.5 ◦C and 2 ◦C global warming scenarios&#xff08;在1.5C和2C全球变暖情景下&#xff0c;中亚地区…

flutter LINK : ...fatal error LNK1168: �޷���...

执行 flutter run -d windows 后报错 LINK : fatal error LNK1168: &#xfffd;޷&#xfffd;&#xfffd;&#xfffd; E:\xiaoli\flutter_project\huapu_update_hardware\build\windows\x64\runner\Debug\huapu_update_hardware.exe &#xfffd;&#xfffd;&#xfffd;…

gstreamer+mpp调用硬解码播放视频

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、cpu解码二、gstreamermpp1.默认已安装2.没安装必要软件 总结 前言 以前一直在MPP上开发硬解码推理&#xff0c;最近想弄一个盒子支持调用mpp硬解码播放视频…

OZON快蜗牛数据工具,OZON数据分析工具

在当今的电商时代&#xff0c;数据已经成为了商家们最宝贵的资产之一。无论是产品选品、市场定位&#xff0c;还是营销策略的制定&#xff0c;都离不开对数据的深入分析和精准把握。而在众多电商平台中&#xff0c;OZON以其独特的商业模式和庞大的用户群体&#xff0c;吸引了众…

Docker高级篇之Dockerfile解析

文章目录 1. DockerFile简介2. DockerFile的构建过程3. DockerFile的常用保留字4. 使用案例5. 虚悬镜像 1. DockerFile简介 DockerFile是用来构建Docker镜像的文本文件&#xff0c;是由一条条构建镜像的指令和参数构成的脚本。 2. DockerFile的构建过程 DockerFile内容的基…

DpEasy社区版1.4.0 | 体验全新的数据库特权账号管理平台!

上周&#xff0c;我们在社区发布了 DpEasy 调整为数据库特权账号管理平台的说明&#xff08;详见文章《“一键”掌控数据库特权&#xff0c;DpEasy 新版本即将起航》&#xff09;。今天&#xff0c;DpEasy 作为数据库特权账号管理平台正式发布了第一个版本&#xff0c;即 DpEas…

惠海 H5112C DC-DC降压恒流 PWM调光芯片12V 24V 36V 48V 60V 共阳无频闪 调光细腻顺滑

H5112C多功能平均电流型LED恒流驱动器是一款性能良好的产品&#xff0c;专为大功率恒流LED驱动领域设计。它具备以下显著特点&#xff1a; 宽电压范围&#xff1a;这款驱动器支持5-90V的宽电压输入范围&#xff0c;使其能够适应许多应用环境&#xff0c;有其稳定驱动性能。 准…

【PL理论】(6) F#:标准库之列表(List)

​​​​​ &#x1f4ad; 写在前面&#xff1a;本章我们将介绍 F# 标准库的列表&#xff0c;我们将简单的先过一遍列表的一些常用操作&#xff0c;具体的讲解我们将放在后续章节。 目录 0x00 标准库&#xff1a;列表&#xff08;List&#xff09; 0x01 模式匹配与列表 0x…

【机器学习系列】“购物篮分析入门:使用Apyori库进行关联规则挖掘”

目录 一、关联分析介绍 关键概念&#xff1a; 1. 支持度&#xff08;Support&#xff09; 2. 置信度&#xff08;Confidence&#xff09; 3. 提升度&#xff08;Lift&#xff09; 4. 频繁项集 5. 关联规则 应用场景&#xff1a; 实现方法 二、导入数据集 额外介绍一…

C语言小例程6/100

题目&#xff1a;输入三个整数x,y,z&#xff0c;请把这三个数由小到大输出。 程序分析&#xff1a;我们想办法把最小的数放到x上&#xff0c;先将x与y进行比较&#xff0c;如果x>y则将x与y的值进行交换&#xff0c;然后再用x与z进行比较&#xff0c;如果x>z则将x与z的值…

信号:干扰类别及特征提取

目录 第一部分&#xff1a;干扰类别 1.压制干扰 1.1噪声调幅瞄准式干扰(单音干扰) 1.2噪声调频阻塞式干扰&#xff08;宽带噪声干扰&#xff09; 1.3噪声调频扫频式干扰&#xff08;线性调频&#xff09; 2.欺骗干扰 2.1距离欺骗干扰&#xff08;幅度调制干扰&#xff0…

现代密码学-X.509认证业务

X.509的基础式公钥密码体制和数字签名。 证书 证书的格式 证书由可信的认证机构CA建立并由CA或者用户自己将其放入目录&#xff0c;以供其他用户方便访问。目录服务器本身并不负责为用户建立公钥证书&#xff0c;仅仅为用户访问公钥提供方便。 x.509证书格式 证书的获取 其…

详解 Flink 的运行架构

一、组件 1. JobManager 作业管理器是一个 Flink 集群中任务管理和调度的核心&#xff0c;是控制应用执行的主进程 1.1 JobMaster JobMaster 是 JobManager 中最核心的组件&#xff0c;负责处理单独的作业&#xff08;Job&#xff09;。JobMaster 和具体的 Job 是一一对应的&…

QT快速下载

去QT官网之后&#xff0c;如下图所示 比如要下载qt-opensource-windows-x86-5.14.2.exe&#xff0c;进入5.14对应的文件夹&#xff0c;找到对应的版本 点击Details&#xff0c; 下载对应的种子&#xff0c;然后通过迅雷下载 个人实测&#xff0c;家庭网络平均18M的速率

【云岚到家】-day01-项目熟悉-查询区域服务开发

文章目录 1 云岚家政项目概述1.1 简介1.2 项目业务流程1.3 项目业务模块1.4 项目架构及技术栈1.5 学习后掌握能力 2 熟悉项目2.1 熟悉需求2.2 熟悉设计2.2.1 表结构2.2.2 熟悉工程结构2.2.3 jzo2o-foundations2.2.3.1 工程结构2.2.3.2 接口测试 3 开发区域服务模块3.1 流程分析…

uinty游戏界面模糊的解决方法

1.把低分辨率关掉 2.调缩放&#xff0c;不要调长宽高 3.调整画布的分辨率 4.调整图片的像素点

令人沉醉的移动端 UI 风格

小程序 UI 风格&#xff0c;独具匠心

Vivado 设置关联使用第三方编辑器 Notepad++

目录 1.前言2.Vivado关联外部编辑器步骤3.Notepad的一些便捷操作 微信公众号获取更多FPGA相关源码&#xff1a; 1.前言 Vivado软件自带的编辑器超级难用&#xff0c;代码高亮对比不明显&#xff0c;而且白色背景看久了眼睛痛。为了写代码时有更加舒适的体验&#xff0c;可以…