模版匹配历劫之路1-匹配点太多如何解决

1测试图片

在这里插入图片描述

2初步推测是否是提取的点太多而导致匹配时间很长

2.1通过canny的算法来提取检测点

import numpy as np
import cv2
import time
import matplotlib.pyplot as pltclass GeoMatch:def __init__(self):self.noOfCordinates=0   # 坐标数组中元素的个数self.cordinates = []   # 坐标数组存储模型点self.modelHeight=0   # 模型高self.modelWidth=0   # 模型宽self.edgeMagnitude = []  # 梯度大小self.edgeDerivativeX = []  # 在X方向的梯度self.edgeDerivativeY = []  # 在Y方向的梯度self.centerOfGravity  = []  # 模板重心self.modelDefined=0# 创建模版maxContrast,minContrast为滞后处理的阈值。def CreateGeoMatchModel(self, templateArr, maxContrast, minContrast):Ssize = []src = templateArr.copy()# 设置宽和高Ssize.append(src.shape[1])  # 宽Ssize.append(src.shape[0])  # 高self.modelHeight = src.shape[0]  # 存储模板的高self.modelWidth = src.shape[1]  # 存储模板的宽self.noOfCordinates = 0  # 初始化self.cordinates = [] #self.modelWidth * self.modelHeight  # 为模板图像中选定点的联合分配内存self.edgeMagnitude = []  # 为选定点的边缘幅度分配内存self.edgeDerivativeX = []  # 为选定点的边缘X导数分配内存self.edgeDerivativeY = []  # 为选定点的边缘Y导数分配内存## 计算模板的梯度gx = cv2.Sobel(src, cv2.CV_32F, 1, 0, 3)gy = cv2.Sobel(src, cv2.CV_32F, 0, 1, 3)MaxGradient = -99999.99orients = []nmsEdges = np.zeros((Ssize[1], Ssize[0]))magMat = np.zeros((Ssize[1], Ssize[0]))# 该for循环可以得到 1、梯度图magMat 2、方向列表orientsfor i in range(1, Ssize[1]-1):for j in range(1, Ssize[0]-1):fdx = gx[i][j]  # 读x, y的导数值fdy = gy[i][j]MagG = (float(fdx*fdx) + float(fdy * fdy))**(1/2.0)  # Magnitude = Sqrt(gx^2 +gy^2)direction = cv2.fastAtan2(float(fdy), float(fdx))  # Direction = invtan (Gy / Gx)magMat[i][j] = MagG  # 把梯度放在图像对应位置if MagG > MaxGradient:MaxGradient = MagG  # 获得最大梯度值进行归一化。# 从0,45,90,135得到最近的角if (direction > 0 and direction < 22.5) or (direction > 157.5 and direction < 202.5) or (direction > 337.5 and direction < 360):direction = 0elif (direction > 22.5 and direction < 67.5) or (direction >202.5 and direction <247.5):direction = 45elif (direction >67.5 and direction < 112.5) or (direction>247.5 and direction<292.5):direction = 90elif (direction >112.5 and direction < 157.5) or (direction>292.5 and direction<337.5):direction = 135else:direction = 0orients.append(int(direction))  # 存储方向信息count = 0 # 初始化count# 非最大抑制 # 这个for循环可以保留边缘点# 请问什么是图像的梯度?这里的图像梯度来自于gx和gy的矢量相加。for i in range(1, Ssize[1]-1):  # 图像边缘像素点没有包含在内for j in range(1, Ssize[0]-1):if orients[count] == 0:leftPixel = magMat[i][j-1]rightPixel = magMat[i][j+1]elif orients[count] == 45:leftPixel = magMat[i - 1][j + 1]rightPixel = magMat[i+1][j - 1]elif orients[count] == 90:leftPixel = magMat[i - 1][j]rightPixel = magMat[i+1][j]elif orients[count] == 135:leftPixel = magMat[i - 1][j-1]rightPixel = magMat[i+1][j+1]if (magMat[i][j] < leftPixel) or (magMat[i][j] < rightPixel):nmsEdges[i][j] = 0else:nmsEdges[i][j] = int(magMat[i][j]/MaxGradient*255)count = count + 1RSum = 0CSum = 0flag = 1# 做滞后阈值# 将阈值再筛选一遍for i in range(1, Ssize[1]-1):for j in range(1, Ssize[0]-1):fdx = gx[i][j]fdy = gy[i][j]MagG = (fdx*fdx + fdy*fdy)**(1/2)   # Magnitude = Sqrt(gx^2 +gy^2)DirG = cv2.fastAtan2(float(fdy), float(fdx))  # Direction = tan(y/x)flag = 1if float(nmsEdges[i][j]) < maxContrast:  # 边缘小于最大阈值if float(nmsEdges[i][j]) < minContrast:  # 边缘小于最小阈值nmsEdges[i][j] = 0flag = 0else: # 如果8个相邻像素中的任何一个不大于maxContrast,则从边缘删除if float(nmsEdges[i-1][j-1]) < maxContrast and \float(nmsEdges[i-1][j]) < maxContrast and \float(nmsEdges[i-1][j+1]) < maxContrast and \float(nmsEdges[i][j-1]) < maxContrast and \float(nmsEdges[i][j+1]) < maxContrast and \float(nmsEdges[i+1][j-1]) < maxContrast and \float(nmsEdges[i+1][j]) < maxContrast and \float(nmsEdges[i+1][j+1]) < maxContrast:nmsEdges[i][j] = 0flag = 0# 保存选中的边缘信息curX = i  # 坐标值curY = jif(flag != 0):  # float(nmsEdges[i][j]) > maxContrastif fdx != 0 or fdy != 0: # 所有有效的梯度值RSum = RSum+curX  # 重心的行和和列和;为了求取重心CSum = CSum+curYself.cordinates.append([curX, curY])  # 边缘点的坐标列表self.edgeDerivativeX.append(fdx)self.edgeDerivativeY.append(fdy)# handle divide by zero 归一化if MagG != 0:self.edgeMagnitude.append(1/MagG)  # 建立归一化后的梯度向量else:self.edgeMagnitude.append(0)self.noOfCordinates = self.noOfCordinates+1  # 记录梯度向量的个数self.centerOfGravity.append(RSum//self.noOfCordinates)  # 重心 = 边缘坐标值累加//总边缘点数self.centerOfGravity.append(CSum // self.noOfCordinates)  # 重心# 改变坐标以反映重心  这里将边缘点坐标变成了相对于重心的坐标。for m in range(0, self.noOfCordinates):temp = 0temp = self.cordinates[m][0]self.cordinates[m][0] = temp - self.centerOfGravity[0]temp = self.cordinates[m][1]self.cordinates[m][1] = temp - self.centerOfGravity[1]self.modelDefined = Truereturn 1# 模版匹配 srcarr图像 minScore最小分数def FindGeoMatchModel(self, srcarr, minScore, greediness):Ssize = []Sdx = []Sdy = []resultScore = 0partialSum = 0sumOfCoords = 0resultPoint = []src = srcarr.copy()if not self.modelDefined:return 0Ssize.append(src.shape[1])  # 高Ssize.append(src.shape[0])  # 宽matGradMag = np.zeros((Ssize[1], Ssize[0]))Sdx = cv2.Sobel(src, cv2.CV_32F, 1, 0, 3)  # 找到X导数Sdy = cv2.Sobel(src, cv2.CV_32F, 0, 1, 3)  # 找到Y导数normMinScore = minScore/ self.noOfCordinates  # 预计算minScorenormGreediness = ((1- greediness*minScore)/(1-greediness)) / self.noOfCordinates  # 预计算greedinessfor i in range(0, Ssize[1]):for j in range(0, Ssize[0]):iSx = Sdx[i][j]  # 搜索图像的X梯度iSy = Sdy[i][j]  # 搜索图像的Y梯度gradMag = ((iSx*iSx)+(iSy*iSy))**(1/2)  # Magnitude = Sqrt(dx^2 +dy^2)if gradMag != 0:matGradMag[i][j] = 1/gradMag  # 1/Sqrt(dx^2 +dy^2)else:matGradMag[i][j] = 0height = Ssize[1]wight = Ssize[0]Nof = self.noOfCordinates   # 模版边缘点的总数for i in range(0, height):for j in range(0, wight):partialSum = 0  # 初始化partialSumfor m in range(0, Nof):curX = i + self.cordinates[m][0]  # 模板X坐标  从模版坐标推导出待测图像的坐标curY = j + self.cordinates[m][1]  # 模板Y坐标iTx = self.edgeDerivativeX[m]  # 模板X的导数iTy = self.edgeDerivativeY[m]  # 模板Y的导数if curX < 0 or curY < 0 or curX > Ssize[1] - 1 or curY > Ssize[0] - 1:continueiSx = Sdx[curX][curY]  # 从源图像得到相应的X导数iSy = Sdy[curX][curY]  # 从源图像得到相应的Y导数if (iSx != 0 or iSy != 0) and (iTx != 0 or iTy != 0):# //partial Sum  = Sum of(((Source X derivative* Template X drivative) + Source Y derivative * Template Y derivative)) / Edge magnitude of(Template)* edge magnitude of(Source))# self.edgeMagnitude(列表)归一化之后的梯度# 这里matGradMag表示待测图片的梯度图# 求解相似度度量partialSum = partialSum + ((iSx*iTx)+(iSy*iTy))*(self.edgeMagnitude[m] * matGradMag[curX][curY])sumOfCoords = m+1partialScore = partialSum/sumOfCoords  # 求解相似度量的平均值# 检查终止条件# 如果部分得分小于该位置所需的得分# 在那个坐标中断serching。# 此处使用了贪心算法if partialScore < min((minScore - 1) + normGreediness*sumOfCoords, normMinScore*sumOfCoords):breakif partialScore > resultScore:resultPoint = []resultScore = partialScore  # 匹配分;匹配分会随着匹配个数,慢慢变化,得到最后的匹配分。但不是一直在增大resultPoint.append(i)  # 结果X坐标resultPoint.append(j)  # 结果Y坐标return resultPoint, resultScoredef DrawContours(self, source, color, lineWidth):for i in range(0, self.noOfCordinates):point = []point.append(self.cordinates[i][1] + self.centerOfGravity[1])point.append(self.cordinates[i][0] + self.centerOfGravity[0])point = map(int, point)point = tuple(point)cv2.line(source, point, point, color, lineWidth)def DrawSourceContours(self, source, COG, color, lineWidth):for i in range(0, self.noOfCordinates):point = [0, 0]point[1] = self.cordinates[i][0] + COG[0]point[0] = self.cordinates[i][1] + COG[1]point = map(int, point)point = tuple(point)cv2.line(source, point, point, color, lineWidth)
if __name__ == '__main__':GM = GeoMatch()lowThreshold = 10  # deafult valuehighThreashold = 100  # deafult valueminScore = 0.4  # deafult valuegreediness = 0.8  # deafult valuetotal_time = 0  # deafult valuescore = 0  # deafult valuetemplateImage = cv2.imread("Template.jpg")  # 读取模板图像searchImage = cv2.imread("Search2.jpg")  # 读取待搜索图片templateImage = np.uint8(templateImage)searchImage = np.uint8(searchImage)# ------------------创建基于边缘的模板模型------------------------#if templateImage.shape[-1] == 3:grayTemplateImg = cv2.cvtColor(templateImage, cv2.COLOR_BGR2GRAY)else:grayTemplateImg = templateImage.copy()print("\nEdge Based Template Matching Program")print("--------------------------------------------------------")print(len(GM.cordinates))if not GM.CreateGeoMatchModel(grayTemplateImg, lowThreshold, highThreashold):print("ERROR: could not create model...")assert 0GM.DrawContours(templateImage, (255, 0, 0), 1)print("Shape model created..with Low Threshold = {} High Threshold = {}".format(lowThreshold, highThreashold))# ------------------找到基于边缘的模板模型------------------------## 转换彩色图像为灰色图像。if searchImage.shape[-1] == 3:graySearchImg = cv2.cvtColor(searchImage, cv2.COLOR_BGR2GRAY)else:graySearchImg = searchImage.copy()print("Finding Shape Model..Minumum Score = {} Greediness = {}".format(minScore, greediness))print("--------------------------------------------------------")start_time1 = time.time()result, score = GM.FindGeoMatchModel(graySearchImg, minScore, greediness)finish_time1 = time.time()total_time = finish_time1 - start_time1if score > minScore:print("Found at [{}, {}]\nScore =  {} \nSearching Time = {} s".format(result[0], result[1], score, total_time))GM.DrawSourceContours(searchImage, result, (0, 255, 0), 1)else:print("Object Not found")plt.figure("template Image")plt.imshow(templateImage)plt.figure("search Image")plt.imshow(searchImage)plt.show()

