python的opencv操作记录13——区域生长及分水岭算法
文章目录
- 图像区域基本算法——形态学运算
- 腐蚀与膨胀
- 开运算与闭运算
- opencv中的形态学运算
- 距离计算——distanceTransform函数
- 连通域
- 连通的定义
- 计算连通域——connectedComponents
- 连通域实验
- 基于区域的分割
- 区域生长算法
- 自定义一个最简单区域生长算法实现
- 区域分割
- 一般区域分割
- opencv中的分水岭算法
- 分水岭算法原理简单说明
- 分水岭算法使用
前面两篇文章说的分割,一个是基于阈值的分割,一个是基于边缘算法的分割。在传统的图像处理算法中,还有一个大类是基于区域的分割。
图像区域基本算法——形态学运算
基于区域的分割,需要先补充一点其他的预备知识,首先是图像形态学。
图像形态学就是对图像在形态上的一些算法,或者说运算。
腐蚀与膨胀
腐蚀和膨胀使形态学运算中最基本的用法,这个在之前的文章里描述过opencv中的原理和具体用法:
https://blog.csdn.net/pcgamer/article/details/124729236?spm=1001.2014.3001.5502
这里就不多说了。
开运算与闭运算
在形态学运算中,还定义了另外了两个运算:
- 开运算:先腐蚀图像,再膨胀图像,同样需要一个kernel。
- 闭运算:先膨胀图像,再腐蚀图像,同样需要一个kernel。
opencv中的形态学运算
opencv中除了提供了腐蚀,膨胀这些基本函数之外,还弄了一个综合函数:cv2.morphologyEx
这个函数可以对图像进行各种形态学操作,由其中一个参数op确认,可执行的运算列表根据枚举量MorphTypes确定:
官网上的这张图像说的非常的明白。
其他的参数和腐蚀和膨胀基本类似。
距离计算——distanceTransform函数
cv2.distanceTransform这个函数计算了一幅图像当中每个点与最近的0像素点之间的距离,如果本身像素为0,那么就等于0.
-
关于距离的定义,可以有三种选项(opencv官网)
-
还有一个参数是maskSize,我理解是在哪个范围之内进行计算,官网上也是提供了三个选项:
如果是DIST_MASK_PRECISE的话,就是在整张图中进行计算。
-
具体是用什么算法优化和减少计算量,官网上也提供了文献,有兴趣的朋友可以去了解了解。
连通域
连通域是图像运算中的一个重要概念,就是判断两个区域是否是连接的。
连通的定义
首先,两个像素怎么才叫连通,这个是可以定义的,比如两个像素像素值相同算连通,或者说两者相差不超过N之类。
其次,一个像素和周边的像素比较的时候,一般有下面几种方式。
- 4连通,像素和周边的四个像素点进行比较(按照上面的规则进行比较),就是上、下、左、右四个像素点。如果4个点都是与当前像素点相连通,那么说这几个像素点组成的区域就是一个4连通区域,很多区域生长算法就是以这个为标准来进行计算和生长的。
- 或者反过来说,一个区域是一个4连通区域的话,这个区域中的像素点与其周边的四个像素点都是连通的(最外边的一圈除外)
- 8连通,和上面的类似,就是像素点的8个邻域像素点都是连通的。
计算连通域——connectedComponents
这个函数就是用来做连通域计算的,有如下的参数:
-
image: 图像,单通道的8位图像。
-
connectivity,使用4连通还是8连通。直接填4或者8.
-
ltype,返回的图像数据(在返回值那里说)使用CV_32S或者CV_16U。
-
ccltype,实用计算连通域的算法(我的python版本好像没有这个入参):
每一种都有对应的论文去阐述,不细说。
返回值有两个:
- ret,返回有几个连通域,就是上面的ltype
- labels,连通域的图像。实际上,计算的结果就是给输入图像的每个区域打个标记,标记一下,这是哪个连通域的。如果标记为0,则为背景。
连通域实验
直接上代码:
img = cv2.imread('/Users/zoulei/files/personal/blog/images/car.jpeg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)cv2.imshow("grey", gray)ret, markers = cv2.connectedComponents(gray)img[markers == 0] = [0, 0, 0]#就直接使用三原色对不同的连通域进行涂色
colors = [[255, 0, 0],[0, 255, 0],[0, 0, 255]
]for i in range(1, ret+1):# python中的特有方式,好用的很img[markers == i] = colors[i % 3]cv2.imshow("component", img)
结果如下:
结果不太理想,还需要别的动作。不是这篇的重点,后续再说
基于区域的分割
区域生长算法
基于区域的分割逻辑上比较简单,就是需要分割出来的区域理论上来说,其中的像素值是相似的,或者说是有关联的。那么算法可以引入一个先验知识,或者说一个前提,算法的初始条件中就需要增加一个:种子点。
这个种子点就是从各个需要分割区域中挑选出来的点(通过各种手段,可以是手动,可以是自动,后续会详细讲到)来根据相似性进行扩展(生长),一直生长到区域的边缘为止(停止生长)。
所以区域生长算法的几个关键问题就是:
- 如何挑选生长点
- 如何确定生长原则
- 如何确定生长停止条件
各种各样的算法就是针对这三个问题提出各自的解决方案。
自定义一个最简单区域生长算法实现
为了理解这个算法,我弄了一个最简单区域生长。
- 固定一个点作为种子节点
- 往四个方向生长,只要像素差值小于20就生长,而且生长规则是直接赋值
- 停止规则也很简单,100个迭代
代码如下:
if __name__ == '__main__':img = cv2.imread("/Users/zoulei/files/personal/blog/images/tubeImg.jpeg")grey = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)cv2.imshow("origin", grey)# 随便挑一个点作为种子点point_x = 100point_y = 100grey[point_x, point_y] = 255# 四个生长方向# 如果差值超过20就停下# 暂时先生成20个迭代for i in range(100):if grey[point_x - i, point_y] - 255 < 20:grey[point_x - i, point_y] = 255if grey[point_x + i, point_y] - 255 < 20:grey[point_x + i, point_y] = 255if grey[point_x, point_y - i] - 255 < 20:grey[point_x, point_y - i] = 255if grey[point_x, point_y + i] - 255 < 20:grey[point_x, point_y + i] = 255cv2.imshow("changed", grey)cv2.waitKey()cv2.destroyAllWindows()
输出的图像为:
也就是说,通过4个方向的简单生长变成了一个十字形的区域,或者说分割出了一个十字形的区域。
我们可以通过修改种子点,生长规则和停止规则来确定一种新的区域分割算法,分水岭算法就是其中的一个代表算法,而opencv里提供了函数watershed来实现一种分水岭算法(分水岭算法也有很多种变形,我只说说opencv的实现算法)。
区域分割
一般区域分割
一般来说,可以直接使用连通域函数函数来做区域分割,我们也拿一个硬币图来实验。
当然不能直接使用连通域计算的函数,还需要做一些预处理:
img = cv2.imread('/Users/zoulei/files/personal/blog/images/coin.jpg')grey = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)ret, thresh_img = cv2.threshold(grey, 50, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))opening = cv2.morphologyEx(thresh_img, cv2.MORPH_OPEN, kernel, iterations=2)ret, markers = cv2.connectedComponents(opening)for i in range(1, ret+1):# python中的特有方式,好用的很img[markers == i] = colors[i % 3]
结果不甚理想:
感觉是最下面两个分成了两个区域,多膨胀几次试试看:
img = cv2.imread('/Users/zoulei/files/personal/blog/images/coin.jpg')grey = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)ret, thresh_img = cv2.threshold(grey, 50, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))opening = cv2.morphologyEx(thresh_img, cv2.MORPH_OPEN, kernel, iterations=2)dialate = cv2.dilate(opening, kernel, iterations=3)ret, markers = cv2.connectedComponents(dialate)for i in range(1, ret+1):# python中的特有方式,好用的很img[markers == i] = colors[i % 3]
很明显,如果两个区域隔的比较近,一膨胀就容易让两个区域变成一个连通域。那么针对这种两个区域有比较接近的边界的情况,有一种区域生长算法是叫做分水岭算法。
opencv中的分水岭算法
watershed函数有两个参数:
- imgage, 输入图像,一个3通道图。
- marker,单通道的图像,有点类似于掩膜的作用,具体的作用我们下面会具体讲到。
分水岭算法原理简单说明
首先说一下,为什么要用分水岭算法,我一直有个疑问的是opencv里面提供了connectedComponents函数来计算连通域(也有不同的算法,opencv中提供了参考文献)。那么分水岭算法和那些有什么区别呢?我个人的理解是在需分割区域的边界比较接近的时候比较有用,就和我上面提到的例子一样,一般来说用基于区域的算法进行分割的时候,通常会使用膨胀算法对内部的杂质或者空洞就行补充,但是如果使用了膨胀,因为分割区域挨的比较近,就会导致变成一个连通区域了。
这个时候就可以用到分水岭算法
分水岭算法的基本逻辑是把整张图像的灰度值或者是像素值想象成一个地形图,灰度值较低的是山谷,或者说盆地;灰度值较高的像素点就是山峰。
- 假设从图像上的盆地开始往图像里注水,水平面慢慢上升就会形成一个一个的水坑或者湖,就是一个一个的区域。
- 当两块水域连接到一起的时候,这里就可以停止注水了,这样就形成了一个边界,就可以完成区域分割操作了。
- 在opencv的分水岭算法中,通过第二个参数marker来给出种子点进行生长。
- opencv的分水岭算法中,是需要基于连通域算法的。
上面是一个基本原理,下面来说说具体的使用。
分水岭算法使用
我们还是使用上面的硬币图来进行实验。
我简单说说我对分水岭算法的理解:
- 上面提到了,分水岭算法是基于连通域算法的基础的。也就是说要通过连通域算法来给图像的每个区域进行编号,这些编号就是给分水岭算法提供的种子点,标记了这些已经是一块一块的区域了。
- 分水岭分割算法的目标是要区分出前景区域和背景区域来。
- 分水岭算法中的markker主要分为三类区域,前景区域(数字标记为1,2,3等等);背景区域,数字标记为-1。unkonwn区域,数字标记为0。这个就是用于解决连通域区域无法很好解决的边界过近,通过膨胀会连在一起的情况。
- 分水岭算法的主要逻辑就是通过确定好一些前景区域(种子点),然后确定一些背景区域,中间模糊的区域就是unknown区域。然后通过注水过程来在模糊区域中找到边界。
根据上面的基本逻辑,详细说说应用分水岭算法的代码:
- 计算背景区域
img = cv2.imread('./images/coin.jpg')grey = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)ret, thresh_img = cv2.threshold(grey, 50, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))opening = cv2.morphologyEx(thresh_img, cv2.MORPH_OPEN, kernel, iterations=2)# 背景区域sure_bg = cv2.dilate(opening, kernel, iterations=2)
上面代码中最后一句是通过一次膨胀来确定背景区域。我是这么理解这个代码的,通过一次threshold的区域分割后,基本上已经将前景区域大致轮廓找到了,经过一次膨胀后,就会比目标区域的范围更大,就可以把这样的一个区域称作为背景区域。
显示出来看一下:
很明显是比目标区域宽一些了。
- 计算前景区域
# 前景区域dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 5)ret, sure_fg = cv2.threshold(dist_transform, 0.2 * dist_transform.max(), 255, cv2.THRESH_BINARY)
这几句代码我理解了一阵子。
distanceTransform函数计算的就是图像中离0最近的像素点的距离。
那么上面的第一句代码计算得到的就是经过开运算之后的前景区域离后面的黑色背景区域的距离。
配合下一句代码的threshold函数,对计算的距离进行阈值运算,就是如果是小于距离最大值的0.2的点就为像素值0,否则则是255.
这两句可以理解为就是缩小开运算之后的目标区域,这部分区域确定为前景区域。
显示出来看一下就是:
区域小多了。那么实际上的边界就会存在于这个前景和背景之间!分水岭算法的任务就是要在这个区域中找到真实的边界。
- 在unknown区域中应用分水岭算法找到边界
fg和bg的中间范围就是上面逻辑中提到的unknown区域,也就是不确定区域。
显示出来结果如下:
sure_fg = np.uint8(sure_fg)
unknown = cv2.subtract(sure_bg, sure_fg)ret, markers = cv2.connectedComponents(sure_fg)markers[unknown == 255] = 0markers = cv2.watershed(img, markers)img[markers==-1] = [0, 0, 255]
- 上面的代码中,用bg图减去fg图就是中间区域。
- 然后通过连通域算法得到前景区域中的区域标记。
- markers[unknown == 255],这句代码就是通过把unknown这个mat中等于255的,在marker这个mat的标记中标记为0.还记得上面提到的逻辑么,0就表示unknown区域。
- 最后应用watershed算法。
- 最后一句,watershed算法计算完成后,marker中为-1的像素值就是边界(marker的尺寸和原图一样)
最终的结果如下:
通过分水岭算法就可以较为准确的找到边界。
当然上图中还有一些多余的分割线,我觉得是可以通过对上面的unknown区域做一些改进和处理,是可以去除掉这些分割线的,这里就不在这里多说了。有兴趣的朋友也可以自行尝试。
相关文章:
python的opencv操作记录13——区域生长及分水岭算法
文章目录图像区域基本算法——形态学运算腐蚀与膨胀开运算与闭运算opencv中的形态学运算距离计算——distanceTransform函数连通域连通的定义计算连通域——connectedComponents连通域实验基于区域的分割区域生长算法自定义一个最简单区域生长算法实现区域分割一般区域分割open…...
一文看懂网上下单的手机流量卡为什么归属都是随机的!
最近很多网上下单的小伙伴们心中似乎都有一个疑问。那就是网上很多手机卡、流量卡都不能自选号码和归属地,就算能自选号码,归属地也是随机的而且很多都不会跟你说具体的城市,这是为什么呢?莫非其中有什么不可告人的秘密吗?小伙伴…...
python Pytest生成alluer测试报告的完整教程
1.下载allure包到本地,解压 网上很多资料,这边不提供了 2.配置环境变量 将上面解压后bin文件的路径复制,添加到环境变量Path下 3.验证环境变量配置是否功 在cmd中输入allure,回车 。查看allure是否成功: 4.pyc…...
4-spring篇
ApplicationContext refresh的流程 12个步骤 prepareRefresh 这一步创建和准备了Environment对象,并赋值给了ApplicationContext的成员变量 要理解Environment对象的作用 obtainFreshBeanFactory ApplicationContext 里面有一个成员变量,Beanfactory b…...
提升 Web 应用程序的性能:如何使用 JavaScript 编写缓存服务
缓存是一种重要的优化技术,用于加速数据访问和降低服务器负载。缓存存储经常访问的数据,以便在需要时可以快速检索。在本文中,我们将探索如何使用简单的数据结构在 JavaScript 中编写缓存服务。 编码缓存服务的第一步是定义将用于访问缓存的…...
供应商绩效管理指南:挑战、考核指标与管理工具
管理和优化供应商绩效既关键又具有挑战性。要知道价格并不是一切,如果你的供应商在商定的价格范围内向你开具发票,但服务达不到标准或货物不合格,你也无法达到节约成本的目标。 供应商绩效管理可以深入了解供应商可能带来的风险,…...
干货文稿|详解深度半监督学习
分享嘉宾 | 范越文稿整理 | William嘉宾介绍Introduction to Semi-Supervised Learning传统机器学习中的主流学习方法分为监督学习,无监督学习和半监督学习。这里存在一个是问题是为什么需要做半监督学习?首先是希望减少标注成本,因为目前可以…...
信箱|邮箱系统
技术:Java、JSP等摘要:在经济全球化和信息技术飞速发展的今天,通过邮件收发进行信息传递已经成为主流。目前,基于B/S(Browser/Server)模式的MIS(Management information system)日益…...
JS数组拓展
1、Array.from Array.from 方法用于将两类对象转为真正的数组: 类似数组的对象,所谓类似数组的对象,本质特征只有一点,即必须有length属性。 因此,任何有length属性的对象,都可以通过Array.from方法转为数组 和 可遍历…...
一道很考验数据结构与算法的功底的笔试题:用JAVA设计一个缓存结构
我在上周的笔试中遇到了这样一道题目,觉得有难度而且很考验数据结构与算法的功底,因此Mark一下。 需求说明 设计并实现一个缓存数据结构: 该数据结构具有以下功能: get(key) 如果指定的key存在于缓存中,则返回与该键关联的值&am…...
(10)C#传智:命名空间、String/StringBuilder、指针、继承New(第10天)
内容开始多了,慢品慢尝才有滋味。 一、命名空间namespace 用于解决类重名问题,可以看作类的文件夹. 若代码与被使用的类,与当前的namespace相同,则不需要using. 若namespace不同时,调用的方法:…...
基于Jetson Tx2 Nx的Qt、树莓派等ARM64架构的Ptorch及torchvision的安装
前提 已经安装好了python、pip及最基本的依赖库 若未安装好点击python及pip安装请参考这篇博文 https://blog.csdn.net/m0_51683386/article/details/129320492?spm1001.2014.3001.5502 特别提醒 一定要先根据自己板子情况,找好python、torch、torchvision的安…...
MySQL存储引擎详解及对比和选择
什么是存储引擎? MySQL中的数据用各种不同的技术存储在文件(或者内存)中。这些技术中的每一种技术都使用不同的存储机制、索引技巧、锁定水平并且最终提供广泛的不同的功能和能力。通过选择不同的技术,你能够获得额外的速度或者功能,从而改善…...
【推拉框-手风琴】vue3实现手风琴效果的组件
简言 在工作时有时会用到竖形手风琴效果的组件。 在此记录下实现代码和实现思路。 手风琴实现 结构搭建 搭建结构主要实现盒子间的排列效果。 用flex布局或者其他布局方式将内容在一行排列把每一项的内容和项头用盒子包裹, 内容就是这一项要展示的内容…...
滑动窗口最大值:单调队列
239. 滑动窗口最大值 难度困难2154收藏分享切换为英文接收动态反馈 给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回 滑动窗口中的最大值 。 示例…...
负载均衡算法
静态负载均衡 轮询 将请求按顺序轮流地分配到每个节点上,不关心每个节点实际的连接数和当前的系统负载。 优点:简单高效,易于水平扩展,每个节点满足字面意义上的均衡; 缺点:没有考虑机器的性能问题&…...
C语言数组二维数组
C 语言支持数组数据结构,它可以存储一个固定大小的相同类型元素的顺序集合。数组是用来存储一系列数据,但它往往被认为是一系列相同类型的变量。 数组的声明并不是声明一个个单独的变量,比如 runoob0、runoob1、…、runoob99,而是…...
7年测试工程师,裸辞掉17K的工作,想跳槽找更好的,还是太高估自己了....
14年大学毕业后,在老师和朋友的推荐下,进了软件测试行业,这一干就是7年时间,当时大学本来就是计算机专业,虽然专业学的一塌糊涂,但是当年的软件测试属于新兴行业,人才缺口比较大,而且…...
企业为什么需要做APP安全评估?
近几年新型信息基础设施建设和移动互联网技术的不断发展,移动APP数量也呈现爆发式增长,进而APP自身的“脆弱性”也日益彰显,这对移动用户的个人信息及财产安全带来巨大威胁和挑战。在此背景下,国家出台了多部法律法规,…...
重回利润增长,涪陵榨菜为何能跑赢周期?
2022年消费市场持续低迷,疫情寒冬之下,不少食品快消企业均遭遇严重的业绩下滑,但一年里不断遭遇利空打击的“榨菜茅”涪陵榨菜,不仅安然躲过“酸菜劫”、走出“钠”争议,而且顺利将产品价格提起来,并在寒冬…...
这6个高清图片素材库,马住,马住~
网上找的图片素材清晰度不够,版权不明确怎么办。看看这几个可商用图片素材网站,解决你的所有图片需求,高清无水印,赶紧马住! 1、菜鸟图库 美女图片|手机壁纸|风景图片大全|高清图片素材下载网 - 菜鸟图库 网站素材…...
绝对零基础的C语言科班作业(期末模拟考试)
编程题(共10题; 共100.0分)模拟1(输出m到n的素数)从键盘输入两个整数[m,n], 输出m和n之间的所有素数。 输入样例:3,20输出样例:3 5 7 11 13 17 19 (输出数据之间用空格间…...
注解开发定义bean
注解开发定义bean 使用Component定义bean在核心配置文件中通过组件扫描加载bean,需要指定扫描包的范围 当然也可以使用Component的衍生注解,可以更加形象的表示 纯注解的开发模式 使用java类来代替了以前的 配置文件,在java类中ÿ…...
剑指 Offer 19. 正则表达式匹配
摘要 剑指 Offer 19. 正则表达式匹配 请实现一个函数用来匹配包含. 和*的正则表达式。模式中的字符.表示任意一个字符,而*表示它前面的字符可以出现任意次(含0次)。在本题中,匹配是指字符串的所有字符匹配整个模式。例如&#x…...
CSS——学成在线案例
🍓个人主页:bit.. 🍒系列专栏:Linux(Ubuntu)入门必看 C语言刷题 数据结构与算法 HTML和CSS3 目录 1.案例准备工作 2.CSS属性书写顺序(重点) 3.页面布局整体思路 4.头部的制作编辑 5.banner制作…...
元数据的类型
元数据通常分为三种类型:业务元数据、技术元数据和操作元数据。这些类别使人们能够理解属于元数据总体框架下的信息范围,以及元数据的产生过程。也就是说,这些类别也可能导致混淆,特别是当人们对一组元数据属于哪个类别或应该由谁…...
LEAP模型的能源环境发展、碳排放建模预测及不确定性分析
LEAP(Long Range Energy Alternatives Planning System/ Low emission analysis platform,长期能源可替代规划模型)是一种自下而上的能源-环境核算工具,由斯德哥尔摩环境研究所和美国波士顿大学联合研发。该模型与情景分析法紧密结…...
C# Task详解
1、Task产生背景 Task出现之前,微软的多线程处理方式有:Thread→ThreadPool→委托的异步调用,虽然也可以基本业务需要的多线程场景,但它们在多个线程的等待处理方面、资源占用方面、线程延续和阻塞方面、线程的取消方面等都显得比…...
Blob分析+特征
Blob分析特征0 前言1 概念2 方法2.1 图像采集2.2 图像分割2.3 特征提取3 主要应用场景:0 前言 在缺陷检测领域,halcon通常有6种处理方法,包括Blob分析特征、Blob分析特征差分、频域空间域、光度立体法、特征训练、测量拟合,本篇博…...
4EVERLAND 的 IPFS Pinning 服务:4EVER Pin
我们很高兴地宣布 4EVERLAND Storage 的一个令人兴奋的补充,即 4EVER Pin。什么是 4EVER Pin?您可能已经知道星际文件系统或IPFS是一个分布式存储网络,来自世界各地的计算机组成节点共享数据。通常,在IPFS中获取一条数据时&#x…...
专业网站建设必要性/药品网络营销公司
粘包产生原因: 先说TCP:由于TCP协议本身的机制(面向连接的可靠地协议-三次握手机制)客户端与服务器会维持一个连接(Channel),数据在连接不断开的情况下,可以持续不断地将多个数据包发…...
厦门网站建设外包/中国国家人事人才培训网证书查询
某些查询条件确定范围between and,not between and确定集合in,not in字符匹配like,not like空值is null,is not null多重条件and,or,not1。确定范围 查询年龄在(不在)21到24之间的学…...
用dw怎么做网站/淘宝权重查询入口
背景 在上午探索了Windows下时间任务创建运行的可视化界面和Schtasks命令行工具且默默失败后,下午我决定不依不饶地去看一下Linux系统下是怎么创建时间任务的。其实我Linux接触得不多,而且今天也是新接触的crontab命令,所以不免会踩坑踩雷&am…...
莱西做网站/长沙关键词快速排名
无意间看到了我仍旧在这里的《每天一点canvas动画》的系列文章(表示感谢),"粒子文字" 这节感觉很不错,研究了一下,因为原作者加入了几个与用户交互的属性可动态改变粒子文字动画的样式,且代码也抽…...
携程网站的会计工作怎么做/百度网站官网
iOS 14.3 Beta2距离苹果推送 iOS 14.3 首个测试版时隔 5 天,苹果今天又向参与测试的 iPhone 设备推送 iOS 14.3 Beta2 更新。这次的更新包比较小,只有 390MB 左右,更新后的版本号为 18C5054c,单纯地从版本号的后缀来看,…...
张店党风廉政建设网站/百度收录刷排名
题库来源:安全生产模拟考试一点通公众号小程序 2020年美容师(中级)考试题及美容师(中级)多少分及格,包含美容师(中级)考试题答案和解析及美容师(中级)多少分…...