双线性插值缩放算法原理以及matlab与verilog的实现(二)

系列文章目录

双线性插值缩放算法原理以及matlab与verilog的实现(一)


文章目录

  • 系列文章目录
  • 前言
  • 一、前提回顾
  • 二、FPGA实现步骤
    • 2.1 找到源图像四个像素点求目标像素点
    • 2.2 FPGA实现步骤
    • 2.3 总体框架
    • 2.4 ROM缓存模块
    • 2.5 VGA模块
    • 2.6 双线性算法模块
  • 三、下板验证


前言

开发平台:vivado2020.1
开发芯片:xc7k410tffv900-2

在上一篇文章,我们学会了双线性缩放插值算法的原理以及matlab的实现,以及VGA时序的简单实现。
本文实现目的:用verilog实现双线性插值算法,将一张112 ×103大小图片,放大两倍至224 ×206,然后通过VGA显示出来

一、前提回顾

双线性插值算法公式如下:
在这里插入图片描述

f ( x , y ) = f ( Q 11 ) ( 1 − u ) ( 1 − v ) + f ( Q 21 ) u ( 1 − v ) + f ( Q 12 ) ( 1 − u ) v + f ( Q 22 ) u v f(x,y)={f(Q_{11})}{(1-u)(1-v)}+{f(Q_{21})}{u(1-v)}+{f(Q_{12})}{(1-u)v}+{f(Q_{22})}{uv} f(x,y)=f(Q11)(1u)(1v)+f(Q21)u(1v)+f(Q12)(1u)v+f(Q22)uv

由于在图像处理中,一般将左上角的像素点定义为坐标原点,因此将上述的图片变换一下坐标,以及命名顺序,就变为了:
在这里插入图片描述

f ( x , y ) = f ( Q 11 ) ( 1 − u ) ( 1 − v ) + f ( Q 21 ) u ( 1 − v ) + f ( Q 12 ) ( 1 − u ) v + f ( Q 22 ) u v f(x,y)={f(Q_{11})}{(1-u)(1-v)}+{f(Q_{21})}{u(1-v)}+{f(Q_{12})}{(1-u)v}+{f(Q_{22})}{uv} f(x,y)=f(Q11)(1u)(1v)+f(Q21)u(1v)+f(Q12)(1u)v+f(Q22)uv

二、FPGA实现步骤

现在我们知道,我们用一张已知各点像素值的图片(源图像),求出一张放大两倍的图片(目标图像),但是目标各点像素值都是未知。双线性插值算法核心就是:用已知的四个像素点的值算出所求目标像素点的值。因此步骤如下:

2.1 找到源图像四个像素点求目标像素点