在这里插入图片描述
在这里插入图片描述

也就是说,canny的提取检测点的办法找出了582个点。时间上可以看出用了80s的时间才匹配到了模版对吧。

2.2分析一下时间为什么会这么多?

for i in range(0, height):for j in range(0, wight):start_time4 = time.time()partialSum = 0  # 初始化partialSumfor m in range(0, Nof):curX = i + self.cordinates[m][0]  # 模板X坐标  从模版坐标推导出待测图像的坐标curY = j + self.cordinates[m][1]  # 模板Y坐标iTx = self.edgeDerivativeX[m]  # 模板X的导数iTy = self.edgeDerivativeY[m]  # 模板Y的导数if curX < 0 or curY < 0 or curX > Ssize[1] - 1 or curY > Ssize[0] - 1:continueiSx = Sdx[curX][curY]  # 从源图像得到相应的X导数iSy = Sdy[curX][curY]  # 从源图像得到相应的Y导数if (iSx != 0 or iSy != 0) and (iTx != 0 or iTy != 0):# //partial Sum  = Sum of(((Source X derivative* Template X drivative) + Source Y derivative * Template Y derivative)) / Edge magnitude of(Template)* edge magnitude of(Source))# self.edgeMagnitude(列表)归一化之后的梯度# 这里matGradMag表示待测图片的梯度图# 求解相似度度量partialSum = partialSum + ((iSx*iTx)+(iSy*iTy))*(self.edgeMagnitude[m] * matGradMag[curX][curY])sumOfCoords = m+1partialScore = partialSum/sumOfCoords  # 求解相似度量的平均值# 检查终止条件# 如果部分得分小于该位置所需的得分# 在那个坐标中断serching。# 此处使用了贪心算法if partialScore < min((minScore - 1) + normGreediness*sumOfCoords, normMinScore*sumOfCoords):breakif partialScore > resultScore:resultPoint = []resultScore = partialScore  # 匹配分;匹配分会随着匹配个数,慢慢变化,得到最后的匹配分。但不是一直在增大resultPoint.append(i)  # 结果X坐标resultPoint.append(j)  # 结果Y坐标start_time41 = time.time()print("start_time4:",start_time41-start_time4)sum+=(start_time41-start_time4)print("sum:",sum)return resultPoint, resultScore

