计算机视觉(OpenCV+TensorFlow)
计算机视觉(OpenCV+TensorFlow)
文章目录
- 计算机视觉(OpenCV+TensorFlow)
- 前言
- 3.图像金字塔
- 3.1 高斯金字塔
- 3.2 拉普拉斯金字塔
- 4.图像轮廓
- 图像边缘和图像轮廓的区别
- 检测图像
- 绘制边缘
- 5.轮廓近似
- 外接矩形
- 外接圆
- 6. 模板匹配
- 6.1 什么是模板匹配
- 总结
前言
本系列文章是OpenCV系列文章的第三篇,仍然跟随上篇内容主要聚焦于图像的一些操作
3.图像金字塔
在通常情况下我们使用大小恒定的图像。但在某些情况下,我们需要使用不同分辨率的同幅图像,例如,在搜索图像中的某些内容比如脸部信息时,并不确定该内容在图像中占据的大小。这种情况下,我们需要创建一组不同的分辨率的相同图像,并在所有图像中搜索该内容。这些不同分辨率的图像被称为图像金字塔(因为当它们堆叠排列时,底部为最高分辨率图像而顶部为最低分辨率图像,看起来像金字塔)
**图像金字塔主要有两种:**
- 高斯金字塔
- 拉普拉斯金字塔
3.1 高斯金字塔
向上采样:在图像金字塔中,越靠下的分辨率越大,所以向上采样指的是从分辨率大的图像中得到分辨率小的图像
方法:
- 将图像与下方的高斯核进行卷积,就是我们前几次一直说的对应位置相乘最后都加在一起从而代替中间像素的那个值
- 将所有偶数行和偶数列去除。
为什么要先卷积再去除呢:
是因为如果直接去除偶数行和偶数列,那势必会导致大量数据的丢失,如果我们先卷积,卷积后的值是它周围的值共同作用的,所以卷积后再去除损失的数据量比直接去除要小很多,但是还是会少一部分数据
向下采样:在图像金字塔中,越靠上的分辨率越大,所以向下采样指的是从分辨率小的图像中得到分辨率大的图像
**方法: **我们看第一步放大后,有近四分之三的数据都是0,第二部卷积后,实际上是把不是0的数据给分配了一部分给0
那实际上,就是把原有的数据给往四周分散了。那在放大的时候,原来的数据给了其他的,那对应自身来说不也就是丢失了一部分数据。
# 引入图片
img=cv2.imread("AM.png")
cv_show(img,'img')
print (img.shape)
# 向上采样
up=cv2.pyrUp(img)
cv_show(up,'up')
print (up.shape)
# 向下采样
down=cv2.pyrDown(img)
cv_show(down,'down')
print (down.shape)
**而为了让数据尽量的少丢失点,我们又有了拉普拉斯金字塔。 **
3.2 拉普拉斯金字塔
https://blog.csdn.net/ftimes/article/details/106731558
** 在高斯金字塔中,我们提到了上采样和下采样。但是无论是上采样还是下采样都会丢失像素值,所以这两种操作并不是可逆的。也就是说,对一幅图先进行上采样再进行下采样,是无法恢复到原始状态。同样,先下采样再上采用也无法恢复到原始状态**
因此我们引入了拉普拉斯金字塔(The Laplacian pramid)
简而言之,拉普拉斯金字塔的第 i 层,是由【高斯金字塔的第 i 层】 与 【高斯金字塔中的第 i+1 层的向上采样结果】之差。
简单来说,拉普拉斯金字塔是一个 高斯差值金字塔,下面这个图就是一个拉普拉斯每一层的流程
下面这个图简化了上图的流程,我们从后往前看,G3向上取样后,G2减去它就是 L2。
而 G3加上L2就是G2。因为L2=G2-G3向上
up=cv2.pyrUp(img)
up_down=cv2.pyrDown(up)
cv_show(img-up_down,'img-up_down')
4.图像轮廓
图像边缘和图像轮廓的区别
** 前面我们在图像形态学操作里,用cv2.morphologyEx()这个函数实现图像梯度的提取,用膨胀图像-腐蚀图像,获取一个图像中前景图像的边缘。还有我们的礼帽和黑帽一定程度也能提取图像的边缘信息。依旧我们在图像梯度中详细讲过的 sobel算子,scharr算子,laplasian算子,canny边缘检测,这些都是检测图像中边缘线条的。**
** 而本章讲的是图像轮廓,图像轮廓和图像边缘不少一回事,图像边缘不少图像轮廓!!!!图像边缘是图像中的线条,这些线条是不连续的,零散的线段,只要是由梯度,把由梯度的像素点提取出来就可以了,这是边缘检测的操作手法。而图像轮廓首先要是一个整体的,就是将边缘连接起来形成一个整体,这才叫轮廓。**
** 边缘检测主要是通过一些手段检测数字图像中明暗变化剧烈(即梯度变化比较大)像素点,偏向于图像中像素点的变化。如Canny边缘检测,结果通常保存在和原图片一样尺寸和类型的边缘图中。轮廓检测指检测图像中的对象边距,更偏向于关注上层语义对象,主要用来分析物体的形态,比如物体的周长和面积等。可以说 边缘包括轮廓。**
** 边缘主要是作为图像的特征使用,比如可以用边缘特征可以区分脸和手,而轮廓则是一个很好的图像目标的外部特征,这种特征对于我们进行图像分析,目标识别和理解等更深层次的处理都有很重要的意义**
检测图像
在OpenCV中,我们用 image, contours, hierarchy = **cv2.findContours(img,mode,method) **这个函数来得到轮廓
- img:要做轮廓检测的图像,必须是8位单通道二值图像。所以,一般情况下我们都是将图像处理位二值图像后再将其作为参数传入。在很多情况下,我们是预先对图像进行阈值分割或者边缘检测处理(比如经过Canny,拉普拉斯等边缘检测算子处理过的二值图像),在得到满意的二值图像后再作为参数传入使用,这样效果会更好。
- mode:轮廓检索模式。均可了轮廓的提取方式:
- cv2.RETR_EXTERNAL:只检测最外面的轮廓
- cv2.RETR_LIST:减少所有的轮廓,并将其保存到一条链表当中,对检测到的轮廓不建立等级关系
- cv2.RETR_CCOMP:检索所有轮廓并将它们组织成两级层次结构。顶层是各部分的外部边界,第二层是空洞的边界。
- cv2.RETR_TREE:检索所有轮廓,并建立一个等级树结构的轮廓,就是重构嵌套轮廓的整个层次
- 说明:一般情况下,我们只用第4种模式,因为第4种模式是检测所有的轮廓,并且把这些轮廓按层次保存成一个树结构,后面如果我们有需要直接调用即可。
- method:轮廓逼近方法,就是如何表达轮廓,意思就是我是用线表示轮廓呢?还是简单的用2个点就表示一条线的轮廓:
- cv2.CHAIN_APPROX_NONE:以 Freeman 链码的方式输出轮廓,意思就是我存储了所有的轮廓点,就是相连两个点的像素位置差不超过 1 ,我可以用完整的线条来表示轮廓,就是我可以画出一个完整的轮廓。
- cv2.CHAIN_APPROX_SIMPLE:压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标。比如一个矩形只用4个点就可以表示。同理如果是一个多边形,我们就输出这个多边形的订单序列
函数返回值:
- image:与参数img的尺寸一致的。后面高版本的opencv已经不返回这个对象
- contours:是返回的轮廓。这个轮廓是一个数组
- hierachy:是轮廓的层次信息,就是mode参数决定的返回的轮廓数据的组织结构
- 说明:在opencv中,我们都是从黑色背景种查找白色对象,因此,对象必须是白色的,背景必须是黑色的
使用轮廓检测函数 cv2.findContours()要注意的点:
- 我们检测一张彩图的轮廓是,首先我们要把彩图转换为灰度图像,然后我们用阈值函数把灰度图像处理成二值图像,此时才能作为参数 img 传入到函数中
- 我们检测轮廓的时候,一张图片可能有多个轮廓,也可能有一个轮廓礼貌套几个轮廓(就是空洞)所以我们要明确我们想要检测几级轮廓。
- 当我们只想检测最外面的一层轮廓时,参数 mode=cv2.RETR_EXTERNAL
- 当我们像检测所有的轮廓(就是轮廓里面套轮廓,可以嵌套多层)时,参数mode可以选择其他三种
- cv2.RETR_LIST是把所用的轮廓放到一起,不区分轮廓之间的等级关系
- cv2.RETR_CCOMP是把所有的轮廓分2级
- cv2.RETR_TREE是建立一个树结构的层次关系
- 当我们轮廓检测完毕后,不管是检测一个轮廓还是检测所有的轮廓,检测所有轮廓不管是保存轮廓之间的等级关系还是不保存,我们的轮廓本身数据可以有两种方式存储,、
- cv2.CHAIN_APPROX_NONE:就是保存轮廓的所有像素点,此时返回的 contours可视化处理后就是轮廓线。
- cv2.CHAIN_APPROX_SIMPLE:就是表示我们轮廓数据不是连续的像素点而是轮廓的顶点序列,此时我们可视化 contours时就是一些顶点,就是轮廓的顶点,不是线。
- countours的属性:
- len(contours)返回的就是我们检测到了几个轮廓
- len(contours[i])返回第 i 个轮廓长度,就是它有多少个像素点
- contours[i].shape返回的就是轮廓内点的形状,比如(4,1,2)就表示轮廓 i 有4个轮廓点,每个点是1行两列
- [[79,270]] [[79,383]]** [[195,383]]** [[195, 270]] 这其实就是一个方框轮廓的4个点的坐标值。**
- hierarchy是我们检测到的轮廓的等级关系的数据,这个数据可以反映我们的轮廓之间是如何连接的。
绘制边缘
轮廓绘制函数:cv2.drawContours(img, contours, contourIdx, color [ thickness, lineType, hierarchy, maxLevel, offset] )
- img:待绘制轮廓的图像
- contours:需要绘制的轮廓,这个参数就是 findContours()的输出
- contourldx:需要绘制的轮廓的索引号,如果 contourldx=-1,表示绘制全部轮廓;如果这个参数是零或者正整数,表示要绘制的轮廓是对应的索引号的轮廓
- color:绘制的颜色,用 BGR 表示
- thickness:表示轮廓的粗细,如果 thickness=-1则表示要绘制实心轮廓
- lineType:轮廓的线条形状
- hierarchy:cv2.findContours()返回的层次信息。
- maxLevel:要绘制的轮廓的偏移到不同的位置展示出来
注意:由于该函数是在 img 的基础上绘制的,不会再重新生成一个带轮廓的新对象,所有这个函数是在原图中绘制的。所以我们要保存原图
轮廓检测步骤小结:
- 当我们拿到的原图是一张彩色图的时候,第一步我们要把彩色图变成灰度图
- 把灰度图用阈值函数处理成二值图像
- 检测轮廓
- 绘制轮廓
# 导入图片
img = cv2.imread('contours.png')
# 彩色图转灰色图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 灰色图转二值图
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
cv_show(thresh,'thresh')
# 检测轮廓
binary, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
# 画轮廓
draw_img = img.copy()
res = cv2.drawContours(draw_img, contours, -1, (0, 0, 255), 2)
cv_show(res,'res')
5.轮廓近似
我们看下面这个图片,它不是一个规则的图形,是一个不规则的图形,如果要精确的描述轮廓的话就是第三幅图
如果像要近似的表示的话,就是第二幅图,用一个矩形就可以表示
https://blog.csdn.net/SSJJRRRR/article/details/108478898
那OpenCV的 approxPolyDP 函数就可以实现这个功能。
approxPolyDP函数使用了 Douglas-Peucker算法:
- 先从轮廓中找出两个最远的点,将两点相连,即 b-c ;
- 在原来的轮廓上查找一个里线段距离最远的点,将该点加入逼近后的新轮廓中,即 c-d ;
- 然后重复前面的算法,不断迭代,将最远的点添加进来,直到所有的点到多边形的最短距离小于指定的精度
在OpenCV中 cv2.approxPolyDP(cnt,epsilon,True) 就是用来得到近似轮廓
cnt 就是 findContours函数得到的 contours
epsilon就是精度
最后一个布尔值:如果为true,则闭合近似曲线(其第一个和最后一个顶点为连接的);否则,不闭合。
# 导入图片
img = cv2.imread('contours2.png')
# 转成灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 转为二值图
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
# 检测轮廓
binary, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
cnt = contours[0]
# 画出轮廓
draw_img = img.copy()
res = cv2.drawContours(draw_img, [cnt], -1, (0, 0, 255), 2)
cv_show(res,'res')
# arcLength轮廓的周长,epsilon是精度
epsilon = 0.15*cv2.arcLength(cnt,True)
# 得到近似轮廓
approx = cv2.approxPolyDP(cnt,epsilon,True)
# 画出轮廓
draw_img = img.copy()
res = cv2.drawContours(draw_img, [approx], -1, (0, 0, 255), 2)
cv_show(res,'res')
外接矩形
x,y,w,h=boundingRect(cnt)
cnt 就是一个轮廓,x,y是矩形的左上角坐标,而(w,h)为矩形的宽度和高度
img = cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
img:画轮廓的图片
(x,y):矩形的左上角的坐标
(x+w,y+h):矩形的右下角的坐标
(0,255,0):颜色 BGR
2:线条宽度
# 引入坐标
img = cv2.imread('contours.png')
# 转为灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 转为二值图
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
# 检测轮廓
binary, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
cnt = contours[0]
# 找到外接矩形的信息
x,y,w,h = cv2.boundingRect(cnt)
# 画矩形
img = cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
cv_show(img,'img')
外接圆
(x,y),radius = cv2.minEnclosingCircle(cnt)
cnt:就是一个轮廓
(x,y):圆心坐标
radius:半径
img = cv2.circle(img,center,radius,(0,255,0),2)
参数基本上与外接矩形都差不多
(x,y),radius = cv2.minEnclosingCircle(cnt)
center = (int(x),int(y))
radius = int(radius)
img = cv2.circle(img,center,radius,(0,255,0),2)
cv_show(img,'img')
6. 模板匹配
6.1 什么是模板匹配
https://blog.csdn.net/m0_37579176/article/details/116950903
模板匹配可以看作是对象检测的一种非常基本的形式。使用模板匹配,我们可以使用包含要检测对象的”模板“来检测输入图像中的对象。
也就是说,我们需要两个图像来应用模板匹配:
- 源图像:这是我们希望在其中找到的与模板匹配的图像
- 模板图像:我们要搜索的图像
为了在源图像中找到模板图像,我们在源图像中从左到右和从上到下依次滑动模板:
应用模板匹配,就像在源图像上从左到右,从上到下滑动模板,在每一个位置都计算一个指标以表明这个位置处两个图像块之间匹配程度的高低
在每个(x,y)位置,都会计算一个度量来表示匹配的“好”或“坏”。通常,我们使用归一化的相关系数来确定两个图像块之间像素强度有多“相似”
相关系数有很多计算方式。‘
对于模板 T 在源图像 I 上的每个位置,取两者重合部分的图像块,计算相似度度量结果,存储在结果矩阵 R 中。源图像中的每个(x,y)坐标在结果矩阵 R 中包含一个条目,除非模板越界
下图就是结果矩阵与源图像重叠后的图像
在这里,我们可以可视化叠加在原始图像上的结果矩阵R。注意R与原始模板大小不相同。这是因为整个模板必须在源图像的内部滑动,得到等大的两个图像块,才能计算相关性。如果模板超出了源的边界,我们将不计算相似性度量。
结果矩阵中 R 最亮的位置表示最佳匹配位置,而暗区表示该点源图像和模板图像之间的相关性很小
当模板图像中的水杯,与源图像中的水杯,两者完全重合的时候,模板图像左上角所在的源图像位置,存储的是模板与源图像相似的的最大值。
但是我们需要确保要检测的模板与源图像中检测的对象几乎完全相同。即使外观很小的偏差也会极大地影响匹配的结果。
在OpenCV中我们可以使用 cv2.matchTemplate()进行模板匹配,这个函数有三个参数:
- 输入图像:包含我们要检测的对象的图像
- 模板图像:对象的图像
- 模板匹配方法
- TM_SQDIFF:计算平方不同,计算出来的值越小,越相关
- TM_CCORR:计算相关性,计算出来的值越大,越相关
- TM_CCOEFF:计算相关系数,计算出来的值越大,越相关
- TM_SQDIFF_NORMED:计算归一化平方不同,计算出来的值越接近0,越相关
- TM_CCORR_NORMED:计算归一化相关性,计算出来的值越接近1,越相关
- TM_CCOEFF_NORMED:计算归一化相关系数,计算出来的值越接近1,越相关
另外值得注意的是,如果您只想检测模板图像上的特定区域,则可以为模板图像提供一个掩膜,如下所示:
**result = cv2.matchTemplate(image, template, cv2.TM_CCOEFF_NORMED, mask) **
掩膜,即为模板图像上感兴趣的区域,用于忽略模板图像上无用的干扰的特征,即不属于检测目标的干扰特征。对于模板上你不希望被搜索的区域,掩膜值应该设置为0。对于模板图像上您要进行搜索的区域,掩膜值应该设置为255。掩膜与模板图像具有相同的维度,并且每个元素的类型也需要一致。
# 引入源图像
img = cv2.imread('lena.jpg', 0)
# 引入模板图像
template = cv2.imread('face.jpg', 0)
# 模板匹配
res = cv2.matchTemplate(img, template, cv2.TM_SQDIFF)
# 得到最大的像素点和最小的像素点的值和坐标
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
# 根据方法选择最大值或最小值的坐标
# 如果是平方差匹配TM_SQDIFF或归一化平方差匹配TM_SQDIFF_NORMED,取最小值
if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:top_left = min_loc
else:top_left = max_loc
bottom_right = (top_left[0] + w, top_left[1] + h)
# 画矩形
cv2.rectangle(img2, top_left, bottom_right, 255, 2)
总结
这次紧接者上篇内容再一次讲解了一些有关图像的操作,预计还需要一期把图像操作讲个差不多后,进入实战环节,将上述图像内容,通过实战进行一个强化训练
我是Mayphry,从一点点到亿点点,我们下次再见
相关文章:

