element upload 图片上传 回显 及删除

element upload 图片上传 回显 及删除 目标需求 图片上传图片回显可以删除图片效果图 实现 模板 <el-form-item :label="$t('station.img')" prop="images"> <el-upload :limit="3" action="" accept=".png, .jpg" show-file-list :on-change="handleChange" :on-remove="handleRemove" list-type="picture-card" :file-list="fileList" :auto-upload="false" multiple > <i slot="default" class="el-icon-plus" /> </el-upload> </el-form-item> js data() { return { fileList: [],//这个必须要有,用来同步组件中的fileList form:{ images:[] //表单中的图片列表 } } methods: { // 删除图片时候同步到表单删除 handleRemove(file, fileList) { const index = this.fileList.findIndex((item) => { return item.uid === file.uid }) this.form.images.splice(index, 1) this.fileList.splice(index, 1) }, // 上传 handleChange(file, fileList) { const isImg = (file.

new一个构造函数时做了那些事情

new做了那些事情? 1、创建一个空对象; 2、将空对象的原型,指向于构造函数的原型; 3、将空对象作为构造函数的上下文(改变this指向); 4、对有返回值的构造函数做判断处理 手写new函数 function Queue(name){ this.name = name; //如果函数有返回值,则new的结果就是此函数return的结果 // return { // a:'ooo' // } } function myNew(context,...args){ //new操作符本身返回的是一个对象,所以先创建一个对象 const obj = Object.create({}); //将创建的对象的原型指向传递进来的构造函数的原型 obj.__proto__ = context.prototype; //改变构造函数的this指向,将其改为obj,此时obj就有了构造函数身上的属性和方法 const result = context.apply(obj,args); //此时如果构造函数本身有返回值,且是对象,则让让其返回本身的返回值, //如过构造函数没有返回值,则result是undefind,则让其返回obj return typeof result === 'object'? result:obj } //下面两个的打印结果是相同的,可见myNew函数实现了new的作用 console.log(myNew(Queue(),'wangzhi')) const a = new Queue('wangzhi') console.log(a)

Java去除字符串中的空格

String str=" Hello word "; str=str.trim(); System.out.println(str); //输出:Hello word trim只能去除字符串首尾的空格,如果想要去除字符串中的所有空格,可用repalce(" ", ""); \r 回车(\u000a) \t 水平制表符(\u0009) \s 空格(\u0008) \n 换行(\u000d) Str.replaceALL("\\s*|\r|\n|\t","")

利用鱼眼畸变OpenCV的方式进行图像矫正

import cv2 # 读取原始图像 img = cv2.imread('fish_eye_image.jpg') # 相机矩阵 K = [[fx, 0, cx], [0, fy, cy], [0, 0, 1]] # 畸变系数 dist = [k1, k2, k3, k4] # 使用鱼眼畸变校正函数进行校正 mapx, mapy = cv2.fisheye.initUndistortRectifyMap(np.array(K), np.array(dist), np.eye(3), K, img.shape[:2], cv2.CV_16SC2) dst = cv2.remap(img, mapx, mapy, interpolation=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT) # 显示消除畸变后的图像 cv2.imshow('Undistorted Image', dst) cv2.waitKey(0) cv2.destroyAllWindows() import cv2 # 读取原始图像 img = cv2.imread('fish_eye_image.jpg') # 相机矩阵 K = [[fx, 0, cx], [0, fy, cy], [0, 0, 1]] # 畸变系数 dist = [k1, k2, k3, k4] # 使用鱼眼畸变校正函数进行校正 mapx, mapy = cv2.

dagreD3.js: 一个基于D3的专注于有向图布局(流程图)javascript库。

dagreD3.js: 一个基于D3的专注于有向图布局(流程图)javascript库。 参考原文链接:dagre/dagre-d3绘制流程图 参考原文链接:dagre/dagre-d3绘制流程图 参考原文链接:dagre/dagre-d3绘制流程图 一开始是用的echarts的关系图,type:‘graph’,但是关系图里面的series.data 很不好处理,他需要每个点的X,Y坐标.后来又换成了关系图和线图type:'line’的结合体,但是依然是老问题,data里面需要横纵坐标,line里面需要source和target,谁指向谁. 然后直接百度qcc的股权穿刺图,发现基本上都是用到d3写的,但是d3框架有点大,学起来,阅读代码起来都是1000行起步,难的去看.后来找到这个基于d3的dagreD3.js,发现写起来就比较方便了,废话不多说,直接撸代码. npm i dagre-d3 npm i d3@5.16.0 //我这里安装的v5版本,d3现在最新的版本应该到v7了,一开始安装的是v7,但是v7有些东西没有,例如下面代码的event // 引入 import dagreD3 from "dagre-d3"; import * as d3 from "d3"; // vue 里面的data数据 data () { return { list: { nodeInfos: [ // 节点数组 ], edges: [ //节点之间关系数组 ] }, tooltip: this.createTooltip(), //创建tooptip窗体 ,即鼠标移入有窗体显示 gGraph: new dagreD3.graphlib.Graph().setGraph({ // 初始画布板式 rankdir:'TB', //设置 node 节点的延伸排列方向,它有4个值: TB, BT, LR, 或者 RL 可选,默认是’TB’(从上到下)。 align:'DL', nodesep: 100, edgesep:100, ranksep: 50, marginx:50, marginy:100 }) }; }, created () { this.

[SpringBoot Server]SpringBoot tomcat配置

目录 1、需要注意的通用配置1.1 tomca默认配置 2、通过application.yaml配置tomcat3、 ServerProperties类(略看一下,ServerProperties中有tomcat静态内部类) 惯例,先摆一个官网文档。 cp配置跳转至第二章。 SpringBoot 默认嵌入的是tomcat,不同应用也提供了其他选择。 For servlet stack applications, the spring-boot-starter-web includes Tomcat by including spring-boot-starter-tomcat, but you can use spring-boot-starter-jetty or spring-boot-starter-undertow instead. For reactive stack applications, the spring-boot-starter-webflux includes Reactor Netty by including spring-boot-starter-reactor-netty, but you can use spring-boot-starter-tomcat, spring-boot-starter-jetty, or spring-boot-starter-undertow instead. 关于服务器配置,初步的需要注意的事项为 并发数、请求响应。这些在tomcat中对应的分别是 工作线程数、最大请求连接数、响应时间。 当cpu线程数小于应用线程数时,操作系统使用时间片机制,采用线程调度算法,频繁的进行线程切换 1、需要注意的通用配置 官方文档 通用配置中,个人认为需要注意的如下: server.max-http-header-size Maximum size of the HTTP message header. HTTP请求头的最大大小,默认 8kb server.servlet.encoding.charset Charset of HTTP requests and responses.

MOS管选型参数:VGS(th)

MOS管选型参数:VGS(th) VGS(th):开启电压(阀值电压)。当外加栅极控制电压 VGS 超过 VGS(th) 时,漏区和源区的表面反型层形成了连接的沟道。应用中,常将漏极短接条件下 ID 等于 1 毫安时的栅极电压称为开启电压。此参数一般会随结温度的上升而有所降低 MOS管 一般都存在 VGS(th) 这一参数,不同厂家的MOS管,该参数也不尽相同。它一般是一个范围。为什么是一个范围呢?那是因为厂家生产的一批器件该参数不可能完全一致,存在一定的离散性。下面就来看几种不同MOS管的VGS(th): 1、KS1206DB: 1~2.5V 2、KSB203DA: 3~4.5V 3、 RM135N100HD: 2.5~4.5V 4、NTD6415ANL: 1~2.0V 5、TMA30N10H: 2~4V 6、YJD15N10A: 1~2.5V 7、YJD40G10A: 1~2.5V 说明 当你的驱动电压已经确定的时候,选择MOS管时,要着重关注此参数,比如驱动电压到电平为5V时,选择VGSth 时就要尽量选择VGSth 上限为4V以下的,倘若选择VGSth 上限为4.5V左右的MOS管,由于器件参数的离散性,厂家标称的参数VGSth上限为4.5V, 个别器件实际参数可能更高,电路可能无法正常运行。所以选型时参数要留出一定的裕量。

修改(elementui)el-table底层背景色

1. 需求:仅修改当前页面的背景色,不修改所有el-table的背景色。 先给table添加类名(如class="styleTable") 在style上面添加scoped 写法:类名 ::v-deep .el-table类名{} 注意:给styleTable也设置背景色为透明才生效。 如下图所示👇 2. 需求:修改全局背景色 单独创建一个css文件,给el-table th,el-table_cell等你要修改的类名添加背景色为透明;在每个vue页面都引用此文件即可生效。 扩展 (也可以不用看) 需求:设置table的最低高度 把padding的值设为0即可。 .el_table .el_table_cell{ padding:0px } 2. 怎么找是设置哪一个样式的属性? F12打开控制台,然后找到Elements,点击【箭头】选中表格,然后到它的属性,我比较笨,我是一个一个试,最后发现.el_table .el_table_cell 设置了就成功了。 此文档仅供参考哈,鄙人也是刚踏进前端的门,可能写的有误,还请高人指导。🙏

SpringBoot 多数据源切换(超级简单)

背景:主从架构下,数据库的读写分离 1. 依赖 <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.3</version> </dependency> <!--引入baomidou的切换数据源的依赖--> <dependency> <groupId>com.baomidou</groupId> <artifactId>dynamic-datasource-spring-boot-starter</artifactId> <version>3.6.1</version> </dependency> </dependencies> 2.配置数据源 spring: datasource: dynamic: primary: master strict: true datasource: master: url: jdbc:mysql://127.0.0.1:3307/user1?useUnicode=true&characterEncoding=utf8&useSSL=false username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver slave_1: url: jdbc:mysql://127.0.0.1:3308/user1?useUnicode=true&characterEncoding=utf8&useSSL=false username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver 3. 使用 (使用 @DS 切换数据源。) @DS 可以注解在方法上或类上,同时存在就近原则 方法上注解 优先于 类上注解。 注解结果没有@DS默认数据源@DS(“dsName”)dsName可以为组名也可以为具体某个库的名称 4.

设计模式学习笔记 - 外观模式

设计模式学习笔记 - 外观模式 一、影院管理问题二、传统方式解决影院管理问题三、外观模式介绍1、基本介绍2、原理类图 四、外观模式解决影院管理问题五、外观模式在MyBatis框架应用的源码分析六、外观模式的注意事项和细节 一、影院管理问题 组建一个家庭影院:DVD 播放器、投影仪、自动屏幕、环绕立体声、爆米花机。要求完成使用家庭影院的功能,其过程为直接用遥控器统筹各设备开关: 1.打开爆米花机 2.放下屏幕 3.打开投影仪 4.打开音响 5.打开DVD,选dvd 6.去拿爆米花 7.调暗灯光 8.播放dvd 9.观影结束后,关闭各种设备 二、传统方式解决影院管理问题 类图: 传统方式解决影院管理问题分析: (1)在 Client的main方法中,创建各个子系统的对象,并直接去调用子系统(对象)相关方法,会造成调用过程混乱,没有清晰的过程。在Client中不利于去维护对子系统的操作。 (2)解决思路:定义一个高层接口,给子系统中的一组接口提供一个一致的界面(比如在高层接口中提供四个方法on、play、pause、off),用来访问子系统中的一群接口。也就是说,通过定义一个一致的接口(界面类),用以屏蔽内部子系统的细节,使得调用端只需跟这个一致的接口发生调用,而无需关心这个子系统的内部细节。这就是使用了外观模式。 三、外观模式介绍 1、基本介绍 外观模式(Facade Pattern),也叫“过程模式”。外观模式为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。 外观模式通过定义一个一致的接口,用以屏蔽内部子系统的细节,使得调用端只需跟这个接口发生调用,而无需关心这个子系统的内部细节。 外观模式可以理解为转换一群接口,客户只要调用一个接口,而不用调用多个接口才能达到目的。 外观模式就是解决多个复杂接口带来的使用困难,起到简化用户操作的作用。 2、原理类图 说明: 外观类(Facade):为调用端提供统一的调用接口,外观类知道哪些子系统负责处理请求,从而将调用端的请求代理给适当子系统对象。子系统的集合:指模块或者子系统,处理Facade对象指派的任务,是功能实际提供者。调用者(Client):外观接口的调用者。 四、外观模式解决影院管理问题 类图: 实现代码: package com.etc.design.facade; public class Client { public static void main(String[] args) { // 使用外观类实现过程 HomeTheaterFacade homeTheaterFacade = new HomeTheaterFacade(); // 开启所有设备 homeTheaterFacade.ready(); // DVD播放 homeTheaterFacade.play(); // DVD暂停 homeTheaterFacade.pause(); // 关闭所有设备 homeTheaterFacade.end(); } } package com.

Windows:解决MySQL登录ERROR 1045 (28000): Access denied for user ‘root‘@‘localhost‘ (using passwor=YES)问题

我在下载的MySQL是8.0.32版本,刚下的时候没什么问题第二天启动MySQL服务就出现了 ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) 或 ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO) 这样的问题,到现在还是不理解为什么会出现这样的问题但是问题已经解决了,希望我的文章可以帮助和我一样刚入门的小白。 一、MySQL密码错误的解决方法 打开以管理员身份打开终端,输入指令net stop mysql停止MySQL服务,停止服务之后不要删后面还有用 找到你MySQL的安装路径并删除该文件夹下的data文件夹(如果有就删掉,没有就不用管) 3.到终端里面输入mysqld --initialize然后等一下(这段时间就是在创建data文件夹),再次输入net start mysql启动MySQL服务,这时便会重新产生一个临时的登录密码 4.然后使用全局搜索找到.err文件(这里我用的是everything,用它来找零碎的文件是真的好用),或者直接去安装目录的data文件夹里面找(里面只有.err这一个文件),用记事本打开查找password,结尾就是登录密码 原文参考链接:https://blog.csdn.net/liu_xin_xin/article/details/96473805 二、MySQL修改密码 1.以管理员身份打开终端,输入net stop mysql停止MySQL服务 2.再次输入mysqld --console --skip-grant-tables --shared-memory跳过密码验证登录,前面的终端那不要关再打开一个新的管理员终端输入mysql -u root -p这时直接回车就行了 输入两段命令使密码置空 use mysql update user set authentication_string=''where user='root'; 4.输入quit退出MySQL,这个别关后面有用 5.这时就可以关掉以mysqld --console --skip-grant-tables --shared-memory启动的管理员终端了 6.在管理员终端输入net start mysql启动MySQL服务 7.这时输入mysql -u root -p回车就能进去了,因为密码已经置空所以不需要密码 8.这时输入ALTER USER 'root'@'localhost' IDENTIFIED BY '新密码';,这样新密码就设置好了

Docker部署RocketMQ集群

一、概述 Apache RocketMQ是阿里开源的一款高性能、高吞吐量、队列模型的消息中间件的分布式消息中间件。 关于RocketMQ集群架构的详细介绍,请参考链接:https://blog.csdn.net/Weixiaohuai/article/details/123607472 二、下载镜像 docker pull apache/rocketmq:4.9.4 docker pull apacherocketmq/rocketmq-dashboard 主要用到了2个镜像,第1个用来部署NameServer和Broker,第2个用来管理rocketmq 三、部署 本文主要采用一台服务器来部署RocketMQ集群,集群部署模式采用多master模式,也就是2个NameServer和2个Broker 刷盘机制采用异步复制,异步刷盘 服务器配置: 操作系统:centos 7.6 硬件配置:2核4g ip地址:192.168.137.138 创建目录 mkdir -p /opt/rocketmq/logs/nameserver-a mkdir -p /opt/rocketmq/logs/nameserver-b mkdir -p /opt/rocketmq/logs/broker-a mkdir -p /opt/rocketmq/logs/broker-b mkdir -p /opt/rocketmq/store/broker-a mkdir -p /opt/rocketmq/store/broker-b mkdir -p /opt/rocketmq/broker-a/ mkdir -p /opt/rocketmq/broker-b/ 设置权限 chmod 777 -R /opt/rocketmq/logs/* chmod 777 -R /opt/rocketmq/store/* 注意:这里如果不设置权限,会导致docker写入文件失败,导致rocketmq启动异常。 创建broker.conf 修改第一个节点配置 vim /opt/rocketmq/broker-a/broker-a.conf 内容如下: brokerClusterName = rocketmq-cluster brokerName = broker-a brokerId = 0 #这个很有讲究 如果是正式环境 这里一定要填写内网地址(安全) #如果是用于测试或者本地这里建议要填外网地址,因为你的本地代码是无法连接到阿里云内网,只能连接外网。 brokerIP1 = 192.

Linux查看硬件超强命令SAR

一、概述 sar(System Activity Reporter,系统活动情况报告)是Linux下系统运行状态统计工具,可从多方面对系统的活动进行报告,包括:文件的读写情况、系统调用的使用情况、磁盘I/O、CPU效率、内存使用状况、进程活动及IPC有关的活动等。算是一个万能的小能手。 二、安装 ubuntu下: root@ubuntu:/home/peng# apt-get install sysstat root@ubuntu:/home/peng# sar -r Cannot open /var/log/sysstat/sa07: No such file or directory Please check if data collecting is enabled 执行后会遇到以下错误,sa07中的07是当天的日期,原因是由于没有创建该文件。解决方法: root@ubuntu:/home/peng# chmod o+w /etc/default/sysstat root@ubuntu:/home/peng# vim /etc/default/sysstat 三、 命令 语法 类型 就是我们要获取的是哪个类型的指标数据,这里的-n,代表的是监控一些网络信息 -a:文件读写情况 -A:所有报告的总和 -B:分页状况 -b:显示I/O和传送速率的统计信息 -c:输出进程统计信息,每秒创建的进程数 -d:块设备状况 -F [ MOUNT ]:文件系统统计信息 -H:交换空间利用率 -I { <中断> | SUM | ALL | XALL }:中断信息状况 -n:汇报网络情况 -P:设定CPU -q:队列长度和平均负载 -R:输出内存页面的统计信息 -r [ ALL ]:输出内存和交换空间的统计信息

【CMD操作】如何使用CMD运行Python文件

首先需要保证已经安装Python解释器并配置好环境变量(安装及配置步骤可见Python安装教程) 一、打开管理员cmd 开始键右击选择Windows Powershell(管理员) 二、输入指令 输入“python ”+要运行的python文件路径 注意:当命令行中文件路径有空格时,需加上双引号方可运行!!

裸金属和虚拟机/裸金属镜像与普通镜像

目录 裸金属镜像和虚拟机的区别 裸金属镜像和普通镜像的区别 裸金属和虚拟机的区别 裸金属机器(Bare Metal)和虚拟机(Virtual Machine)都是计算机系统中的不同类型。 裸金属机器是指一台物理服务器,它没有操作系统或虚拟化层。它直接运行在硬件上,并且可以独立于其他计算机系统运行。裸金属机器通常用于需要高性能和可靠性的应用程序,例如数据库、游戏服务器、视频处理等。 虚拟机是一种通过虚拟化技术创建的虚拟计算机。它可以运行在物理服务器上,并模拟出一台完整的计算机系统。虚拟机可以在同一台物理服务器上运行多个虚拟机,每个虚拟机都可以运行自己的操作系统和应用程序。虚拟机通常用于需要灵活性和可扩展性的应用程序,例如网站托管、测试环境等。 下面是裸金属机器和虚拟机之间的一些主要区别: 硬件资源:裸金属机器提供完整的硬件资源,包括CPU、内存、磁盘等。虚拟机则共享物理服务器的硬件资源,每个虚拟机只能访问分配给它的一部分资源。 性能:由于裸金属机器直接运行在硬件上,因此通常具有更高的性能和更低的延迟。虚拟机则需要通过虚拟化技术来模拟硬件资源,因此可能会有性能损失和延迟。 部署:裸金属机器需要在操作系统和应用程序上进行手动配置和安装,而虚拟机则可以通过预先配置的映像进行快速部署。 弹性:虚拟机具有更好的弹性,可以快速添加或删除虚拟机来满足需要。裸金属机器则需要手动添加或删除物理服务器。 安全性:由于裸金属机器没有虚拟化层,因此可能更容易受到攻击。虚拟机则提供更好的隔离和安全性,每个虚拟机都运行在自己的安全容器中。ps:( 相比较而言,虚拟机可以提供更好的隔离和安全性,因为每个虚拟机都运行在自己的安全容器中,可以相互隔离。虚拟机可以限制各个虚拟机之间的资源访问,减少恶意软件和攻击的传播风险。同时,虚拟机通常提供更多的安全特性和功能,例如虚拟防火墙、安全软件和加密等。 然而,裸金属服务器在某些情况下可能被认为更加安全。由于裸金属服务器没有虚拟化层,因此它可以提供更高的性能和更低的延迟,并减少虚拟化层引入的潜在安全漏洞。此外,裸金属服务器可以让用户完全掌控硬件资源,避免虚拟机之间的资源竞争问题,并减少虚拟机中出现的一些安全问题。 综上所述,选择裸金属服务器还是虚拟机取决于具体的应用场景和安全需求。在考虑安全性方面,需要综合考虑安全特性、性能需求、资源控制和监控等因素,评估哪种选择更适合。 ).. 裸金属镜像和普通镜像的区别 普通镜像(比如Docker镜像)是为虚拟化平台而设计的,通常包含了完整的操作系统和应用程序环境,并通过虚拟化技术运行在虚拟机中。普通镜像需要依赖虚拟化平台提供的虚拟化层,无法直接运行在裸金属服务器上。 裸金属镜像则是为裸金属服务器而设计的,它们不包含虚拟化层,直接运行在裸金属服务器的物理硬件上。裸金属镜像通常不包含完整的操作系统,而是包含了裸金属服务器需要的最小化系统环境,如基础的操作系统内核和驱动程序等。 另外,裸金属镜像也可以包含一些预装的应用程序,但通常是为了方便用户快速启动和配置应用程序而设计的,而不是为了提供完整的应用程序环境。 由于裸金属镜像的设计目标和适用范围不同于普通镜像,因此它们的制作和使用也有所不同。制作裸金属镜像需要考虑裸金属服务器的硬件和系统环境,而使用裸金属镜像则需要自行安装和配置应用程序环境。 总的来说,裸金属镜像和普通镜像是针对不同的应用场景和平台而设计的,需要根据具体需求选择合适的镜像类型。

OpenFeign核心源码简读

目录 1、FeignClient注册逻辑 1.1、入口@EnableFeignClients 1.2、FeignClientsRegistrar 1.2.1、registerBeanDefinitions 1.2.2、registerFeignClients 1.2.3、registerFeignClient 1.3、FeignClientFactoryBean 1.3.1、getObject -> getTarget 1.3.2、loadBalance 1.4、feign.Feign#target 2、FeignClient接口调用逻辑 2.1、feign.ReflectiveFeign#newInstance 2.1.1、方法增强 2.1.2、FeignClient增强 2.2、feign.SynchronousMethodHandler 2.2.1、invoke 2.2.2、executeAndDecode 3、一些实用功能 3.1、Feign请求预处理(RequestInterceptor) 3.2、FeignClient请求优先走本地接口实现类(思路) 版本:spring-cloud-openfeign-core:3.1.2 1、FeignClient注册逻辑 1.1、入口@EnableFeignClients @EnableFeignClients -> @Import(FeignClientsRegistrar.class) 1.2、FeignClientsRegistrar org.springframework.cloud.openfeign.FeignClientsRegistrar 通过实现ImportBeanDefinitionRegistrar接口,重写registerBeanDefinitions方法,可以完成自定义Bean的注入。 1.2.1、registerBeanDefinitions registerDefaultConfiguration:注入FeignClient的全局配置,将@EnableFeignClients中的defaultConfiguration属性中配置的class类型注入到容器。registerFeignClients:将所有添加了@FeignClient注解的接口,创建Bean并注入到容器中。 1.2.2、registerFeignClients 扫描指定package下所有@FeignClient修饰的接口,注入FeignClient客户端(代理)对象,供应用程序远程调用时使用。 1.2.3、registerFeignClient 根据@FeignClient注解中的属性配置,定义FeignClient对应的BeanDefiniton对象,并注入到容器中。核心是一个FeignClientFactoryBean对象,该对象是一个FactoryBean对象,生成的实例是FactoryBean.getObject()方法返回的对象; 对于FeignClientFactoryBean来说,getObject()返回的就是Feign接口类的代理对象。 1.3、FeignClientFactoryBean org.springframework.cloud.openfeign.FeignClientFactoryBean 1.3.1、getObject -> getTarget 如果@FeignClient注解配置了url属性,返回一个默认代理类; 反之,则返回一个带有负载均衡功能的代理类(feign + ribbon)。 1.3.2、loadBalance targeter.target -> org.springframework.cloud.openfeign.DefaultTargeter#target -> feign#target targeter.target:创建代理对象 1.4、feign.Feign#target 包含build()和newInstance()两个方法。 build(): FeignClient的构造器,返回一个ReflectiveFeign对象。newInstance(): 创建FeignClient的动态代理对象 2、FeignClient接口调用逻辑 2.1、feign.ReflectiveFeign#newInstance 包含方法增强和FeignClient增强。 2.1.1、方法增强 Map<Method, MethodHandler> methodToHandler保存了方法对应的增强逻辑,MethodHandler具体类型为SynchronousMethodHandler; 2.1.2、FeignClient增强 使用动态代理的方式增强Feign请求逻辑,增强逻辑在ReflectiveFeign.FeignInvocationHandler的invoke方法中。当有Feign请求时,会进入该方法。

Centos7.9终端背景及字体颜色设置为类似Ubuntu样式

最近使用Centos系统觉得终端的字体看得太费劲了,反观Ubuntu的终端看起来就很舒服,所以特地去学习了一下如何修改Centos的终端样式,仅此记录。 关于样式设置参考了这篇文章 https://wuyaogexing.com/65/84451.html 下面给出我的样式最终效果图和设置方法: 最终效果 Centos7.9 对比Ubuntu22.04 设置方法 普通用户的样式设置: cd ~ vim .bashrc 新增一行: PS1="\[\e[37;37m\]\[\e[32;32m\]\u\[\e[32;32m\]@\h:\[\e[34;34m\]\w\[\e[0m\]\\$ " root用户的样式设置: su # 输入root密码 或者 sudo -i # 输入当前用户密码 切换到root用户 vim /etc/bashrc 新增一行: PS1="\[\e[31;31m\]\[\e[31;31m\]\u\[\e[31;31m\]@\h:\[\e[34;34m\]\w\[\e[0m\]\\$ " 使用命令source /etc/bashrc 使更改立即生效(source .bashrc)

Python开发环境的搭建(小白适用)

Anaconda与Python的选择 个人理解Anaconda是对Python的集成,Anaconda据说自带了3000多个第三方包也是比较强大的存在了,但是本文讲解的是如何安装普通版本的Python。 下载Python 进入Python官网,点击Download 选择一个喜欢的Python版本点击进入该版本的详情页并下滑,可以看到很多可供下载的选择。 在这个地方需要说明一下,一般咱们应该选择下载 executable installer 文件,因为这个文件下载下来是一个exe可执行文件,安装比较方便。(windows 下可执行文件一般是 exe,msi等) 接下来还有一个问题需要注意就是下载64位的Python还是32位的Python,对于这个问题个人建议. 64位操作系统的同学下载 64位Python32位操作系统的同学下载 32位Python 点击此电脑,选择属性,查看操作系统位数。 确定好一切,咱们就可以下载Python,因为之前刚学Python的时候在这个地方吃了不少亏,所以希望大家注意,否则以后可能在开发过程中出现很多第三方包安装失败的问题,通过这个问题也可以间接的说明一件事情: 既然Python分64位和32位,那么Python的第三方包是不是也分64位或者32位呢? 答案是:大部分情况是的。 注:Mac系统的同学只要注意操作系统位数,下载对应版本的python,按照教程安装即可。 安装Python 点击下载好的Python进行安装 一般在安装程序的时候,本人的作风都是一路Next,但是这样之后本人往往都是这个样子。 这里我们点击 Customize installation(自定义安装),并且记得勾选Add Python To Path。 选择点击Next。 这里需要勾选第一个 Install for all user,并修改安装目录,本人直接修改C变为D即可(我很懒的). 点击Next,继续安装。 等待安装完成。安装完成进入Windows终端试着输入一些测试命令测试Python是否安装成功。 如果出现意外情况,发生 “不是内部或外部命令,也不是可运行的程序”, 请及时检查环境变量是否存在 python安装的路径,以及Python安装的路径+Scripts,如果不存在,我们需要将这两个路径添加到环境变量中。 安装全宇宙最强Python编辑器 个人觉得敲代码如果有一个很好的代码编辑器将会是一个非常好的编程体验,这里咱们选择安装全宇宙最强Python代码编辑器 Pycharm (这个是链接)。点击进入Pycharm 下载页面,点击download 下载。 下载完成之后点击安装。一路next即可,但是这里需要注意尽可能别把程序安装在系统盘(也就是C盘),将安装路径修改即可。 安装完成之后点击启动。 点击OK 由于Pycharm是收费的,所以这里我们只好选择尝试百度去解决这个问题。 点击下载注册码,将获取的注册码填入到Activation code,点击Ok即可。至此Pycharm 安装完成。 将 Python 环境导入Pycharm中 使用Pycharm打开我们的代码,但是发现Pycharm 并不能运行代码,这是为什么呢,原因其实是因为我们并没有将 Python 环境导入Pycharm中。 我们点击左上角的 File,点击Settings,点击Project:项目名,点击Project Interpreter。 点击小齿轮,点击Add,点击 System Interpreter 导入自己的Python安装文件夹下的Python.exe 文件即可。然后一路OK即可。最终效果图如下:

【计算机网络】传输层TCP协议

文章目录 认识TCP协议TCP协议的格式字段的含义序号与确认号六个标志位窗口大小 确认应答(ACK)机制超时重传机制连接管理机制三次握手四次挥手 滑动窗口流量控制拥塞控制延迟应答捎带应答面向字节流粘包问题TCP异常情况总结 认识TCP协议 TCP(Transmission Control Protocol,传输控制协议)是一种面向连接、可靠的、基于字节流的传输层协议。TCP协议是互联网协议栈中最重要的协议之一,它提供了可靠的数据传输服务,保证了数据的完整性、可靠性和有序性。 TCP协议通过建立连接、传输数据和断开连接三个步骤来完成数据传输。在建立连接时,双方需要通过三次握手协议来确认彼此的身份和可用性。在传输数据时,TCP协议会把数据分割成TCP数据包,并对每个数据包进行编号和校验,确保数据的完整性和有序性。在断开连接时,双方需要通过四次挥手协议来协商关闭连接。 TCP协议还提供了流量控制和拥塞控制功能,以便在网络拥塞或带宽限制的情况下保证数据传输的顺畅。此外,TCP协议还支持多路复用,可以在同一个连接上传输多个应用程序的数据。 总之,TCP协议是一种可靠、安全、高效的传输层协议,广泛应用于互联网中。 TCP协议的格式 字段的含义 源端口和目的端口:源端口是发送端口,目的端口是接收端口。它们分别占用16个比特,总共32个比特。序号与确认序号:序列号表示TCP报文段中第一个字节的序列号,确认号表示期望接收到的下一个字节的序列号。它们各占用32个比特,总共64个比特。数据偏移:其中填充了TCP报头的长度,以4字节为单位,一般为20字节,最长为60字节(20字节的固定首部加上加上选项的大小)。保留字段:TCP报头中暂未被使用的6个比特位。控制位:包括URG、ACK、PSH、RST、SYN和FIN六个标志位,用于指示TCP报文段的不同控制信息。窗口大小:保证TCP通信的可靠性和效率的字段。校验和:包括TCP报头和TCP数据两部分,校验和用于检测TCP报文段中是否有错误,占用16个比特。紧急指针:用于指示紧急数据的位置,占用16个比特,需要配合标志位中的URG标识使用。选项和填充:选项用于扩展TCP报文段,占用可变长度,填充用于对齐TCP报文段的长度,占用可变长度。最大40字节。 序号与确认号 32位序号: 如果双方在进行数据通信时,只有收到了上一次发送数据的响应才能发下一个数据,那么此时双方的通信过程就是串行的,效率可想而知。 因此双方在进行网络通信时,允许一方向另一方连续发送多个报文数据,只要保证发送的每个报文都有对应的响应消息就行了,此时也就能保证这些报文被对方收到了。 但在连续发送多个报文时,由于各个报文在进行网络传输时选择的路径可能是不一样的,因此这些报文到达对端主机的先后顺序也就可能和发送报文的顺序是不同的。但报文有序也是可靠性的一种,因此TCP报头中的32位序号的作用之一实际就是用来保证报文的有序性的。 TCP将发送出去的每个字节数据都进行了编号,这个编号叫做序列号。 比如现在发送端要发送3000字节的数据,如果发送端每次发送1000字节,那么就需要用三个TCP报文来发送这3000字节的数据。此时这三个TCP报文当中的32位序号填的就是发送数据中首个字节的序列号,因此分别填的是1、1001和2001。 当接收方收到这三个报文之后,就会根据其中的序列号进行排序,排序完成后再放入TCP缓冲区中,这样就能保证发送出去的和接收到的数据顺序保持一致。 32位确认号: TCP报头当中的32位确认序号是告诉对方,当前已经收到了哪些数据,并且数据下一次应该从哪里开始发送 以上文的例子为例,当主机B收到主机A发送过来的32位序号为1的报文时,由于该报文当中包含1000字节的数据,因此主机B已经收到序列号为1-1000的字节数据,于是主机B发给主机A的响应数据的报头当中的32位确认序号的值就会填成1001。 一方面是告诉主机A,序列号在1001之前的字节数据我已经收到了。另一方面是告诉主机A,下次向我发送数据时应该从序列号为1001的字节数据开始进行发送。 如果报文在传输过程中丢失了,例如最终只要序号为1和2001的报文被主机B收到,那么当B对报文进行排序的时候,就会发现少了1001 ~ 2000 之间的数据,那么此时向主机A响应的报文中的32位确认序号的值就是1001,告诉主机A下次再次发送1001开始的数据。 【注意】 如果此时主机B在给主机A响应时,其32位确认序号不能填3001,因为1001-2000是在3001之前的,如果直接给主机A响应3001,就说明序列号在3001之前的字节数据全都收到了。因此主机B只能给主机A响应1001,当主机A收到该确认序号后就会判定序号为1001的报文丢包了,此时主机A就可以选择进行数据重传。 TCP报头中有了序号和确认号的机制,一定程度上保证了数据传输的完整性,同时也保证了TCP传输的可靠性。 六个标志位 TCP报文的种类多种多样,除了正常通信时发送的普通报文,还有建立连接时发送的请求建立连接的报文,以及断开连接时发送的断开连接的报文等等。收到不同种类的报文时需要对应执行动作,因此需要用标志位进行区分不同的报文类型。这六个标志位都只占用一个比特位,为0表示假,为1表示真。 URG: 双方在进行网络通信的时候,由于TCP是保证数据按序到达的,即便发送端将要发送的数据分成了若干个TCP报文进行发送,最终到达接收端时这些数据也都是有序的,因为TCP可以通过序号来对这些TCP报文进行顺序重排,最终就能保证数据到达对端接收缓冲区中时是有序的。 虽然TCP的有序到达是我们想要的目的,并且接收方的对端上层也是从接收缓冲区中按顺序读取的,但是有时候发送方也会发送紧急数据,那么就要让接收方的对端上层也要紧急读取该数据,因此就需要使用的URG标志位。 当URG标志位设置位1时,需要使用TCP报头中的16位紧急指针找到紧急数据,因此一般情况下不会使用到报头中的紧急指针。16位紧急指针表示了紧急数据在报文中的偏移量。 ACK: 报文中的ACK标志设置为1,表示该报文可以对接收到的报文进行确认。一般除了第一个请求连接的报文没有设置ACK外,其余报文基本上都设置了ACK,因为携带了ACK的报文需要对接收到的报文进行确认。 PSH: 当PSH标志位设置为1时,会提示接收端应用程序立刻从TCP缓冲区读取数据,并交付给上层应用。 一般我们会认为当使用read从缓冲区读取数据时,如果缓冲区中有数据,那么这些数据就会被返回,如果没有数据就会阻塞式的等待write向缓冲区中写入数据再进行读取。 其实这种说法并不准确,因为在缓冲区中都有应该水位线的概念,例如下图: 当缓冲区存储的数据没有达到水位线的时候,read就会进行阻塞等待,只要超过水位线后才会进行读取。因为如果缓冲区中有一点数据就进行读取的话会导致频繁的调用read,势必会造成效率的低下。 当报文当中的PSH被设置为1时,实际就是在告知对方操作系统,尽快将接收缓冲区当中的数据交付给上层,尽管接收缓冲区当中的数据还没到达所指定的水位线。 RST: 报文当中的RST被设置为1,表示需要让对方重新建立连接。在通信双方在连接未建立好的情况下,一方向另一方发数据,此时另一方发送的响应报文当中的RST标志位就会被置1,表示要求对方重新建立连接。在双方建立好连接进行正常通信时,如果通信中途发现之前建立好的连接出现了异常也会要求重新建立连接。 SYN: 报文当中的SYN被设置为1,表明该报文是一个连接建立的请求报文。只有在连接建立阶段,SYN才被设置,正常通信时SYN不会被设置。 FIN: 报文当中的FIN被设置为1,表明该报文是一个连接断开的请求报文。只有在断开连接阶段,FIN才被设置,正常通信时FIN不会被设置。 窗口大小 当发送端要将数据发送给对端时,本质是把自己发送缓冲区当中的数据发送到对端的接收缓冲区当中。但缓冲区是有大小的,如果接收端处理数据的速度小于发送端发送数据的速度,那么总有一个时刻接收端的接收缓冲区会被填满,这时发送端再发送数据过来就会造成数据丢包,进而引起丢包重传等一系列的连锁反应。 因此TCP报头中就引入的16位窗口大小来加以控制。这个16位窗口中填充的就是自身缓冲区剩余空间的大小,发送给对方后就能让对方知道自己缓冲区的存储能力,从而控制传输的速率。 窗口大小字段越大,说明接收端接收数据的能力越强,此时发送端可以提高发送数据的速度。窗口大小字段越小,说明接收端接收数据的能力越弱,此时发送端可以减小发送数据的速度。如果窗口大小的值为0,说明接收端接收缓冲区已经使用完了,此时发送端就不应该再发送数据了。 确认应答(ACK)机制 确认应答机制是保证TCP通信可靠性的机制之一,它是由32位序号和32位确认序号来保证的。 TCP是面向字节流的,它会为每个字节的数据都进行了编号,即序列号: 每一个ACK都带有对应的确认序列号,意思是告诉发送者,当前接收方已经收到了哪些数据,下一次发送方应该发送哪些数据。 超时重传机制 主机A发送数据给主机B之后,可能因为网络拥堵等原因,导致数据无法到达主机B。如果主机A在一个特定时间间隔内没有收到主机B发来的确认应答,就会进行数据重传,这就是超时重传机制。 如果主机A也没有收到来自主机B的确认应答,也可能是因为ACK丢失了。 当ACK发生丢包时,由于存在超时重传机制,主机B就会收到重复的数据,此时主机B就会意识到自己发送的确认应答有可能发生了丢包,导致主机A没有收到,因此就会重新发送确认应答,并且主机B会根据其前面接收到的数据的序号,丢弃掉重复的数据。 那么超时重传的时间该如何设定呢? 最理想的情况下,找到一个最小的时间,保证确认应答一定能在这个时间内返回。但是这个时间的长短,随着网络环境的不同,而存在差异。如果超时时间设的太长,会影响整体的重传效率;如果超时时间设的太短,有可能会频繁发送重复的包。 TCP为了保证无论在任何环境下都能比较高性能的通信,因此会动态计算这个最大超时时间: Linux中(Windows也是如此),超时以500ms为一个单位进行控制,每次判定超时重发的超时时间都是500ms的整数倍。如果重发一次之后,仍然得不到应答,等待 2*500ms 后再进行重传。如果仍然得不到应答,等待 4*500ms 进行重传,依次类推,以指数形式递增。当累计到一定的重传次数,TCP就会认为网络或者对端主机出现异常,最后强制关闭连接。 连接管理机制 在正常情况下,TCP要经过三次握手建立连接,四次挥手断开连接,以下是TCP连接到断开的全部过程:

Linux之安装node

Linux之安装node步骤如下 1.去网站下载node 下载地址: https://npm.taobao.org/mirrors/ 2.上传到指定目录下 3.解压 tar -zxvf node-v17.3.0-linux-x64 4.配置node环境变量 //执行以下命令 vim /etc/profile //在path中加入以下内容 /usr/local/node-v15.14.0/bin //刷新配置 source /etc/profile 5.验证node是否安装成功

常用聚类算法分析

1. 什么是聚类 1.1. 聚类的定义 聚类(Clustering)是按照某个特定标准(如距离)把一个数据集分割成不同的类或簇,使得同一个簇内的数据对象的相似性尽可能大,同时不在同一个簇中的数据对象的差异性也尽可能地大。也即聚类后同一类的数据尽可能聚集到一起,不同类数据尽量分离。 1.2. 聚类和分类的区别 聚类(Clustering):是指把相似的数据划分到一起,具体划分的时候并不关心这一类的标签,目标就是把相似的数据聚合到一起,聚类是一种无监督学习(Unsupervised Learning)方法。分类(Classification):是把不同的数据划分开,其过程是通过训练数据集获得一个分类器,再通过分类器去预测未知数据,分类是一种监督学习(Supervised Learning)方法。 1.3. 聚类的一般过程 数据准备:特征标准化和降维特征选择:从最初的特征中选择最有效的特征,并将其存储在向量中特征提取:通过对选择的特征进行转换形成新的突出特征聚类:基于某种距离函数进行相似度度量,获取簇聚类结果评估:分析聚类结果,如距离误差和(SSE)等 1.4. 数据对象间的相似度度量 对于数值型数据,可以使用下表中的相似度度量方法。 Minkowski距离就是范数(),而 Manhattan 距离、Euclidean距离、Chebyshev距离分别对应时的情形。 1.5. cluster之间的相似度度量 除了需要衡量对象之间的距离之外,有些聚类算法(如层次聚类)还需要衡量cluster之间的距离 ,假设和为两个 cluster,则前四种方法定义的和之间的距离如下表所示。 Single-link定义两个cluster之间的距离为两个cluster之间距离最近的两个点之间的距离,这种方法会在聚类的过程中产生链式效应,即有可能会出现非常大的clusterComplete-link定义的是两个cluster之间的距离为两个``cluster之间距离最远的两个点之间的距离,这种方法可以避免链式效应`,对异常样本点(不符合数据集的整体分布的噪声点)却非常敏感,容易产生不合理的聚类UPGMA正好是Single-link和Complete-link方法的折中,他定义两个cluster之间的距离为两个cluster之间所有点距离的平均值最后一种WPGMA方法计算的是两个 cluster 之间两个对象之间的距离的加权平均值,加权的目的是为了使两个 cluster 对距离的计算的影响在同一层次上,而不受 cluster 大小的影响,具体公式和采用的权重方案有关。 2. 数据聚类方法 数据聚类方法主要可以分为划分式聚类方法(Partition-based Methods)、基于密度的聚类方法(Density-based methods)、层次化聚类方法(Hierarchical Methods)等。 2.1. 划分式聚类方法 划分式聚类方法需要事先指定簇类的数目或者聚类中心,通过反复迭代,直至最后达到"簇内的点足够近,簇间的点足够远"的目标。经典的划分式聚类方法有k-means及其变体k-means++、bi-kmeans、kernel k-means等。 2.1.1. k-means算法 经典的k-means算法的流程如下: 经典k-means源代码,下左图是原始数据集,通过观察发现大致可以分为4类,所以取k = 4,测试数据效果如下右图所示。 该函数的曲线如下图所示 可以发现该函数有两个局部最优点,当时初始质心点取值不同的时候,最终的聚类效果也不一样,接下来我们看一个具体的实例。 在这个例子当中,下方的数据应该归为一类,而上方的数据应该归为两类,这是由于初始质心点选取的不合理造成的误分。而k值的选取对结果的影响也非常大,同样取上图中数据集,取k = 2, 3,可以得到下面的聚类结果: 优点 原理简单,算法复杂度较低 缺点 k值未知,需要人为设定 对于初始化中心点特别敏感,不同的初始化,结果可能不一样 容易受到噪声的影响,可能收敛于局部最小值,同时数据量大时收敛速度较慢 不太适合离散的数据,样本类别不均衡的数据的聚类 k-means 有一个重要特征,它要求这些簇的模型必须是圆形:k-means 算法没有内置的方法 来实现椭圆形的簇 算法复杂度 O(t*k*n*d) ,其中t是迭代次数,k是类数,n是数据点个数,d是数据维度 2.1.2. k-means++算法 k-means++是针对k-means中初始质心点选取的优化算法。该算法的流程和k-means类似,改变的地方只有初始质心的选取,该部分的算法流程如下

localStorage-本地存储

以前了解过好久没用过了在了解一遍 localStorage 属性允许在浏览器中存储 key/value 对的数据。 localStorage 用于长久保存整个网站的数据,保存的数据没有过期时间,直到手动去删除 用法 window.localStorage //保存数据语法: localStorage.setItem("key", "value"); //读取数据语法: var lastname = localStorage.getItem("key"); //删除数据语法: localStorage.removeItem("key"); //清空 localStorage.clear(); localStorage 的优势 1、localStorage 拓展了 cookie 的 4K 限制。 2、localStorage 会可以将第一次请求的数据直接存储到本地,这个相当于一个 5M 大小的针对于前端页面的数据库,相比于 cookie 可以节约带宽,但是这个却是只有在高版本的浏览器中才支持的。 localStorage 的局限 1、浏览器的大小不统一,并且在 IE8 以上的 IE 版本才支持 localStorage 这个属性。 2、目前所有的浏览器中都会把localStorage的值类型限定为string类型,这个在对我们日常比较常见的JSON对象类型需要一些转换。 3、localStorage在浏览器的隐私模式下面是不可读取的。 4、localStorage本质上是对字符串的读取,如果存储内容多的话会消耗内存空间,会导致页面变卡。 5、localStorage不能被爬虫抓取到。 localStorage 与 sessionStorage 的唯一一点区别就是 localStorage 属于永久性存储,而 sessionStorage 属于当会话结束的时候,sessionStorage 中的键值对会被清空。 localStorage 使用 首先在使用 localStorage 的时候,我们需要判断浏览器是否支持 localStorage 这个属性: if(! window.localStorage){ alert("浏览器不支持localstorage"); return false; }else{ //主逻辑业务 }

Module not found: Error: Can‘t resolve ‘js-cookie‘ 问题处理

问题描述 在启动前端时,出现Module not found: Error: Can't resolve 'js-cookie' 问题 原因分析: 是因为没有安装'js-cookie'module 可以在package.json文件中查看有没有js-cookie 解决方案: 安装js-cookie即可 如何安装: 使用如下命令: npm install -save js-cookie 局部引用 import Cookies from "js-cookie";

Redis

这里写目录标题 1.Redis入门1.1 Redis简介1.2 Windows系统中启动和停止Redis 2.Redis数据类型2.1 字符串string操作命令2.2 哈希hash操作命令2.3 列表list操作命令2.4 集合set操作命令2.5 有序集合sorted set操作命令2.6 通用命令 3.在Java中操作Redis3.1 介绍3.2 Jedis3.3 Spring Data Redis3.3.1 入门案例3.3.2 存取练习 1.Redis入门 1.1 Redis简介 Redis是用C语言开发的一个开源的高性能键值对(key-value)数据库,官方提供的数据是可以达到100000+的QPS(每秒内查询次数)。它存储的value类型比较丰富,也被称为结构化的NoSql数据库。 官网 1.2 Windows系统中启动和停止Redis Windows系统中启动Redis,直接双击redis-server.exe即可启动Redis服务,redis服务默认端口号为6379 停止Redis服务:Ctrl + C 双击redis-cli.exe即可启动Redis客户端,默认连接的是本地的Redis服务,而且不需要认证即可连接成功。 退出客户端可以输入exit或者quit命令。 2.Redis数据类型 字符串 string哈希 hash列表 list集合 set有序集合 sorted set / zset 2.1 字符串string操作命令 一、SET key value 设置指定key的值 二、GET key 获取指定key的值 三、SETEX key seconds value 设置指定key的值,并将 key 的过期时间设为 seconds 秒 四、SETNX key value 只有在 key不存在时设置 key 的值 2.2 哈希hash操作命令 一、HSET key field value

Verilog快速入门(8)—— 4bit超前进位加法器电路

Verilog快速入门 (1) 四选一多路器 (2)异步复位的串联T触发器 (3)奇偶校验 (4)移位运算与乘法 (5)位拆分与运算 (6)使用子模块实现三输入数的大小比较 (7)4位数值比较器电路 (8)4bit超前进位加法器电路 (9)优先编码器电路① (10)用优先编码器①实现键盘编码电路 (11)8线-3线优先编码器 (12)使用8线-3线优先编码器实现16线-4线优先编码器 (13)用3-8译码器实现全减器 (14)使用3-8译码器①实现逻辑函数 (15)数据选择器实现逻辑函数 (16)状态机 (17)ROM的简单实现 (18)边沿检测 4bit超前进位加法器电路 Verilog快速入门一、题目描述二、解析与代码1. 半加器2. 全加器3. 行波进位加法器4. 超前进位加法器 一、题目描述 输入描述: 输入信号: A_in[3:0], B_in[3:0] C_1 类型:wire 输出描述: 输出信号: S[3:0] CO 类型:wire 二、解析与代码 以下内容摘自Leonico题主解析 1. 半加器 它不考虑进位输入。其中A和B是两个加数,S是和, C o C_o Co​是进位输出。 assign S = A ^ B; assign C_out = A & B; 2. 全加器 全加器是多bit加法器的基础。 C i C_i Ci​是进位输入, C o C_o Co​是向上进位输出。

uniapp开发微信小程序 ,使用本地图片做背景图应该怎么处理

<view class="answering_page" v-if="bgImg" :style="{'backgroundImage':backBg}"> </view> data(){ return{ bgImg: '/static/image/background.png', }}, computed:{ backBg(){ //这里在引用全局定义的图片转base64方法,处理成base64主要是在开发者工具中调试便于图片能够正常显示 return 'url('+getApp().globalData.urlToBase64(this.bgImg)+')' }, } //图片转换base64 urlToBase64(url){ let imgBase64 = wx.getFileSystemManager().readFileSync(url, "base64"), base64Url = `data:image/png;base64,${imgBase64}`; return base64Url; } 注意,把获取可用的base64地址的方法放在computed 里面是非常必要的。如果放在methods里面初次进入这个页面时候会报错(除了首页之外)。这里就是跟methods和computed特性有关。

坦克大战(java)

import javax.swing.*; import java.awt.*; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.util.ArrayList; import java.util.Random; public class GamePanel extends JFrame { Image offScreemImage=null; //窗口长宽 int wide=800; int height=610; Image select= Toolkit.getDefaultToolkit().getImage("src/image/爱心.png"); int y=150; int state=0; int a=1; int count=0; int enemyCount=0; ArrayList<Bullet>bulletList=new ArrayList<Bullet>(); ArrayList<Bot>botList=new ArrayList<Bot>(); ArrayList<Bullet>removeList=new ArrayList<Bullet>(); ArrayList<Tank>playerList=new ArrayList<Tank>(); ArrayList<Wall>wallList=new ArrayList<Wall>(); ArrayList<Base>baseList=new ArrayList<Base>(); ArrayList<Blast>blastList=new ArrayList<Blast>(); PlayerOne playerOne=new PlayerOne("src/image/hero1U.gif",125,500,this, "src/image/hero1U.gif","src/image/hero1L.gif","src/image/hero1R.gif","src/image/hero1D.gif"); Base base=new Base("src/image/基地.png",375,520,this); // Bot bot=new Bot("src/image/hero1U(1).png",600,50,this, // "src/image/hero1U(1).png","src/image/hero1L(1).png","src/image/hero1R(1).png","src/image/hero1D(1).png"); //窗口的启动方法 public void launch(){ //标题 setTitle("

WebRTC系列- turn及stun网络分析法

文章目录 1. TCPDUMP分析法1.1 简述1.2 使用 2. WireShark 基本使用简述实战 之前的文章有分析各种协议包的组成,那么实际上在使用的时候是不是和分析的一样,这就需要获取到请求的包进行分析;在分析网络协议最好能抓取到数据包,然后看分析数据包是不是和规定的协议一致; 一般的网络数据包分析我们有两个常用的工具: Linux端的一般经常使用tcpdump其他客户端一般使用WireShark 当然可以将tcpdump抓取的数据拿到wireShark中分析。 1. TCPDUMP分析法 1.1 简述 TCPdump是Linux端强大的网络抓包分析工具,但是要求使用者对网络协议等要有较高的熟悉度,如果不熟悉,看到的都是满屏的二进制数据,TCPdump在Linux上配合grep的搜索就会有很强大方便的分析能力;需要注意的是,由于需要抓取网卡的数据这里需要sudo root权限; 1.2 使用 使用实例如下: sudo tcpdump -i en7 src www.xxx.top -xx -Xs 0 上述命令中的各个参数解析如下: -i : 用来指定要捕获的接口,通常是以太网卡或无线网卡,后面跟网卡名称(比如:这里监听en7网卡的数据包),也可以是 vlan 或其他特殊接口,当然在当前系统上只有一个网络接口,则无需指定。src 指明包的来源,一般可以使用src 或 dst 只抓取源或目的地,后面跟的可以是IP地址也可以使用域名;port 指定要监听的端口,可以是源端口或目的端口,可以是tcp或udp端口;-xx 指被抓取到的包以16进制现实;-Xs 实际上是两个参数 X表示ASCII码的形式显示二进制数据;s 0表示需要抓取整个包,o表示抓取的数量无限制;-w 是指要写入到文件中,后面跟文件名; 上述命令执行后如下: mac下抓取网卡后写入文件的方式如下: sudo tcpdump -i en7 dst www.test.top -xx -Xs 0 -w /Users/用户名/desktop/test.cap 抓取一段时间后,结束抓取(control + c)就会在桌面生成一个cap文件,这个文件可以使用wireshake打开,打开效果如下: 详细的使用介绍超详细的网络抓包神器 tcpdump 使用指南 2. WireShark 基本使用 简述 由于一个网卡的数据可能包含多个协议及很多的源地址和目的地址等, WireShark 提供了基本逻辑运算用于处理数据,常用的如下:

vue3.0把html生成图片以及把图片下载到本地

1. 安装插件 html2canvas插件 npm install html2canvas cnpm i html2canvas --save 2.如何使用 在组件中引入 import html2canvas from "html2canvas"; 3.综合使用 <template> <div> <div ref="poster" class="posterImg"> <h3>公告</h3> <p> 如果同学们的这个项目写的比较快,也能接收额外实战知识,增加难度 </p> <img src="@/assets/icon_login.png" /> </div> <img :src="posterimg"/> <button type="button" class="" @click="goDown">下载</button> <!-- volar --> </div> </template> <script setup lang="ts"> import { ref} from "vue"; import html2canvas from "html2canvas"; const posterimg = ref(); // 绑定 需要把那个内容生成图片 const poster =ref(); const goDown = ()=> { // document.

web自动化测试之selenium-webdriver环境搭建

1、安装python及pycharm 安装python步骤: 1)登录Python官网:https://www.python.org/ 2)下载与自己电脑匹配的版本,安装即可(建议3.5以上) 注意:安装时选择安装界面的“Add Python 3.x to PATH”进行勾选,避免再次配置环境变量; 3)安装完成后可以通过Windows命令CMD输入“python”,查看是否安装成功,如下图所示: 安装pycharm步骤: 1)下载pycharm的安装包,下载地址:http://www.jetbrains.com/pycharm/download/ 专业版和社区版,两者差别不大,如果只是学习的话,社区版就足够了,我就安装的社区版,直接点击download下载即可。 2)下载完成后,点击安装,按照提示一直点击NEXT,直到安装成功即可 安装完成后需要检查一下pip是否存在 最新版的python安装包中已经集成了pip,可以在安装目录下的script路径下查看是否有pip.exe或pip3.exe文件,如果有,则cmd命令行中输入pip进行验证;出现如下图所示则证明pip已安装成功 不存在则下载安装: setuptools下载地址:https://pypi.python.org/pypi/setuptools pip下载地址:https://pypi.python.org/pypi/pip 2、安装及配置selenium 完成上面步骤后,可以通过cmd命令直接安装selenium包,命令:pip install selenium 注意:安装时如果只输入包名,则默认安装当前库中的最新版本,如果想安装自己需要的版本,则需要在包名后面加上版本号,比如: pip install selenium==2.48.0 查看selenium安装路径命令: pip show selenium 3、下载浏览器驱动包(以chrome为例子) 【方法一】百度搜索chromedriver—选择对应的浏览器版本 下载好ChromeDriver后把chromedriver.exe文件放到python安装的根目录下 【方法二】一键搭建 安装webdriver-helper (pip install webdriver_helper==1.0.1) webdriver-helper 自动获取浏览器的版本、操作系统类型 自动下载浏览器驱动 自动窗口创建和返回WeBDriver对象 控制浏览器 from webdriver_helper import get_webdriver with get_webdriver() as driver: driver.get("http://shell.sdcc.cxist.net:30000") driver.maximize_window() 4、打开pycharm导入selenium包 : file–setting–project–project interpreter–点击+ --搜索selenium–点击install package 到此,selenium配置完成

LDPC码的编译码原理简述

关于fpga调用ldpc IP core的相关参数问题可以看我的另一篇文章 LDPC码由Gallager在1962年提出,全称为 Low Density Parity-check Codes 低密度奇偶校验码 它的译码性能可以逼近Shannon信道容量限,广富盛名的Turbo码也被证明是LDPC码的一个特例。并且LDPC码具有在中长码长时超过 Turbo 码的性能,并且具有译码复杂度更低,能够并行译码及译码错误可检测等特点。 LDPC码内容较为复杂,本人由于未学过图论等重要相关知识,难以透彻理解其本质,因此本文主要是介绍以及引用、链接他人的描述。 LDPC编码 ldpc码是一种线性分组码,因此它有生成矩阵和校验矩阵。 我们假设有一个长度为k的信息序列 s 1 ∗ k s_{1*k} s1∗k​,可以通过生成矩阵 G k ∗ n G_{k*n} Gk∗n​得到编码后码长为n的码字 x 1 ∗ n = s 1 ∗ k ⋅ G k ∗ n x_{1*n} = s_{1*k} · G_{k*n} x1∗n​=s1∗k​⋅Gk∗n​ 同时还有一个唯一对应的校验矩阵 H ( n − k ) ∗ n H_{(n-k)*n} H(n−k)∗n​,所有码字满足 x 1 ∗ n ⋅ H ( n − k ) ∗ n T = 0 1 ∗ ( n − k ) x_{1*n} · H_{(n-k)*n}^T=0_{1*(n-k)} x1∗n​⋅H(n−k)∗nT​=01∗(n−k)​

java.util.concurrent.CompletionException: org.picocontainer.PicoRegistration idea启动报错,无法打开软件

路径位置:C:\Users\yang\AppData\Roaming\JetBrains\IntelliJIdea2020.1\plugins 报错信息: java.util.concurrent.CompletionException: org.picocontainer.PicoRegistrationException: Key com.tang.intellij.lua.luacheck.LuaCheckSettings duplicated 错误相关信息: 原因lua插件重复导致的错误。如果是其他插件,直接将相关的文件夹删除就行 修改方式:找到目标文件夹将luanalysis删除,只留下Emmylua插件即可,直接删除喔 查找插件路径: 路径位置:C:\Users\yang\AppData\Roaming\JetBrains\IntelliJIdea2020.1\plugins(示例) 修改完成即可正常使用了 详细报错信息: java.util.concurrent.CompletionException: org.picocontainer.PicoRegistrationException: Key com.tang.intellij.lua.luacheck.LuaCheckSettings duplicated at java.base/java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:3 14) at java.base/java.util.concurrent.CompletableFuture.uniApplyNow(CompletableFuture.java:683) at java.base/java.util.concurrent.CompletableFuture.uniApplyStage(CompletableFuture.java:658) at java.base/java.util.concurrent.CompletableFuture.thenApply(CompletableFuture.java:2094) at com.intellij.idea.ApplicationLoader.registerAppComponents(ApplicationLoader.kt:104) at com.intellij.idea.ApplicationLoader.executeInitAppInEdt(ApplicationLoader.kt:63) at com.intellij.idea.ApplicationLoader.access$executeInitAppInEdt(ApplicationLoader.kt:1) at com.intellij.idea.ApplicationLoader$initApplication$1$1.run(ApplicationLoader.kt:363) at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:313) at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:776) at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:727) at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721) at java.base/java.security.AccessController.doPrivileged(Native Method) at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85) at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:746) at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203) at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124) at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113) at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109) at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90) Caused by: org.picocontainer.PicoRegistrationException: Key com.tang.intellij.lua.luacheck.LuaCheckSettings duplicated at com.

android SystemUI 自定义广播接受器

自定义广播需动态注册 系统广播可静态注册 BroadcastDispatcher 来源 import com.android.systemui.broadcast.BroadcastDispatcher; private class DismissReceiver extends BroadcastReceiver { private final IntentFilter INTENT_FILTER = new IntentFilter(); { INTENT_FILTER.addAction("com.android.sustemui.SHOW_STATUS"); } private boolean mRegistered; private final BroadcastDispatcher mBroadcastDispatcher; DismissReceiver() { mBroadcastDispatcher = Dependency.get(BroadcastDispatcher.class); } void register() { mBroadcastDispatcher.registerReceiver(this, INTENT_FILTER, null, UserHandle.CURRENT); mRegistered = true; } void unregister() { if (mRegistered) { mBroadcastDispatcher.unregisterReceiver(this); mRegistered = false; } } @Override public void onReceive(Context context, Intent intent) { } } Intent intent = new Intent(); intent.

光线反射设置&反射探针

目录 1. 反射探针概念 2. 反射探针的工作原理 3. 反射探针组件 属性 4. 3D 场景中的默认光照探针 AmbientProbe —— 环境(光)探针 禁用 SkyManager 5. 反射探针使用步骤 添加反射探针: 添加具有镜面效果表面的反射对象: 反射探针添加位置 6. 改正室内光照场景中的金属苹果反射 在前面的室内场景中,有一个漂浮的金属质地苹果,它反射了画廊中位于其上方的两个彩色聚光灯,但它也反射了室内空间之外的天空盒。看起来非常违和,是因为它上面的反射根本就是错误的! 在本节中,将介绍反射探针的概念及用法,到最后,大家会学会如何设置反射探针,并将上面的苹果反射修正。 1. 反射探针概念 现实中,具有镜面特征的物体表面,可以映出周围的景象,比如,镜子、窗户玻璃、车窗、高光墨镜、金属物体、平静的水面等。 CG 电影和动画通常具有高度逼真的反射,这对于在场景中的对象之间提供“连接”感非常重要。 然而,这些反射的准确性伴随着处理器时间的高成本,虽然这对电影来说不是问题,但它严重限制了反射物体在实时游戏中的使用。 显然,直接建立对象间连接,生成生成静态或动态投影的方式,在游戏中代价太高,特别是动态的。虽然在一些高级硬件中,配合特定算法,已经能够实现反射动态投影,但不适合大多数游戏和硬件。 以前传统的处理方式:游戏使用一种称为_反射贴图_的技术来模拟来自对象的反射,同时将处理开销保持在可接受的水平。此技术假定场景中的所有反射对象都可以“看到”(因此会反射)完全相同的周围环境。 Unity 通过使用__反射探针__改进了基本反射贴图,这种探针可在场景中的关键点对视觉环境进行采样。通常情况下,应将这些探针放置在反射对象外观发生明显变化的每个点上(例如,隧道、建筑物附近区域和地面颜色变化的地方)。当反射对象靠近探针时,探针采样的反射可用于对象的反射贴图。此外,当几个探针位于彼此附近时,Unity 可在它们之间进行插值,从而实现反射的逐渐变化。因此,使用反射探针可以产生非常逼真的反射,同时将处理开销控制在可接受的水平。 反射探针在场景中也有一个不可见的框,用作效果区域。可以配置此框的大小。 在反射探测器区域内通过的反射对象的反射立方体贴图由该反射探测器临时提供。当对象从一个区域移动到另一个区域时,立方体贴图会相应地发生变化。 2. 反射探针的工作原理 场景中某个点的视觉环境可由立方体贴图表示。立方体贴图在概念上很像一个在内部表面绘有六个方向(上、下、左、右、前、后)平面图像的盒子。 为了让对象显示反射,其着色器必须能够访问表示立方体贴图的图像。对象表面的每个点都可在表面朝向的方向(即表面法向矢量的方向)上“看到”立方体贴图的一小块区域。着色器在此处使用立方体贴图的颜色来计算对象表面应该是什么颜色;镜面材质可能会准确反射颜色,而闪亮的汽车可能会略微褪色和着色。 3. 反射探针组件 __反射探针__非常像一个捕捉周围各个方向的球形视图的摄像机。然后,捕捉的图像将存储为立方体贴图,可供具有反射材质的对象使用。可在给定场景中使用多个反射探针,并可将对象设置为使用由最近探针生成的立方体贴图。带来的结果是对象上的反射可根据环境发生令人信服的变化。 属性 不同的渲染管线,反射探针的属性也不同,下面是内置渲染管线的 探针的 Type 属性可确定如何创建和更新反射数据: 烘焙 (Baked) 探针可存储 Editor 中烘焙的静态反射立方体贴图。自定义 (Custom) 探针可存储通过烘焙生成的或由用户手动设置的静态立方体贴图。实时 (Realtime) 探针在运行时更新立方体贴图,因此可对场景中的动态对象做出反应。 其他两种渲染管线中的反射探针具体属性文档,可以从下面的链接中找到: URP 渲染管线文档:https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@latest/ HDRP 渲染管线文档:https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@latest/ 4. 3D 场景中的默认光照探针 Unity 不仅使用天空盒来生成和配置环境光,而且还会在使用了天空盒(SkyBox)的 3D 场景中自动生成 AmbientProbe —— 环境(光)探针 和 反射探针。

激光点云系列之三:点云配准

交流群 | 进“传感器群/滑板底盘群”请加微信号:xsh041388 交流群 | 进“汽车基础软件群”请加微信号:Faye_chloe 备注信息:群名称 + 真实姓名、公司、岗位 作者 | 奚少华 在第一篇《详解激光雷达点云数据的处理过程》和第二篇《激光雷达点云处理中遇到的问题及对策》的激光点云系列文中,笔者分别分析了激光雷达的点云处理流程和点云处理环节中遇到的典型问题及对策。在本篇文章中,笔者将重点分析激光点云在定位环节中的点云配准技术。 由于受到视场角的限制,激光雷达在实时采集点云数据时,只能获得有限视野范围内的点云图像。为了获得三维场景的点云数据,感知算法人员需要在已知的初始姿态信息下,将采集到的前后两帧不同点云转换到统一坐标系下,将点云重合的部分拼接在一起——这就是点云配准技术。 下文将逐一分析点云配准具体是什么、点云配准的技术方法、点云配准面临的问题及对策。 01 点云配准在自动驾驶方面的应用 点云配准早先主要应用于建筑行业中的建筑信息模型(BIM)、采矿行业中的矿区开采等,而在自动驾驶领域内的作用主要有三类,分别为三维地图构建、高精地图定位、姿态估计。 第一,三维地图构建。在建高精地图时,自动驾驶系统通过激光雷达采集回来的相邻帧点云进行点云配准后,将不同位置采集回来的点云统一到一个坐标系下,然后构建出一个三维的高精度地图。 第二,高精地图定位。在自动驾驶车辆行驶时,车辆需要做到厘米级的精准定位。例如,自动驾驶车辆需要估计其在地图上的精确位置及车与道路路沿的距离。自动驾驶系统通过点云配准技术,将实时采集到的点云数据与高精地图的数据做匹配,为自动驾驶车辆给出精确的定位。 第三,姿态估计。自动驾驶系统通过点云配准技术来估计车辆的相对姿态信息,然后并有利于对车辆做决策规划。 02 点云配准的工作原理与技术方法 2.1 点云配准的工作原理 点云配准的工作原理是激光雷达由于受到环境等各种因素的限制,在点云采集过程中单次采集到的点云只能覆盖目标物表面的一部分,为了得到完整的目标物点云信息,就需要对目标物进行多次扫描,并将得到的三维点云数据进行坐标系的刚体变换,把目标物上的局部点云数据转换到同一坐标系下。 通俗点来说,点云配准的关键是如何寻找到初始点云和目标点云之间的对应关系,然后通过这个对应关系将原始点云和目标点云进行匹配,并计算出它们的特征相似度,最后统一到一个坐标系下。 图:点云的三维建图效果 (数据来源:互联网) 点云配准通常可分为两个步骤,分别是粗配准和精配准。 粗配准,即点云的初始配准,指的是通过一个旋转平移矩阵的初值,将两个位置不同的点云尽可能地对齐。粗配准的主流方法包括RANSAC、4PCS等。 经过粗配准之后,两片点云的重叠部分已经可以大致对齐,但精度还远远达不到自动驾驶车辆的定位要求,需要进一步做精配准。 精配准指的是在初始配准的基础上,进一步计算两个点云近似的旋转平移矩阵。精配准的主流方法包括ICP、NDT、深度学习等。 2.2 点云配准的技术方法 上文提到了一些点云配准的具体方法,由于各家自动驾驶公司的技术水平与技术方案都不同,所以他们会采用不同的点云配准方法——有些公司会在粗配准或者精配准过程中只采取一种方法,也有些公司会采取多种组合的方法。比如,在精准配过程中,某些公司会采用ICP+深度学习的方式。该章节将详细论述上文的几种点云配准方法。 2.2.1 粗配准的技术方法 (1)RANSAC(RAndom SAmple Consensus,随机采样一致) 方法原理:该算法从给定的样本集中随机选取一些样本并估计一个数学模型,将样本中的其余样本带入该数学模型中验证,如果有足够多的样本误差在给定范围内,则该数学模型最优,否则继续循环该步骤。 RANSAC算法被引入三维点云配准领域,其本质就是不断的对源点云进行随机样本采样并求出对应的变换模型,接着对每一次随机变换模型进行测试,并不断循环该过程直到选出最优的变换模型作为最终结果。 具体步骤: 1)对点云进行降采样和滤波处理,减少点云的计算量。 2)基于降采样和滤波处理后的点云数据,进行特征提取。 3)使用RANSAC算法进行迭代采样,获取较为理想的变换矩阵。 4)使用所获得的变换矩阵进行点云变换操作。 优点:适用于较大点云数据量的情况,可以在不考虑点云间距离大小的情况下,都能实现点云的粗配准。 缺点:存在配准精度的不稳定的问题。 (2)4PCS(4-Points Congruent Sets,全等四点集) 方法原理:该算法利用刚体变换中的几何不变性(如向量/线段比例、点间欧几里得距离),根据刚性变换后交点所占线段比例不变以及点之间的欧几里得距离不变的特性,在目标点云中尽可能寻找4个近似共面点(近似全等四点集)与之对应,从而利用最小二乘法计算得到变换矩阵,基于RANSAC算法框架迭代选取多组基,根据最大公共点集(LCP)的评价准则进行比较得到最优变换。 具体步骤: 1)在目标点云集合中寻找满足长基线要求的共面四点基(基线的确定与输入参数中overlap有很大关系,overlap越大,基线选择越长,长基线能够保证匹配的鲁棒性,且匹配数量较少)。 2)提取共面四点基的拓扑信息,计算四点基间的两个比例因子。 3)计算四种可能存在的交点位置,进而计算所有中长基线点对的交点坐标,比较交点坐标并确定匹配集合,寻找到对应的一致全等四点。 4)寻找点云中所有的共面四点集合,重复上述步骤可得到全等四点集合,并寻找最优全等四点对。 优点:适用于重叠区域较小或者重叠区域发生较大变化场景点云配准,无需对输入数据进行预滤波和去噪。 缺点:不适合工程化应用。 2.2.2 精配准的技术方法 (1)ICP(Iterative Closest Point,最近点迭代法) 方法原理:选取两片点云中距离最近的点作为对应点,通过所有对应点对求解旋转和平移变换矩阵,并通过不断迭代的方式使两片点云之间的配准误差越来越小,直至满足我们提前设定的阈值要求或迭代次数。 具体步骤: 1)计算源点云中的每一个点在目标点集中的对应近点。

flink流式分析

时间语义 flink明确支持以下三种时间语义,如果想要使用事件时间,需要额外给flink提供一个时间戳提取器和Watermark生成器,flink使用它们来跟踪事件时间的进度 事件时间:事件产生时间,数据中的记录的时间摄取时间:flink读取事件时的时间处理时间:具体算子处理事件的时间 Watermarks watermarks的作用是定义何时停止等待较早的时间(乱序的事件流) windows windows的作用是将无界数据流分解成有界数据流做聚合分析 用 flink 计算窗口分析取决于两个主要的抽象操作:Window Assigners,将事件分配给窗口(根据需要创建新的窗口对象),以及 Window Functions,处理窗口内的数据 窗口分类 滚动时间窗口滑动时间窗口滚动事件窗口滑动事件窗口会话窗口全局窗口 窗口应用函数 批处理,ProcessWindowFunction 会缓存 Iterable 和窗口内容,供接下来全量计算流处理,每一次有事件被分配到窗口时,都会调用 ReduceFunction 或者 AggregateFunction 来增量计算两者结合,通过 ReduceFunction 或者 AggregateFunction 预聚合的增量计算结果在触发窗口时, 提供给 ProcessWindowFunction 做全量计算 晚到的事件 默认场景下,超过最大无序边界的事件会被删除,但我们有两个选择去控制这些事件 旁路输出指定允许的延迟间隔,在这个间隔事件内,延迟的事件会继续分配给窗口 深入了解窗口操作 滑动窗口是通过复制来实现的时间窗口会和时间对齐,一个小时的窗口,12:05开始运行,第一个窗口会在1:00关闭。滑动窗口和滚动窗口分配器所才用的offset参数可以改变窗口的对齐方式。窗口后面可以再接窗口事件触发窗口的创建,如果窗口内没有事件,就不会有窗口,也就不会输出结果

优化改进YOLOv5算法之Wise-IOU损失函数

1 Wise-IOU损失函数 边界框回归(BBR)的损失函数对于目标检测至关重要。它的良好定义将为模型带来显著的性能改进。大多数现有的工作假设训练数据中的样本是高质量的,并侧重于增强BBR损失的拟合能力。如果盲目地加强低质量样本的BBR,这将危及本地化性能。Focal EIoU v1被提出来解决这个问题,但由于其静态聚焦机制(FM),非单调FM的潜力没有被充分利用。基于这一思想,作者提出了一种基于IoU的损失,该损失具有动态非单调FM,名为Wise IoU(WIoU)。当WIoU应用于最先进的实时检测器YOLOv7时,MS-COCO数据集上的AP75从53.03%提高到54.50%。 现有工作记锚框为 ,目标框为 IoU 用于度量目标检测任务中预测框与真实框的重叠程度,定义为: 同时,IoU 有一个致命的缺陷,可以在下面公式中观察到。当边界框之间没有重叠时 , 反向传播的梯度消失。这导致重叠区域的宽度 在训练时无法更新 现有的工作考虑了许多与包围盒相关的几何因素并构造了惩罚项 来解决这个问题,现有的边界框损失都是基于加法的损失,并遵循以下范式: Distance-IoU DIoU 将惩罚项定义为中心点连接的归一化长度: 同时为最小包围框的尺寸 提供了负梯度,这将使得 增大而阻碍预测框与目标框重叠: 但不可否认的是,距离度量的确是一个极其有效的解决方案,成为高效边界框损失的必要因子。EIoU 在此基础上加大了对距离度量的惩罚力度,其惩罚项定义为: Complete-IoU 在的基础上,CIoU 增加了对纵横比一致性的考虑: 其中的描述了纵横比一致性: 其中反向传播的梯度满足 ,也就是不可能为预测框的宽高提供同号的梯度。在前文对 DIoU 的分析中可知 DIoU 会产生负梯度,当这个负梯度与正好抵消时,会导致预测框无法优化。而 CIoU 对纵横比一致性的考虑将打破这种僵局。 Scylla-IoU Zhora Gevorgyan 证明了中心对齐的边界框会具有更快的收敛速度,以 angle cost、distance cost、shape cost 构造了 SIoU。其中 angle cost 描述了边界框中心连线与 x-y 轴的最小夹角: distance cost 描述了两边界框的中心点在x轴和y轴上的归一化距离,其惩罚力度与 angle cost 正相关。distance cost 被定义为: shape cost 描述了两边界框的形状差异,当两边界框的尺寸不一致时不为 0。shape cost 被定义为: 与类似,它们都由 distance cost 和 shape cost 组成: Wise IoU

SAP SD模块 信用额度不正确怎么办

信用管理是SD模块中重要的一部分,是为降低公司经营风险,用于对不同类型的客户实施不同管理政策。信用相关的事务码包括:信用特批VKM1 VKM3,信用维护 FD32 FD33。 当发现某一客户信用有问题,可以使用SE38>RVKRED88模拟更新信用,如果与FD33查看客户的信用不一致,则需要使用SE38>RVKRED77更新客户信用。 在使用RVKRED77更新客户信用时,SAP会锁表,当用户在做修改订单等操作时,RVKRED77是不会更新成功的,如要RVKRED77更新客户信用,有两个方式可供选择: 1)挑选中午或下班时更新数据,此时在系统中操作的用户相对较少,更新信用成功的概率相对较高,当然如果很急就不能采用这个方式了; 2)设定后台作业更新,2min更新一次,记得定时查看后台作业是否成功,更新成功了取消后台作业即可。 然而在前段时间,遇到了一个很特殊的场景*(客户有一张发货单的POD数量为0,该张发货单开票后,未将所占用的信用额度释放)*,特殊之处在于①能确定FD33查看到的客户信用额度错误;②使用RVKRED88,RVKRED77不能将客户信用更新为正常的值,后来查了NOTE 2742146 - RVKRED77: Incorrect open delivery value,结合测试终于搞定了这个问题。 问题和NOTE中描述的一致: 1)启用了POD; 2)有一张POD数量=0的发货单; 3)该客户有未完结的订单or发货单; 4)发票与发货单相关。 知道了问题出在哪里,解决起来其实很方便。捞出来该客户的未清订单,发现确实存在一张订单,订单中的部分已经完成发货过账>POD确认(存在POD数量=0的发货单)>开票一系列操作,但是订单中仍然有一部分数量未发货。解决方法就很简单了,①将订单中的未清数量先结案(为了运行RVKRED77能正确更新客户信用);②SE38运行RVKRED88以及RVKRED77,运行完成之后会发现被错误占用的信用额度已经释放;③将订单中的未清数量反结案,再观察FD33客户的信用是否正确,此时已经恢复正常。

你想知道的do{...}while(0)的作用,都在这里了

我们在嵌入式开发的过程中,经常可以碰到在一些宏定义或者是代码段中使用了do {...} while(0)的语句,从语义上理解,do {...} while(0)内的逻辑就只执行一次,并没有循环执行,粗略看来,似乎画蛇添足了,那么为什么还需要在只执行一次的逻辑外面加上一层do {...} while(0)语句呢?实际上,在这些逻辑中使用do {...} while(0)的作用远大于美化你的代码,下面就来看看实际的使用场景。 1、用于定义一个作用域,避免替换的时候出错 我们都知道,在程序中如果一些常量参数或者代码语句反复出现,就可以使用宏定义来替代。预处理阶段,对程序中所有出现的“宏名”,预处理器都会用宏定义中的字符串替代,这称为“宏替换”或“宏展开”。 这样做可提高程序的通用性和易读性,减少不一致性,一个较好的宏名可以更好的让读者理解常量参数的含义;同时程序易于修改,我们仅需要改变一个宏定义,就可以改变整个程序中出现的所有该常量或者语句。 但是有时可能程序代码段中,出现多条语句重复连续的使用,这样我们就可以尝试使用一个复杂的宏来替换。你有可能会这样定义: 1#define REPLACE_FUN() funA(); funB() 本意是在程序中当出现funA()和funB()多条语句连续使用时,使用REPLACE_FUN()来替换。 1if(判断条件) 2 REPLACE_FUN(); 但是实际上在预处理的时候,宏展开替换后变成了: 1if(判断条件) 2 funA(); 3 funB(); //此处funB()一定会执行,造成逻辑错误 可以看出,funB()不会按照判断条件才去执行。而是变成了一条独立的语句,而如果在宏中使用括号: 1#define REPLACE_FUN() {funA(); funB();} 我们一般的代码习惯都会在语句的末尾加上分号,因此也会出错: 1if(判断条件) 2 REPLACE_FUN(); 3//宏展开后为:4if(判断条件) 5{ 6 funA(); 7 funB(); 8 }; //此处替换后多一个分号;导致编译报错 因此,针对这种多条重复语句的连续使用,如果想用宏替换实现这个作用域的功能,就可以考虑使用do {...} while(0)语句: 1define REPLACE_FUN() \ 2do{ \ 3 funA();\ 4 funB();\ 5 }while(0)\ 6//宏展开前为: 7if(判断条件) 8 REPLACE_FUN(); 9//宏展开后为:10if(判断条件) 11do{ 12 funA(); 13 funB(); 14 }while(0); //根据判断条件,正确执行了一次逻辑 2、避免goto语句的使用 goto语句也称为无条件转移语句,使用后可以从多重循环或者多个判断中直接跳出。对于如下例子:

2023年寒假算法训练营周赛Round 3

P5724 【深基4.习5】求极差 / 最大跨度值 题目链接 题意 给出 n 和 n 个整数 a i,求这n 个整数中的极差是什么。极差的意思是一组数中的最大值减去最小值的差。 思路 运用最大值减去最小值 坑点 无 算法一: 实现步骤 将最大值减去最小值 代码 #include<bits/stdc++.h> using namespace std; int a[100001];//将在a数组里 int main() { int n; cin>>n; for(int i=1;i<=n;i++) { cin>>a[i]; } sort(a+1,a+n+1); cout<<a[n]-a[1];//a[n]为最大值,-a[1] 为最小值 return 0; } 总结 一道很简单的基础题 题目名字 题目链接 题意 设有一个 N×M方格的棋盘(1≤N≤100,1≤M≤100)求出该棋盘中包含有多少个正方形、多少个长方形(不包括正方形)。 思路 找规律 坑点 不注意正方形以及长方形的区分 算法一 实现步骤 1.小写为正方形个数,大写为长方形加上正方形个数 代码 #include<iostream> #include<cmath> //头文件 int n,m,sum,N,M,SUM; //定义,小写的是求正方形个数的 ,大写的是求正方形+长方形个数的 int main() { cin>>n>>m; //读入棋盘的长和宽 //输入 for(int i=1; i<=min(n,m); i++) //枚举边长,记住min(n,m),因为正方形只能由小的那条边作为边长,记住,这个min函数是在cmath库里调用的 sum+=(n-i+1)*(m-i+1); //套公式(n-边长+1)*(m-边长+1) //求正方形,知识点:1.

软件测试重要的7项原则

01 持续地测试 持续地反馈。软件测试贯穿着整个软件开发生命周期,随时发现需求、设计或代码中问题,及时将发现的问题反馈给用户、产品设计人员、开发人员等,主动、积极地交流,持续提高软件产品质量,这在敏捷测试中更为重要。 02 80/20 原则 在有限的时间和资源下进行测试,找出软件中所有的错误和缺陷是不可能的,因此测试总是存在风险的。测试的一个重要目标是尽量减少风险,抓住重点进行更多的测试。根据80/20 原则,即帕累托法则(Pareto Principle),用户80%的时间在使用软件产品中20%的功能。“重点测试”就是测试这20%的功能,而其他80%的功能属于优先级低的测试范围,占测试20%的资源。 03 建立清晰的阶段性目标 饭要一口一口地吃,不能一口就吃成胖子。测试的目标也要逐步达到,不可能在某一瞬间就达到。根据软件开发生命周期的不同阶段性任务,我们要决定相应的测试目标和任务。如在需求分析阶段,要参与需求评审以全面理解用户需求、发现需求的问题;在功能测试执行阶段,测试人员不仅要对新功能进行测试,而且要有效地完成回归测试。 04 测试独立性 测试在一定程度上带有“挑剔性”,心理状态是测试自己程序的障碍。同时,对于需求规格说明的错误理解也很难在程序员本人进行测试时被发现。程序员应避免测试自己的程序,为达到最佳的效果,应由独立的测试小组、第三方来完成测试。 05 确保可测试性 事先定义好产品的质量特性指标,测试时才能有据可依。有了具体的指标要求,才能依据测试的结果对产品的质量进行客观的分析和评估,才能使软件产品具有良好的可测试性。例如,进行性能测试前,产品规格说明书就已经清楚定义了各项性能指标。同样,测试用例应确定预期输出结果,如果无法确定所期望的测试结果,则无法进行正确与否的校验。 06 计划是一个过程 虽然通过文档来描述软件测试计划,并最后归档,但计划是一个过程,是指导各项软件测试活动的持续过程。在项目开始时很难将所有的测试点、测试风险等都了解清楚,随着时间推移,通过需求和设计的评审和探索式测试,对产品的理解越来越深,对测试的需求和风险越来越了解,可以进一步细化、不断丰富测试计划。其次,计划赶不上变化,软件产品的需求常会发生变化,测试计划不得不因此做出调整。所以,测试计划是适应实际测试状态不断变化而进行调整的一个过程。 07 一切从用户角度出发 在所有测试活动的过程中,测试人员都应该从客户的需求出发,想用户所想。正如我们所知,软件测试的目标就是验证产品开发的一致性和确认产品是否满足客户的需求,与之对应的任何产品质量特性都应追溯到用户需求。测试人员要始终站在用户的角度去思考、分析产品特性,多问问类似下面这样的问题: 这个新功能对客户的价值是什么? 客户会如何使用这个新功能? 客户在使用这个功能时,会进行什么样的操作? 按目前设计,用户觉得方便、舒服吗? 如果发现缺陷,去判断软件缺陷对用户的影响程度,系统中最严重的错误是那些导致程序无法满足用户需求的缺陷。软件测试,就是揭示软件中所存在的逻辑错误、低性能、不一致性等各种影响客户满意度的问题,一旦修正这些错误就能更好地满足用户需求和期望。 最后: 下方这份完整的软件测试视频学习教程已经整理上传完成,朋友们如果需要可以自行免费领取 【保证100%免费】 这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!

elementui上传图片 回显

<el-upload class="avatar-uploader" ref="otherLicense" action :auto-upload="false" :on-preview="handlePicPreview" :on-remove="handleRemove" :file-list="form.fileList" :limit="imgLimit" :on-change="otherSectionFile" list-type="picture-card" multiple > <i class="el-icon-plus"></i> </el-upload> <!-- 上传图片放大 --> <el-dialog :visible.sync="dialogVisible"> <img width="100%" :src="dialogImageUrl" alt="" /> </el-dialog> data中 // 业务结束证明材料 let validateImage = (rule, value, callback) => { // console.log(this.AddDateModel.fileId); //验证器 if (this.AddDateModel.fileId.length <= 0) { //为true代表图片在 false报错 callback(new Error("请上传业务结束证明材料")); } else { callback(); } }; AddDateModel: { fileId:[] }, // 回显图片的路径 photoList: [{ url: "" }], // 放大图片的路径 dialogImageUrl: "

网络有线无线配置

一、需求 在无线接入区内,当Lsw1的上联口出现故障时,需要通过AP1-LSw1-LSw2-LSw3的路径访问公网server3。这是因为AP1通过无线网连接到LSw1,而LSw1与LSw3之间的链路出现故障,无法直接访问公网server3。因此,流量需要通过LSw2进行转发,然后通过LSw3访问公网server3。 在有线接入区内,当Lsw2的上联口出现故障时,需要通过Lsw2-LSw1-LSw3的路径访问公网server。因为终端C通过有线网连接到LSw2,而Lsw2与LSw3之间的链路出现故障,无法直接访问公网server。因此,流量需要通过LSw1进行转发,然后通过LSw3访问公网server。 在无线接入区内,当Lsw1的上联口出现故障时,需要在LSw1和LSw2之间添加一个备用路径。具体配置命令如下: 实验过程: 二、配置命令 首先进行VLAN划分,将无线划分为VLAN10,管理AP划分为VLAN20,有线网划分为VLAN30.在LSW1和LSW2之间配置链路聚合,同时配置LSW1,LSW2,LSW3之间互联链路为trunk链路并且放行VLAN10,20,30,100的VLAN通过先在LSW3设备上面配置VLANif10,VLANif30的IP地址以及地址池,同时部署DHCP协议,使得无线终端和有线终端获取IP地址在AC1上部署VLANif20,同时配置地址池,并且配置dhcp使得AP获取到地址。配置设备管理VLANif100,对设备进行管理配置静态路由将外网打通以及设备管理打通配置telnet协议,采用aaa认证配置无线,无线ssid模板,安全模板,VAP模板,进行绑定,绑定到AP1,使得能终端能获取到VLAN10的地址。最后配置NAT策略,VLAN10和VLAN30的流量经过NAT转换。 具体配置如下: LSW1: sysname LSW1 # 设备更改设备名 vlan batch 10 20 30 100 # interface Vlanif100 ip address 192.168.100.1 255.255.255.0 # interface MEth0/0/1 # interface Eth-Trunk10 port link-type trunk port trunk allow-pass vlan 2 to 4094 mode lacp-static # interface GigabitEthernet0/0/1 eth-trunk 10 # interface GigabitEthernet0/0/2 eth-trunk 10 # interface GigabitEthernet0/0/3 port link-type trunk port trunk allow-pass vlan 10 20 30 100 # interface GigabitEthernet0/0/4 port link-type trunk port trunk pvid vlan 20 port trunk allow-pass vlan 2 to 4094 创建VLAN,配置ETh-trunk10,同时在交换机互联接口配置trunk接口允许VLAN10,20,30,100通过 ip route-static 0.

[LeetCode]-队列&优先队列/堆

前言 记录 LeetCode 刷题时遇到的 队列 以及 优先队列相关题目 队列 225.用队列实现栈 用两个队列实现栈。建立两个队列,队列1和队列2。数据输入时输入到其中一个队列,要取出数据时,将这个有数据的队列的元素一个一个出队并进入另一个队列,直到这个有数据的队列剩下最后一个元素时就是整个栈的栈顶元素,如果是要出栈,直接把这最后一个元素出队就可以了;如果是要获取栈顶元素,那就要先用一个Integer变量存这个元素的值,然后把这个元素加入另一个队列,再把这个值返回 所以可以看出来,两个队列,除了在初始化整个栈以及弹出所有栈中元素时都为空队列,其他时候两个队列中只会有一个队列不含元素。在入栈,出栈以及获取栈顶元素时要先判断 class MyStack { private LinkedList<Integer> queue1; private LinkedList<Integer> queue2; public MyStack() { queue1 = new LinkedList<>(); queue2 = new LinkedList<>(); } //入栈 public void push(int x) { if(queue1.peek() == null){ queue2.offer(x); }else { queue1.offer(x); } } //出栈 public int pop() { if(queue1.peek() == null){ if(queue2.peek() == null){ return -1; }else { while (queue2.size() > 1){ queue1.offer(queue2.poll()); } return queue2.

解决api-ms-win-crt-runtime-l1-1-0.dll文件丢失

其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题,如果是新手第一时间会认为是软件或游戏出错了,其实并不是这样,其主要原因就是你电脑系统的该dll文件丢失了或者损坏了,这时你只需下载这个api-ms-win-crt-runtime-l1-1-0.dll文件进行安装(前提是找到适合的版本),当我们执行某一个.exe程序时,相应的DLL文件就会被调用,因此安装好之后就能重新打开你的软件或游戏了. 那么出现api-ms-win-crt-runtime-l1-1-0.dll丢失要怎么解决? 一、手动从本站下载dll文件 1、从下面列表下载api-ms-win-crt-runtime-l1-1-0.dll文件 32位 文件: api-ms-win-crt-runtime-l1-1-0.dll 10.0.10240.16390 2、将下载的文件放入到你要运行的软件或者游戏的安装所在文件夹之中,可以右键点击主执行程序.exe然后选择"打开文件所在的位置" 找到安装目录,将文件复制进去。 或者将文件复制到Windows系统目录,这个需要注意电脑的系统是32位还是64位,如果是32位的系统,那就将本站下载32位的dll文件放到“C:/Windows/System32”这个文件夹里面,如果是64位的系统,那就将本站下载的32位dll文件放到“C:/Windows/SysWOW64”这个文件夹里面,本站下载的64位文件放到“C:/Windows/System32”这个文件夹里面. 如果问题依然无法解决,值得注意的是此类文件的丢失有时候和杀毒软件的误报毒有关,所以请将此类dll文件添加到杀毒软件的信任列表当中. 二、使用本站提供的软件进行自动修复 本站出品的DLLEscort软件具有修复Windows系统文件的特性,它可以帮助你修复系统软件或游戏丢失的DLL运行库文件。 如:DirectX游戏运行库,directx出现错误导致的游戏打不开等BUG; VC(Microsoft Visual C++)运行库是在Windows系统下运行Visual Studio开发的应用必备组件,缺少的话无法运行软件,会出现提示缺少DLL的情况。 DLLEscort全面支持32/64位 Windows XP,Windows Vista, Windows 7, Windows 8, Windows 8.1, Windows 10 操作系统 下载地址:本站下载 | 百度网盘下载(提取码: 9999),下载完成后得到安装包文件运行后,点击Next下一步进行安装,安装完毕后会自动打开软件或手动执行桌面主程序(DLLEscort)即可打开软件, 桌面软件图标: 一、点击“PC Scan”或 “Click to Start Scan”开始对系统丢失文件扫描 二、扫描完成,扫描结果分成三部分,包括1,待修复的丢失文件。 2,待修复的注册表。 3.待清理的系统缓存文件。 三、点击”ALL Repair”修复开始,请保持网络通畅,直到所有问题修复完成。

芯旺微烧录器使用及驱动安装

芯旺微烧录器使用及驱动安装 一、烧录器驱动安装说明: 注意事项:在我们安装IDE的时候正常都会默认安装了烧录器的驱动,只有安装了烧录器驱动电脑才能识别到烧录器,才能进行后续的固件升级; 所以如果已经默认IDE安装步骤的可以无视此条,如果一不小心没有安装或者未安装成功的也不用担心,下面就是通过IDE的烧录器驱动安装步骤 : 步骤 1、点击菜单栏的 帮助 — 安装驱动程序 2、在弹框后直接下一步直到安装完成即可; 这样插上烧录器就可以正常识别到烧录器啦,如果电脑有个别加密软件或者WIN7系统尽管提示安装成功,但是仍然识别烧录器的,建议安装后重启一下电脑,如果还是无法识别,最好是更换其他电脑尝试。 二 、固件升级说明: 1、黄色 烧录器使用: 此版本的烧录器为初始版本的烧录器,适配所有版本的IDE,固件升级通过帮助,固件升级,在弹框中升级后即可正常使用。 步骤 1、开打IDE并点击 菜单栏的 帮助 ---- 固件升级管理 ; 2、弹框后 2、蓝色 烧录器使用: 此版本烧录器为新版本的烧录器,在IDE不是最新的(目前版本1.0.19.4)情况下,需要通过官网的压缩包另行单独升级,链接附上 新版本烧录器下载链接 步骤 1、下载压缩包 2、下载后解压,找到此文件,双击 3、弹框后进行升级,依次点击如下 以上即可完成新版本的烧录器升级任务。 本次更新时间为20230202.

大数据毕业设计 opencv指纹识别系统 - python 图像识别

文章目录 0 前言1 课题背景2 效果展示3 具体实现3.1 图像对比过滤3.2 图像二值化3.3 图像侵蚀细化3.4 图像增强3.5 特征点检测 4 OpenCV5 最后 0 前言 🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的是 🚩 基于机器视觉的指纹识别系统 🥇学长这里给一个题目综合评分(每项满分5分) 难度系数:3分工作量:3分创新点:4分 1 课题背景 指纹是指人类手指上的条状纹路, 它们的形成依赖于胚胎发育时的环境。“没有2个完全相同的指纹”这一观点已经得到公认。指纹识别已经有了很长一段历史。 据考古学家证实:公元前6 000年以前, 指纹作为身份鉴别的工具已经在古叙利亚和中国开始应用。到了20世纪80年代,、光学扫描这2项技术的革新, 使得它们作为指纹取像的工具成为现实, 从而使指纹识别可以在其他领域中得以应用。 现在, 随着取像设备的引入及其飞速发展, 生物指纹识别技术的逐渐成熟, 可靠的比对算法的发现都为指纹识别技术提供了更广阔的舞台。 本项目实现了一种指纹识别系统,通过过滤过程来确定用户指纹是否与注册的指纹匹配。通过过滤技术对捕获的指纹进行处理,以从捕获的图像中去除噪声。去除噪声后的最终结果与注册的指纹进行特征匹配,以确定它们是否相同。 2 效果展示 3 3 具体实现 3.1 图像对比过滤 图像融合是一种图像增强方法,这里先融合两个图像便于特征点对比。利用的是opencv封装的函数 cv2.addWeighted() 相关代码 def apply_Contrast(img): alpha = 0.5 # assigned weight to the first image beta = 0.5 # assigned weight to the second image img_second = np.

SqlForamt,sql组装工具类

import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @author: wenyong.wang@kuwo.cn * @version: v1.0 * @description: cn.kuwo.added.service.ui * @date:2023/2/20 */ public class SqlForamt { private static final String sqlFormat = "select %s from %s where 1=1 %s %s %s %s %s"; private StringBuffer columns = new StringBuffer(); private StringBuffer table = new StringBuffer(); private StringBuffer condition = new StringBuffer(); private StringBuffer groupBy = new StringBuffer(); private StringBuffer orderBy = new StringBuffer(); private StringBuffer limit = new StringBuffer(); private StringBuffer ext = new StringBuffer(); public String getSQL(){ return String.