Searching Time = 78.99114680290222s。

  • 我们可以看到这里面复杂度最高的是三个循环结构。前面两循环,我们可以通过图像金字塔来解决。
  for i in range(0, height):for j in range(0, wight):
  • 第三个循环,则是依赖于特征点的多少?
for m in range(0, Nof):

2.3 不妨再来分析一下模版的轮廓点是越多越好吗?

在金字塔高层,我们会发现比较模糊,模糊代表着特征点肯定会比较少。另一方面,如果是第一层金字塔,也就是原图,图像很精细,侧面也说明噪声很多,边缘的噪声很有可能影响匹配的准确性。

所以也就是说轮廓点其实不是越多越好。我们暂时推荐按照关键点检测的数量来定。

2.4 那我们计算一下优化点之后的时间(79s->10.6s)

582/77=7.4285
78.99114680290222s/7.4285=10.6s
但是10s还是太慢了,并且我们要知道本算法并没有添加旋转特征的方式。所以我们应该还是要讨论一下在下一章讨论一下金字塔,再之后讨论如何将并行计算加入到图像金字塔搜索中去。

2.5 我们应该还是要讨论一下在下一章讨论一下金字塔,再之后讨论如何将并行计算加入到图像金字塔搜索中去。

利用角点检测检测轮廓点