计算机视觉(OpenCV+TensorFlow)
计算机视觉(OpenCVTensorFlow) 文章目录 计算机视觉(OpenCVTensorFlow)前言3.图像金字塔3.1 高斯金字塔3.2 拉普拉斯金字塔 4.图像轮廓图像边缘和图像轮廓的区别检测图像绘制边缘 5.轮廓近似外接矩形外接圆 6. 模板匹配6.1 什么是…...

shell语法
概论 shell是我们通过命令行与操作系统沟通的语言 shell脚本可以直接在命令行中执行,也可以将一套逻辑组织成一个文件,方便复用。 DA Terminal中的命令行可以看成是一个“shell脚本在逐行执行”。 1.脚本示例 新建一个test.sh文件,内容如…...

JAXB的XmlAttribute注解
JAXB的XmlAttribute注解,将一个JavaBean属性映射到一个XML属性。 例如,下面的Java代码,将属性currency映射到了XML的属性currency: package com.thb;import jakarta.xml.bind.annotation.XmlAttribute; import jakarta.xml.bind…...

【代码】基于改进差分进化算法的微电网调度研究matlab
程序名称:基于改进差分进化算法的微电网调度研究 实现平台:matlab 代码简介:了进一步提升差分进化算法的优化性能,结合粒子群(PSO)算法的进化机制,提出一种混合多重随机变异粒子差分进化算法(DE-PSO)。所提算法不仅使用粒子群差分变异策略和…...