根据目标像素点位置乘以缩放系数( s r c w i d t h d s t w i d t h , s r c h e i g h t d s t h e i g h t \frac{srcwidth}{dstwidth},\frac{srcheight}{dstheight} dstwidthsrcwidthdstheightsrcheight)得到一个浮点坐标 ( i + u , j + v ) (i+u,j+v) i+uj+v(其中 i i i j j j为浮点坐标的整数部分; u u u v v v为浮点坐标的小数部分),而这个浮点坐标 ( i + u , j + v ) (i+u,j+v) i+uj+v的像素值 f ( i + u , j + v ) f(i+u,j+v) f(i+uj+v),就是上图中所要求的p点值,所以由公式可知, f ( p ) f(p) f(p)可由 f ( Q 11 f(Q_{11} f(Q11)、 f ( Q 12 f(Q_{12} f(Q12)、 f ( Q 21 f(Q_{21} f(Q21)、 f ( Q 22 f(Q_{22} f(Q22)求出。而 f ( Q 11 f(Q_{11} f(Q11)、 f ( Q 12 f(Q_{12} f(Q12)、 f ( Q 21 f(Q_{21} f(Q21)、 f ( Q 22 f(Q_{22} f(Q22)的坐标分别是 ( i , j ) (i,j) ij ( i + 1 , j ) (i+1,j) i+1j ( i , j + 1 ) (i,j+1) ij+1 ( i + 1 , j + 1 ) (i+1,j+1) i+1j+1

例如:将图像放大2倍

  1. 缩放系数为(0.5,0.5)
  2. 假如求目标图像坐标(10,15)的像素值,浮点坐标为(5 + 0,7 + 0.5)其中u = 0,v = 0.5
  3. 源图像四个点坐标为 ( 5 , 7 ) (5,7) 57 ( 6 , 7 ) (6,7) 67 ( 5 , 8 ) (5,8) 58 ( 6 , 8 ) (6,8) 68
  4. 带入双线性插值算法公式就可求出

2.2 FPGA实现步骤

  1. 求出缩放系数,通常涉及到小数,FPGA处理小数通常是将浮点数转化成定点数来计算(参考FPGA浮点数计算),本文将浮点数放大256倍,例如缩放系数为0.5,则在FPGA中显示为128。再例如,计算 1 - 0.7 = 0.3,在FPGA中就是256 - 179 = 77
  2. 如何同时取出源图像四个点:因为FPGA中,无论是RAM还是ROM,一个时钟周期只能读出一个数据,所以需要将源图像缓存至四个RAM或者4个ROM中(面积换速度),这样一次性给四个地址到这四个ROM中,就能同时收到四个像素点
  3. 实现公式:公式都是由加法和乘法组成,为了速度能快,选用加法器和乘法器的IP,而不是直接用 +,×
  4. 计算完成,数据缓存到RAM里,VGA接口直接读RAM

2.3 总体框架

在这里插入图片描述

2.4 ROM缓存模块

  1. 将图片通过matlab提取像素点,按照RGB顺序,十六进制的格式写入coe文件里,maltab代码如下:
% 读取图像
img = imread('C:\Users\Administrator\Desktop\qq.jpg');% 获取图像尺寸
[height, width, ~] = size(img);% 打开 COE 文件以写入数据
fileID = fopen('C:\Users\Administrator\Desktop\save.coe', 'w');% 写入 COE 文件头部信息
fprintf(fileID, 'memory_initialization_radix=16;\n');
fprintf(fileID, 'memory_initialization_vector=\n');% 遍历图像像素并将像素值写入 COE 文件
for i = 1:heightfor j = 1:width% 将像素值写入 COE 文件fprintf(fileID, '%02X%02X%02X,\n', img(i,j,1), img(i,j,2), img(i,j,3));  end
end% 关闭 COE 文件
fclose(fileID);
disp('COE file generation complete.');

得到coe文件
在这里插入图片描述
打开ROM ip,生成一个位宽24位。深度112×103=11536的ROM,初始化文件为此coe文件
在这里插入图片描述

2.5 VGA模块

vga模块代码和上篇文章一样,只是加了读ROM的操作,代码如下:

 //显示ROM缓存的图片
module vga_ctrl
(input                                               clk ,input           [23:0]                              data_in ,output  reg     [13:0]                              rd_rom_addr,	output  reg                                         vs =1'b0 ,output  reg                                         hs =1'b0 ,output  reg     [23:0]                              data_out    );parameter                                           hcnt_max        =1100;//行扫描是对列计数,最大值parameter                                           vcnt_max        =2250;//列扫描是对行计数,最大值parameter                                           H_ACTIVE        =960; //行数据有效时间parameter                                           H_FRONT_PORCH   =44 ; //行前沿时间parameter                                           H_SYNC_TIME     =22;//行同步信号时间parameter                                           H_BACK_PORCH    =74;//行消隐后肩时间parameter                                           V_ACTIVE        =2160;//场数据有效时间parameter                                           V_FRONT_PORCH   =8 ; //场前沿时间parameter                                           V_SYNC_TIME     =10   ; //场同步信号时间parameter                                           V_BACK_PORCH    =72;//场后沿时间reg             [10:0]                              hcnt ='d0    ;reg             [11:0]                              vcnt ='d0   ;reg             [10:0]                              pix_x ='d0    ;//当前显示像素点x坐标reg             [11:0]                              pix_y ='d0   ; //当前显示像素点y坐标//对行扫描进行计数always @(posedge clk)beginif(hcnt == hcnt_max - 1 )hcnt <= 0;elsehcnt <= hcnt +'d1;		end//对列扫描进行计数always @(posedge clk)beginif((vcnt == vcnt_max-1)&&(hcnt == hcnt_max -1))vcnt <= 0;else	if(hcnt == hcnt_max -1)vcnt <= vcnt +'d1;elsevcnt <= vcnt;endalways@(posedge clk)beginif(hcnt < H_SYNC_TIME)hs <= 1;elsehs <= 0;endalways@(posedge clk)beginif(vcnt < V_SYNC_TIME)vs <= 1;elsevs <= 0;end	//整个屏幕有效显示区域always @(posedge clk) beginif(((hcnt >= H_SYNC_TIME +H_BACK_PORCH)&&(hcnt < H_SYNC_TIME +H_BACK_PORCH +H_ACTIVE))&&((vcnt >=V_SYNC_TIME + V_BACK_PORCH)&&(vcnt<V_SYNC_TIME+V_BACK_PORCH+V_ACTIVE)))beginde <= 1'b1;endelse beginde <= 1'b0;endend//当前显示的像素点的位置always@(posedge clk)beginif(de == 1'b1)beginpix_x <= hcnt - H_SYNC_TIME - H_BACK_PORCH;pix_y <= vcnt - V_SYNC_TIME - V_BACK_PORCH;endelse beginpix_x <= 'd0;pix_y <= 'd0;endend
//提前一拍读ROM地址always @(posedge clk) beginif((pix_x >= 278)&&(pix_x <390)&&((pix_y >=1080)&&(pix_y < 1183)))beginif(rd_rom_addr <'d11535)rd_rom_addr <= rd_rom_addr + 1;elserd_rom_addr <= 'd0;endelse beginrd_rom_addr <= rd_rom_addr;endendalways @(posedge clk) beginif((pix_x >= 279)&&(pix_x <391)&&((pix_y >=1080)&&(pix_y < 1183)))data_out <= data_in;else data_out <= 96'h800080_800080_800080_800080;endendmodule 

屏幕显示效果:
在这里插入图片描述
VGA模块以及ROM数据皆正常,至于为什么图片偏绿,可能是因为显示器YUV和RGB色域转换的问题,后续文章会说明,现在暂时不管。

2.6 双线性算法模块

module bilinear_calculate(input                                               clk ,input                                               rst_n   ,input           [7:0]                               cur_u_dec   ,       //输入的uinput           [7:0]                               cur_v_dec   ,       //输出的vinput                                               pix_en,input           [7:0]                               i_j_pix ,		    //i_j_pix=f(i,j)input           [7:0]                               i_j_1_pix   ,		//i_j_1_pix=f(i,j+1)input           [7:0]                               i_1_j_pix   ,		//i_1_j_pix=f(i+1,j)input           [7:0]                               i_1_j_1_pix ,	    //i_1_j_1_pix=f(i+1,j+1)output  reg     [7:0]                               post_cal_data,output  reg                                         post_cal_data_valid =1'b0);//f(x,y)= f(0,0)*(1-u)(1-v)+f(1,0)*u*(1-v)+f(0,1)*(1-u)*v+f(l,1)*u*vreg             [7:0]                               cur_u_dec_reg=8'd0  ;reg             [7:0]                               cur_v_dec_reg=8'd0  ;reg             [8:0]                               u_1 =9'd0;	//1-ureg             [8:0]                               v_1 =9'd0;	//1-vreg             [8:0]                               u   =9'd0;	//ureg             [8:0]                               v   =9'd0;	//vreg             [8:0]                               u_1_reg =9'd0;	reg             [8:0]                               v_1_reg =9'd0;	reg             [8:0]                               u_reg   =9'd0;	reg             [8:0]                               v_reg   =9'd0;	reg             [8:0]                               u_1_reg_copy    =9'd0;	reg             [8:0]                               v_1_reg_copy    =9'd0;	reg             [8:0]                               u_reg_copy  =9'd0;	reg             [8:0]                               v_reg_copy  =9'd0;	wire            [17:0]                              u_v ;wire            [17:0]                              u_1_v_1 ;wire            [17:0]                              u_v_1  ;wire            [17:0]                              u_1_v  ;reg             [17:0]                              u_v_reg =18'd0;reg             [17:0]                              u_1_v_1_reg =18'd0;reg             [17:0]                              u_v_1_reg   =18'd0;reg             [17:0]                              u_1_v_reg   =18'd0;reg             [7:0]                               i_j_pix_reg =8'd0;	reg             [7:0]                               i_j_1_pix_reg   =8'd0;	reg             [7:0]                               i_1_j_pix_reg   =8'd0;	reg             [7:0]                               i_1_j_1_pix_reg =8'd0;wire            [25:0]                              Fi_j_pix0   ;					wire            [25:0]                              Fi_j_1_pix0 ;	wire            [25:0]                              Fi_1_j_pix0 ;wire            [25:0]                              Fi_1_j_1_pix0   ; 	reg             [25:0]                              Fi_j_pix0_reg   =26'd0;	reg             [25:0]                              Fi_j_1_pix0_reg =26'd0;	reg             [25:0]                              Fi_1_j_pix0_reg =26'd0;reg             [25:0]                              Fi_1_j_1_pix0_reg   =26'd0; 	reg             [25:0]                              F_i_u_j_v1_pix0 =26'd0;reg             [25:0]                              F_i_u_j_v2_pix0 =26'd0;reg             [26:0]                              F_i_u_j_v_pix0  =27'd0;reg             [5:0]                               pix_en_reg ='d0  ;always@(posedge clk )begincur_u_dec_reg	     <= cur_u_dec;cur_v_dec_reg      <= cur_v_dec;
endalways@(posedge clk )beginu_1    <= {1'b0,~cur_u_dec_reg} + 1;v_1    <= {1'b0,~cur_v_dec_reg} + 1;u 	    <= cur_u_dec_reg;v 	    <= cur_v_dec_reg;
endalways@(posedge clk )beginu_1_reg	   <= u_1; v_1_reg	   <= v_1;u_reg	 <= u; 	v_reg	 <= v; 	
endalways@(posedge clk )beginu_1_reg_copy	  <= u_1; v_1_reg_copy	  <= v_1;u_reg_copy		   <= u; 	v_reg_copy		   <= v; 	
endmult_9_9 mult_u_v (.CLK(clk),  .A(u_reg),      .B(v_reg),      .P(u_v)      
);mult_9_9 mult_u_1_v_1 (.CLK(clk),  .A(u_1_reg),      .B(v_1_reg),      .P(u_1_v_1)      
);mult_9_9 mult_u_1_v (.CLK(clk),  .A(u_1_reg_copy),      .B(v_reg_copy),      .P(u_1_v)      
);mult_9_9 mult_u_v_1 (.CLK(clk),  .A(u_reg_copy),      .B(v_1_reg_copy),      .P(u_v_1)      
);always@(posedge clk)beginu_v_reg			<= u_v;		u_1_v_1_reg		<= u_1_v_1;	u_v_1_reg		<= u_v_1;	u_1_v_reg		<= u_1_v;	
end// pix_cal
always@(posedge clk)begini_j_pix_reg		<= i_j_pix;		i_j_1_pix_reg	<= i_j_1_pix;	i_1_j_pix_reg	<= i_1_j_pix;	i_1_j_1_pix_reg <= i_1_j_1_pix;
endmult_18_8 mult1 (.CLK(clk),  .A(u_1_v_1_reg),      .B(i_j_pix_reg),      .P(Fi_j_pix0)      
);mult_18_8 mult2 (.CLK(clk),  .A(u_1_v_reg),      .B(i_j_1_pix_reg),      .P(Fi_j_1_pix0)      
);mult_18_8 mult3(.CLK(clk),  .A(u_v_1_reg),      .B(i_1_j_pix_reg),      .P(Fi_1_j_pix0)      
);mult_18_8 mult4(.CLK(clk),  .A(u_v_reg),      .B(i_1_j_1_pix_reg),      .P(Fi_1_j_1_pix0)      
);always@(posedge clk)beginFi_j_pix0_reg		<= Fi_j_pix0;		Fi_j_1_pix0_reg		<= Fi_j_1_pix0;	Fi_1_j_pix0_reg		<= Fi_1_j_pix0;	Fi_1_j_1_pix0_reg  	<= Fi_1_j_1_pix0;
endalways@(posedge clk)beginF_i_u_j_v1_pix0	<=	Fi_j_pix0_reg + Fi_j_1_pix0_reg;F_i_u_j_v2_pix0	<=	Fi_1_j_pix0_reg + Fi_1_j_1_pix0_reg;endalways@(posedge clk)beginF_i_u_j_v_pix0 <= {1'b0,F_i_u_j_v1_pix0} + {1'b0,F_i_u_j_v2_pix0};
endalways@(posedge clk)beginif(F_i_u_j_v_pix0[26 : 24] == 'd0)post_cal_data <= F_i_u_j_v_pix0[23 : 16];elsepost_cal_data <= 8'hff;
endalways @(posedge clk) beginpix_en_reg <= {pix_en_reg[4:0],pix_en};if(pix_en_reg[5] == 1'b1)post_cal_data_valid <= 1'b1;elsepost_cal_data_valid <= 1'b0;
end
endmodule

三、下板验证

再修改一下vga模块,让它显示两部分,左边是原始图片,右边显示放大图片。效果如下:
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PlantUML + VS Code

PlantUML 使用实例 文章目录 PlantUML 使用实例1. PlantUML简介1.1 什么是PlantUML1.2 PlantUML优势在哪 2. 怎么用2.1 环境依赖2.2 VS Code组件安装 3. 常用语法3.1 标记开始结束3.2 声明参与者3.3 声明关系3.4 对消息序列编号3.5 组合消息 4. 实例 1. PlantUML简介 1.1 什么…

deepin23beta中SQLite3数据库安装与使用

SQLite 是一个嵌入式 SQL 数据库引擎&#xff0c;它实现了一个自包含、无服务器、零配置、事务性 SQL 数据库引擎。 SQLite 的代码属于公共领域&#xff0c;因此可以免费用于任何商业或私人目的。 SQLite 是世界上部署最广泛的数据库&#xff0c;其应用程序数量之多&#xff0c…

SQLiteC/C++接口详细介绍之sqlite3类(三)

快速跳转文章列表&#xff1a;SQLite—系列文章目录 上一篇&#xff1a;SQLiteC/C接口详细介绍之sqlite3类&#xff08;二&#xff09; 下一篇&#xff1a;SQLiteC/C接口详细介绍之sqlite3类&#xff08;四&#xff09; 6.sqlite3_create_module与sqlite3_create_module_v2函数…

数据库不应放在容器中?- B站Kubernetes有状态服务实践(Elasticsearch/Clickhouse)

本期作者 前言 云原生时代下&#xff0c; Kubernetes已成为容器技术的事实标准&#xff0c; 使得基础设施领域应用下自动化运维管理与编排成为可能。对于无状态服务而言&#xff0c; 业界早已落地数套成熟且较完美的解决方案。可对于有状态的服务&#xff0c; 方案的复杂度就以…

电视盒子解析安装包失败,安卓4.4安装不了kodi的解决方法,如何安装kodi

有些安卓电视或者电视盒子的安卓系统版本太低、自身架构或者屏蔽了安装其他应用的功能&#xff0c;下载的Kodi apk安装包提示无法安装&#xff0c;解析程序包时出现问题、解析出错无法安装、[INSTALL_FAILED_OLDER_SDK]、此应用与您的电视不兼容。 解决方法&#xff1a; 1、3…

学习Android的第二十八天

目录 Android Service (服务) 线程 Service (服务) Service 相关方法 Android 非绑定 Service startService() 启动 Service 验证 startService() 启动 Service 的调用顺序 Android 绑定 Service bindService() 启动 Service 验证 BindService 启动 Service 的顺序 …

【AI】如何创建自己的自定义ChatGPT

如何创建自己的自定义ChatGPT 目录 如何创建自己的自定义ChatGPT大型语言模型(LLM)GPT模型ChatGPTOpenAI APILlamaIndexLangChain参考推荐超级课程: Docker快速入门到精通Kubernetes入门到大师通关课本文将记录如何使用OpenAI GPT-3.5模型、LlamaIndex和LangChain创建自己的…

DirectShowPlayerService::doSetUrlSource: Unresolved error code 0x800c000d

报出这个问题&#xff0c;应该是对给的url解析不正确&#xff0c;我给的是rtsp的视频流地址&#xff0c;应该是对该格式解析异常。 所以参考两篇文&#xff1a; QT无法播放视频&#xff1a;报错&#xff1a;DirectShowPlayerService::doRender: Unresolved error code 0x8004…

vue3项目随笔1

1,Eslint Prettier 报错情况&#xff1a; 解决办法&#xff1a; &#xff08;1&#xff09;下载Prettier - code formatter &#xff08;2&#xff09;配置setting.json文件 文件 -> 首选项 -> 设置 -> 用户 -> Eslint "editor.defaultFormatter":…

拖动排序与置顶的Java实现

文章目录 1、需求分析2、表设计3、接口设计4、业务层5、数据层 整理个需求的实现思路。 1、需求分析 列表展示了一系列产品&#xff0c;现要支持通过拖动来给产品排序&#xff0c;也要支持单个产品的置顶、删除。类似CSDN的专栏文章管理。 2、表设计 现要支持对列表的产品进…

融入Facebook的世界:探索数字化社交的魅力

融入Facebook的世界&#xff0c;是一场数字化社交的奇妙之旅。在这个广袤的虚拟社交空间中&#xff0c;人们可以尽情展现自己、分享生活&#xff0c;与全球朋友、家人和同事保持紧密联系&#xff0c;共同探索社交互动的乐趣与魅力。让我们深入了解这个世界的魅力所在&#xff1…

ASP.NET-Server.HtmlEncode

目录 背景: 1.转义特殊字符&#xff1a; 2.防止跨站脚本攻击&#xff08;XSS&#xff09;&#xff1a; 3.确保输出安全性&#xff1a; 4.保留原始文本形式&#xff1a; 5.与用户输入交互安全&#xff1a; 实例说明: 不用Server.HtmlEncode 效果展示: 用Server.HtmlEnc…

多场成像,快速提高机器视觉检测能力--51camera

多阵列CMOS传感器与芯片级涂层二向色滤光片相结合&#xff0c;可在单次扫描中同时捕获明场、暗场和背光图像。 多场成像是一种新的成像技术&#xff0c;它可以在不同的光照条件下同时捕获多幅图像。再加上时间延迟积分(TDI)&#xff0c;这种新兴的成像技术可以克服许多限制的传…

【敬伟ps教程】视频动画

文章目录 视频文档视频时间轴帧动画视频文档 工作区需由[基本功能]切换为[动感] 可以看到我们需从时间的维度来编辑动态视觉图像 时间轴:从时间的维度来编辑动态视觉图像 PS提供的时间轴有两种:1、视频时间轴;2、动画时间轴 新建视频文档,点击新建或Ctrl+N,预设选择“胶…

springboot276基于JS的个人云盘管理系统的设计与实现

个人云盘管理系统设计与实现 摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装个人云盘管理系统软件来发挥其…

3.自定义工程目录配置CMakeLists

问题背景 熟悉stm32keil开发的都知道&#xff0c;我们在编写不同的外设时&#xff0c;通常都会单独编写一个app文件夹或者是user文件夹之类的来存放不同外设功能的源文件和头文件。 在前面一节2.构建第一个工程并烧录到ESP32开发板-CSDN博客中&#xff0c;我们是使用了一个乐鑫…

【联邦学习贡献评估-参与方贡献评估方案的介绍】

在明确如何度量参与方组合数据价值的基础上, 本篇介绍如何进一步度量参与方在联邦合作中的贡献, 具体介绍如下 4 种参与方贡献评估方案. 个体法 将参与方自身数据的价值度量或者相关变体作为该参与方的贡献. 个体法可以基于任何 数据价值度量指标进行, 特别地, 有个体信誉、个…

Python面试笔记

Python面试笔记 PythonQ. Python中可变数据类型与不可变数据类型&#xff0c;浅拷贝与深拷贝详解Q. 解释什么是lambda函数&#xff1f;它有什么好处&#xff1f;Q. 什么是装饰器&#xff1f;Q. 什么是Python的垃圾回收机制&#xff1f;Q. Python内置函数dir的用法&#xff1f;Q…

SpringBoot整合Activiti7——实战之请假流程(普通)

文章目录 代码实现xml文件部署流程启动流程查询任务填写请假单部门审批 请假流程&#xff1a;开始-填写请假单-部门审批-结束 代码实现 xml文件 <?xml version"1.0" encoding"UTF-8"?> <definitions xmlns"http://www.omg.org/spec/BPMN/…

服务器段的连接端口和监听端口编程实现

new ServerSocket(int)是开启监听端口&#xff0c;并不是连接端口。真正的连接端口是随机开辟的空闲端口&#xff0c;当连接创建完成后&#xff0c;监听关口可以继续等待下一次连接请求&#xff0c;处于空闲等待状态。 编程实现方式 1 、主线程一直处于阻塞等待状态&#xff0c…