#include<opencv2/opencv.hpp>
#include<iostream>using namespace std;
using namespace cv;int main(int agrc, char** argv) {Mat src = imread("E:/Template Matching/Template.jpg");imshow("input", src);Mat gray;cvtColor(src, gray, COLOR_RGB2GRAY);vector<Point>corners;goodFeaturesToTrack(gray, corners, 50, 0.015, 5);for (size_t t = 0; t < corners.size(); t++){circle(src, corners[t], 2, Scalar(0, 0, 255), 2, 8, 0);}imshow("角点检测", src);waitKey(0);return 0;}

这里可以看到角点50个边缘的效果就挺好的。
在这里插入图片描述

利用关键点检测检测轮廓点

#include<opencv2/opencv.hpp>
#include<iostream>using namespace std;
using namespace cv;int main(int agrc, char** argv) {Mat src = imread("E:/Template Matching/Template.jpg");imshow("input", src);auto orb = ORB::create(100);Mat result;vector<KeyPoint>kypts;orb->detect(src, kypts);cout << kypts.size() << endl;drawKeypoints(src, kypts, result, Scalar::all(-1), DrawMatchesFlags::DEFAULT);imshow("关键点检测", result);waitKey(0);return 0;

kypts.size()的结果为77,也就是有77个点。
在这里插入图片描述
可以看到关键点的检测和轮廓确实不一样。

halcon提取出模版是什么样子的。

点超级多呀,真的是需要这么多点吗?
在这里插入图片描述

visionpro提取的模版是什么样子的。

这个点就不会特别多了,有点类似关键点。所以猜想是不是曲线拟合了一下,然后提取出来了轮廓,外加关键点。
在这里插入图片描述

总结

看了一些资料,个人感觉匹配的点不是最主要的。如果我们的主要矛盾在于解决匹配的速度和精度,那么最先要解决的主要矛盾应该是金字塔结构。如果主要矛盾是旋转匹配,那就解决旋转匹配的问题。再之后尝试解决匹配点,并且可能和轮廓拟合存在一定关系,拟合不好轮廓梯度是会发生变化的。
在一篇论文中提到的一种改进思路:
1、边缘点稀疏通过等距采样边缘点减少模板的匹配运算量。
2、逐层重叠筛选通过对每一层候选对象进行非极大值筛选来排除无效区域。
3、并行算法使用SSE指令优化了亚像素点梯度的插值计算方法,使用PPL并行库实现了多模版的并行匹配。
4、针对传统形状匹配算法位姿匹配精度不高的问题,提出了结合小批量梯度下降法的位姿逼近算法。该方法使用基于二次曲面拟合改进的Canny算法获得亚像素精度的边缘点,提高了形状模版的精度。通过最小化边缘点与对应边缘切线的距离,将位姿逼近问题转化为非线性最小二乘问题来逐步求解,获取更高精度的位姿参数。

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

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

相关文章

思维链COT原理探究

要进行因果分析&#xff0c;需要把思维链中的不同元素拆解开来&#xff0c;然后通过控制变量实验&#xff0c;来研究不同元素对COT效果的影响。以下两篇论文的核心差异就在于: COT的变量拆解&#xff0c;以及控制变量的实验方式。 结合两篇论文的实验结论&#xff0c;可能导致…

MIT线性代数笔记-第34讲-左右逆,伪逆

目录 34.左右逆&#xff0c;伪逆左右逆伪逆 打赏 34.左右逆&#xff0c;伪逆 左右逆 之前讲到的逆都是针对可逆方阵而言的&#xff0c;对于长方矩阵&#xff0c;实际上也有广义的逆&#xff0c;那就是左逆和右逆 左逆 当矩阵列满秩&#xff0c;即 r n r n rn时&#xff0c;…

老子的《道德经》透露,不努力反而更成功

人类生而自由&#xff0c;但到处都是枷锁。 永远不要怀疑经过慎思且足够投入的一小群人能否改变这个世界。事实上&#xff0c;只有他们才办得到。 优美灵魂的两个发展方向&#xff1a;崇拜道德的天才&#xff0c;对别人实行道德的判断。 一、道 《道德经》开始的名字是《老子…

关键字:try-catch关键字

在 Java 中&#xff0c;try-catch关键字用于异常处理。它们允许编写代码来捕获和处理异常&#xff0c;以确保程序能够在出现问题时合理地处理它们而不会崩溃。 以下是try-catch关键字的基本语法&#xff1a; 在try块中编写可能会抛出异常的代码。如果在try块中的任何代码抛出…

全连接层:神经网络的桥梁

全连接层&#xff1a;神经网络的桥梁 大家好&#xff0c;我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天&#xff0c;让我们一同探讨深度学习中至关重要的一环——“全连接层”&am…

Linux上使用Certbot生成免费SSL证书

Linux上使用Certbot生成免费SSL证书 补充&#xff1a;certbot在大多数linux上是自带的&#xff0c;若没有可执行以下命令下载 Ubuntu&#xff1a; sudo apt-get update sudo apt-get install --only-upgrade certbotCentos sudo yum update sudo yum install certbot一、暂时停…

JavaScript setTimeout和setInterval的用法与区别详解

目录 I. 总述 II. setTimeout()函数 III. setInterval()函数 IV. 新年倒计时案例 Javascript的setTimeOut和setInterval函数应用非常广泛&#xff0c;它们都用来处理延时和定时任务&#xff0c;下面这篇文章主要给大家介绍了关于JavaScript setTimeout和setInterval的用法与…

读取某股票的日线数据

只需修改对应股票的ts_code&#xff0c;start_date&#xff0c;end_date即可获取对应股票的全部数据。 import tushare as ts import pandas as pdpd.set_option(expand_frame_repr, False) # 当列太多时不换行 pd.set_option(display.max_rows, 5000) # 最多显示数据的行数…

结构型设计模式—装饰器模式

装饰器模式&#xff1a;不改变原对象的基础上&#xff0c;灵活地给对象添加额外职责。装饰器相比于生成子类更加灵活。即将实现同一接口的父类当做参数传入包装器对象&#xff0c;动态创建出新的对象。 给对象添加新行为最简单直观的办法就是扩展本体对象&#xff0c;通过继承…

编程笔记 html5cssjs 018 HTML颜色

编程笔记 html5&css&js 018 HTML颜色 一、HTML 颜色二、HTML中设置颜色值注意 颜色是视觉中重要因素&#xff0c;尤其是处理人机界面中&#xff0c;更是要处理颜色设置和搭配。在网页中&#xff0c;提供了设置颜色的一些方案&#xff0c;需要我们认真学习和掌握。 一、…

HTML5和JS实现新年礼花效果

HTML5和JS实现新年礼花效果 2023兔年再见&#xff0c;2024龙年来临了&#xff01; 祝愿读者朋友们在2024年里&#xff0c;身体健康&#xff0c;心灵愉悦&#xff0c;梦想成真。 下面是用HTML5和JS实现新年礼花效果&#xff1a; 源码如下&#xff1a; <!DOCTYPE html>…

MySQL数据库学习一

1 什么是数据库的事务&#xff1f; 1.1 事务的典型场景 在项目里面&#xff0c;什么地方会开启事务&#xff0c;或者配置了事务&#xff1f;无论是在方法上加注解&#xff0c;还 是配置切面。 <tx:advice id"txAdvice" transaction-manager"transactionMa…

个人简历范本(精选5篇)

HR浏览一份简历也就25秒左右&#xff0c;如果你连「好简历」都没有&#xff0c;怎么能找到好工作呢&#xff1f; 如果你不懂得如何在简历上展示自己&#xff0c;或者觉得怎么改简历都不出彩&#xff0c;那请你一定仔细读完。 个人求职简历第 1 篇 男 22 本科 AI简历 市场营…

007、控制流

先看下本篇学习内容&#xff1a; 通过条件来执行 或 重复执行某些代码 是大部分编程语言的基础组成部分。在Rust中用来控制程序执行流的结构主要就是 if表达式 与 循环表达式。 1. if表达式 if表达式允许我们根据条件执行不同的代码分支。我们提供一个条件&#xff0c;并且做出…

【NTN 卫星通信】Oneweb星座以及Oneweb与Starlink比较

1 什么是OneWeb OneWeb于2012年以WorldVu的名义成立&#xff0c;于2020年开始构建其星座。然而&#xff0c;对于这家英国公司来说&#xff0c;这是一个艰难的旅程&#xff0c;OneWeb于2020年3月宣布破产&#xff0c;并认为covid-19大流行是一个主要因素。OneWeb星座当时仅完成…

一次降低进程IO延迟的性能优化实践——基于block层bfq调度器

如果有个进程正频繁的读写文件&#xff0c;此时你vim查看一个新文件&#xff0c;将会出现明显卡顿。即便你vim查看的文件只有几十M&#xff0c;也可能会出现卡顿。相对的&#xff0c;线上经常遇到IO敏感进程偶发IO超时问题。这些进程一次读写的文件数据量很少&#xff0c;正常几…

Redis的缓存过期淘汰策略

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码、Kafka原理、分布式技术原理、数据库技术&#x1f525;如果感觉博主的文章还不错的…

RocketMQ(Linux版本5.1.4)

1、停止之前的运行服务 [roottssvr1-c1 rocketmq-all-4.7.0-bin-release]# sh bin/mqshutdown namesrv No mqnamesrv running. [roottssvr1-c1 rocketmq-all-4.7.0-bin-release]# [roottssvr1-c1 rocketmq-all-4.7.0-bin-release]# [roottssvr1-c1 rocketmq-all-4.7.0-bin-r…

Debezium发布历史39

原文地址&#xff1a; https://debezium.io/blog/2018/09/19/debezium-0-8-3-final-released/ 欢迎关注留言&#xff0c;我是收集整理小能手&#xff0c;工具翻译&#xff0c;仅供参考&#xff0c;笔芯笔芯. Debezium 0.8.3.Final 发布 2018 年 9 月 19 日 作者&#xff1a; …

LOJ #6278 数列分块2题解 2024年第一篇题解

Part #0 . 前言 \text{Part \#0 . 前言} Part #0 . 前言 数列分块1 分块是一种优雅的暴力。 Part #1 . 数列分块入门2 \text{Part \#1 . 数列分块入门2} Part #1 . 数列分块入门2 传送门 观察题目&#xff0c;我们可以发现题目是一个区间查询&#xff0c;区间修改。 首先&a…