计算机基础知识63
Django的条件查询:查询函数 exclude exclude:返回不满足条件的数据 res Author.objects.exclude(pk1) print(res) # <QuerySet [<Author: Author object (2)>, <Author: Author object (3)>]> order_by 1、按照 id 升序排序 res …...

springboot虚拟请求——测试
springboot虚拟请求 表现层测试 web环境模拟测试 虚拟请求状态匹配——执行状态的匹配 Testvoid testStatus(Autowired MockMvc mvc) throws Exception { // //http://localhost:8080/books// 创建一个虚拟请求,当前访问的是booksMockHttpServletRequestBui…...

计算机视觉各个方向概述
计算机视觉发展很长时间了,由传统的计算机视觉到现在如火如荼的计算机视觉多模态,有很多的方向,每一个方向都是一个研究门类,有些已经比较成熟,有些还处于一个开始的阶段,相对于文本语言的处理,…...

AIGC: 关于ChatGPT中API接口调用相关准备工作
ChatGPT之API接口相关 通过页面和GPT交流获取信息相比直接调用GPT的API而言是非常有限的 页面上的GPT是比较封闭的,而且只允许我们去输入文本的信息 我们需要借助GPT的API开发来激发AI工具的无限可能,实现更多个性化需求 1 )使用API 使用A…...

【Java Web学习笔记】 1 - HTML入门
项目代码 https://github.com/yinhai1114/JavaWeb_LearningCode/tree/main/html 零、网页的组成 HTML是网页内容的载体。内容就是网页制作者放在页面上想要让用户浏览的信息,可以包含文字、图片视频等。 CSS样式是表现。就像网页的外衣。比如,标题字体、…...

基于windows系统使用Python对于pc当前的所有窗口的相关操作接口
对于windows系统的电脑使用Python可以对其当前的窗口进行宏观的查询等操作 派生博客1:python对pc的窗口进行操作(windows) 派生博客2python获取当前pc的分辨率(windows) 派生博客3使用uiautomation模块来对基于windows系统的pc中的前端界面进行自动化测试(查找控件ÿ…...

30秒搞定一个属于你的问答机器人,快速抓取网站内容
我的新书《Android App开发入门与实战》已于2020年8月由人民邮电出版社出版,欢迎购买。点击进入详情 文章目录 简介运行效果GitHub地址 简介 爬取一个网站的内容,然后让这个内容变成你自己的私有知识库,并且还可以搭建一个基于私有知识库的问…...

JPA数据源Oracle异常记录
代码执行异常 ObjectOptimisticLockingFailureException org.springframework.orm.ObjectOptimisticLockingFailureException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1; nested exception is org.hibernate.StaleSta…...

抽奖送平板是骗局!!!
在街上被派传单,然后扫了码抽奖中了平板,被领到卖电器门店兑奖。他们给我在宜嘉商城上充值4980,我现场给他们付了4980元,签了他们的业务办理单,上面有违约者赔款30%违约金字样。我领走了荣耀畅玩40plus手机一台。第二天…...

json.decoder.JSONDecodeError: Extra data: line 1 column 332 (char 331)
项目场景: 提示:扩充数据集时,同步修改json标签中的"imagePath"字段的值,出现json文件读写不一致问题。 采用open函数读写模式修改json文件字段。open(jsonF.json, r)。 问题描述 运行修改json文件报错:j…...

rust持续学习 COW
COW我第一次看见还以为是奶牛 很奇怪是个啥 后来了解到是clone on write 缩写的,大乌龙啊 这个有两种enum,一种是borrow,一种是own rust中,数据读写经常涉及到所有权 这个borrow,很显然,就是不可变借用了 own就是可以写…...

【计算机网络】14、DHCP
文章目录 一、概述1.1 好处 二、概念2.1 分配 IP2.2 控制租赁时间2.3 DHCP 的其他网络功能2.4 IP地址范围和用户类别2.5 安全 三、DHCP 消息3.1 DHCP discover message3.2 DHCP offers a message 如果没有 DHCP,IT管理者必须手动选出可用的 ip,这太耗时了…...

【FPGA】Verilog:计数器 | 异步计数器 | 同步计数器 | 2位二进制计数器的实现 | 4位十进制计数器的实现
目录 Ⅰ. 实践说明 0x00 计数器(Counter) 0x01 异步计数器(Asynchronous Counter)...

IDEA常用快捷键
快捷键功能tab接受选择–选择的名称将覆盖带插入符号右侧的其它名称–而如果按shift或者enter,光标右边的内容会保留Ctrlshift空格智能匹配–查找当前上下文的方法和变量Ctrld对比文件–选中需要对比的文件shift滚动水平滚动Ctrlaltl格式化Ctrlk提交Ctrlaltz回滚类C…...

【2024秋招】2023-10-17 金山云文档服务端二面
1 实习 1.1 讲解一下curd启动器 1.2 数据同步的过程是怎么实现的,同步过程中的数据一致性怎么保证的 答:同步过程中会记录断点,表示每一批同步成功时的位置,如果对端出现问题,则下一次同步会继续从这个断点后开始同…...

一种excel多线程并发写sheet的方案
一、背景 有一次项目的需求要求导出excel,并且将不同的数据分别写到不同的sheet中。 二、 方案概述 首先一开始使用easyexcel去导出excel,结果发现导出时间需要3秒左右。于是想着能不能缩短excel导出时间,于是第一次尝试使用异步线程去查询数…...

深入了解接口测试:揭秘网络分层和数据处理!
网络分层和数据 上一小节中介绍了接口测试中一些必要重要的定义,这一节我们来讨论一下在学习接口测试过程中我们要关注的最重要的东西:网络分层和数据。 首先,我们来尝试理解一下,为什么网络是要分层的呢? 我们可以…...

Java并发编程
进程和线程 进程即程序的一次执行过程,各个进程之间是独立的。线程是更小的单位,一次进程中,可能会有多个线程,可能会相互影响,各个线程有自己的程序计数器,虚拟机栈和本地方法栈,同时共同使用…...

vue+echarts实现依赖关系无向网络拓扑结图节点折叠展开策略
目录 引言 一、设计 1. 树状图(不方便呈现节点之间的关系,次要考虑) 2. 力引导依赖关系图 二、力引导关系图 三、如何实现节点的Open Or Fold 1. 设计逻辑 节点展开细节 节点收缩细节 代码实现 四、结果呈现 五、完整代码 引言 我…...

Unity3d 灯光阴影开启,法线贴图出现BUG
URP项目打开灯光的阴影后,法线贴图出现BUG 解决方案:按照下图所示调整材质的选项即可...

c语言:模拟实现atoi函数
atoi函数的功能和用法: 主要功能:将字符串转换为整数。例如,将字符类型的“123”转换为整数123. #include <stdio.h> #include <stdlib.h>int main() {char str[] "123";int num atoi(str);printf("Converted …...

Docker 使用心得
创建一个docker 镜像,相关运行代码,放在docker镜像文件同级, pm2 不能与 docker一起使用() # node 服务docker FROM node:10.16.3LABEL author"sj"RUN mkdir -p /var/nodeCOPY ./node /var/nodeWORKDIR /va…...

Nacos 架构原理
基本架构及概念 服务 (Service) 服务是指一个或一组软件功能(例如特定信息的检索或一组操作的执行),其目的是不同的客户端可以为不同的目的重用(例如通过跨进程的网络调用)。Nacos 支持主流的服务生态,…...

尝试修改vim光标的思路
尝试修改vim光标,失败 想让vim的光标在不同模式下显示不同样式 尝试了很多方法,但是没有作用 " Set cursor shape and color if &term ~ "xterm"" INSERT modelet &t_SI "\<Esc>[6 q" . "\<Esc&…...

SpringBoot整合Activiti7——消息事件(十)
文章目录 消息事件开始事件中间事件边界事件代码实现xml文件测试流程流程执行步骤 消息事件 消息事件只有一个接收者,消息具有名字与载荷。 信息会储存在 act_ru_event_subscr 表中。 <!-- 定义消息 --> <message id"msgId1" name"msgName…...

高翔:《自动驾驶与机器人中的SLAM技术 》-Slam_in_autonomous_driving 编译过程中遇到的问题
使用的环境是ubuntu20.04 问题1.安装g2o没有问题,不过在编译整个项目工程时候报错: ”openmp_mutex.h: 30:10: fatal error: g2o/config.h: No such file or directory“: 解决办法: 只需要将/thirdparty/g2o/build/g2o下的config.h放到/…...