【深度学习】OCR文本识别

news2024/12/22 22:24:14

OCR文字识别定义

OCR(optical character recognition)文字识别是指电子设备(例如扫描仪或数码相机)检查纸上打印的字符,然后用字符识别方法将形状翻译成计算机文字的过程;即,对文本资料进行扫描,然后对图像文件进行分析处理,获取文字及版面信息的过程。如何除错或利用辅助信息提高识别正确率,是OCR最重要的课题。衡量一个OCR系统性能好坏的主要指标有:拒识率、误识率、识别速度、用户界面的友好性,产品的稳定性,易用性及可行性等。

由于扫描仪的普及与广泛应用,OCR软件只需提供与扫描仪的接口,利用扫描仪驱动软件即可。因此,OCR软件主要是由下面几个部分组成。

  1. 图像输入、预处理:
    图像输入:对于不同的图像格式,有着不同的存储格式,不同的压缩方式。预处理:主要包括二值化,噪声去除,倾斜较正等
  2. 二值化:
    对摄像头拍摄的图片,大多数是彩色图像,彩色图像所含信息量巨大,对于图片的内容,我们可以简单的分为前景与背景,为了让计算机更快的,更好的识别文字,我们需要先对彩色图进行处理,使图片只前景信息与背景信息,可以简单的定义前景信息为黑色,背景信息为白色,这就是二值化图了。
  3. 噪声去除:
    对于不同的文档,我们对噪声的定义可以不同,根据噪声的特征进行去噪,就叫做噪声去除
  4. 倾斜较正:
    由于一般用户,在拍照文档时,都比较随意,因此拍照出来的图片不可避免的产生倾斜,这就需要文字识别软件进行较正。
  5. 版面分析:
    将文档图片分段落,分行的过程就叫做版面分析,由于实际文档的多样性,复杂性,因此,还没有一个固定的,最优的切割模型。
  6. 字符切割:
    由于拍照条件的限制,经常造成字符粘连,断笔,因此极大限制了识别系统的性能,这就需要文字识别软件有字符切割功能。
  7. 字符识别:
    这一研究,已经是很早的事情了,比较早有模板匹配,后来以特征提取为主,由于文字的位移,笔画的粗细,断笔,粘连,旋转等因素的影响,极大影响特征的提取的难度。
  8. 版面恢复:
    人们希望识别后的文字,仍然像原文档图片那样排列着,段落不变,位置不变,顺序不变,的输出到word文档,pdf文档等,这一过程就叫做版面恢复。
  9. 后处理、校对:
    根据特定的语言上下文的关系,对识别结果进行较正,就是后处理。

开发一个OCR文字识别软件系统,其目的很简单,只是要把影像作一个转换,使影像内的图形继续保存、有表格则表格内资料及影像内的文字,一律变成计算机文字,使能达到影像资料的储存量减少、识别出的文字可再使用及分析,当然也可节省因键盘输入的人力与时间。

从影像到结果输出,须经过影像输入、影像前处理、文字特征抽取、比对识别、最后经人工校正将认错的文字更正,将结果输出。


以美团的OCR识别为例

基于深度学习的OCR

文字是不可或缺的视觉信息来源。相对于图像/视频中的其他内容,文字往往包含更强的语义信息,因此对图像中的文字提取和识别具有重大意义。OCR在美团业务中主要起着两方面作用。一方面是辅助录入,比如在移动支付环节通过对银行卡卡号的拍照识别以实现自动绑卡,辅助运营录入菜单中菜品信息,在配送环节通过对商家小票的识别以实现调度核单,如图1所示。另一方面是审核校验,比如在商家资质审核环节对商家上传的身份证、营业执照和餐饮许可证等证件照片进行信息提取和核验以确保该商家的合法性,机器过滤商家上单和用户评价环节产生的包含违禁词的图片。
在这里插入图片描述

OCR技术发展历程

传统的OCR基于图像处理(二值化、连通域分析、投影分析等)和统计机器学习(Adaboost、SVM),过去20年间在印刷体和扫描文档上取得了不错的效果。传统的印刷体OCR解决方案整体流程如图所示。
在这里插入图片描述
从输入图像到给出识别结果经历了图像预处理、文字行提取和文字行识别三个阶段。其中文字行提取的相关步骤(版面分析、行切分)会涉及大量的先验规则,而文字行识别主要基于传统的机器学习方法。随着移动设备的普及,对拍摄图像中的文字提取和识别成为主流需求,同时对场景中文字的识别需求越来越突出。因此,相比于印刷体场景,拍照文字的识别将面临以下三方面挑战:

  • 成像复杂。噪声、模糊、光线变化、形变。
  • 文字复杂。字体、字号、色彩、磨损、笔画宽度任意、方向任意。
  • 场景复杂。版面缺失、背景干扰。

对于上述挑战,传统的OCR解决方案存在着以下不足:

  • 通过版面分析(连通域分析)和行切分(投影分析)来生成文本行,要求版面结构有较强的规则性且前背景可分性强(例如黑白文档图像、车牌),无法处理前背景复杂的随意文字(例如场景文字、菜单、广告文字等)。另外,二值化操作本身对图像成像条件和背景要求比较苛刻。
  • 通过人工设计边缘方向特征(例如方向梯度直方图)来训练字符识别模型,在字体变化、模糊或背景干扰时,此类单一的特征的泛化能力迅速下降。
  • 过度依赖于字符切分的结果,在字符扭曲、粘连、噪声干扰的情况下,切分的错误传播尤其突出。
  • 尽管图像预处理模块可有效改善输入图像的质量,但多个独立的校正模块的串联必然带来误差传递。另外由于各模块优化目标独立,它们无法融合到统一的框架中进行。

为了解决上述问题,现有技术在以下三方面进行了改进。

1. 文字行提取

传统OCR(如图3所示)采取自上而下的切分式,但它只适用于版面规则背景简单的情况。该领域还有另外两类思路。

  • 自底向上的生成式方法。该类方法通过连通域分析或最大稳定极值区域(MSER)等方法提取候选区域,然后通过文字/非文字的分类器进行区域筛选,对筛选后的区域进行合并生成文字行,再进行文字行级别的过滤,如图3所示。该类方法的不足是,一方面流程冗长导致的超参数过多,另一方面无法利用全局信息。
    在这里插入图片描述
  • 基于滑动窗口的方法。该类方法利用通用目标检测的思路来提取文字行信息,利用训练得到的文字行/词语/字符级别的分类器来进行全图搜索。原始的基于滑动窗口方法通过训练文字/背景二分类检测器,直接对输入图像进行多尺度的窗口扫描。检测器可以是传统机器学习模型(Adaboost、Random Ferns),也可以是深度卷积神经网络。

为了提升效率,DeepText、TextBoxes等方法先提取候选区域再进行区域回归和分类,同时该类方法可进行端到端训练,但对多角度和极端宽高比的文字区域召回低。

2. 传统单字识别引擎→基于深度学习的单字识别引擎

由于单字识别引擎的训练是一个典型的图像分类问题,而卷积神经网络在描述图像的高层语义方面优势明显,所以主流方法是基于卷积神经网络的图像分类模型。实践中的关键点在于如何设计网络结构和合成训练数据。对于网络结构,我们可以借鉴手写识别领域相关网络结构,也可采用OCR领域取得出色效果的Maxout网络结构,如图4所示。对于数据合成,需考虑字体、形变、模糊、噪声、背景变化等因素。

在这里插入图片描述
表1给出了卷积神经网络的特征学习和传统特征的性能比较,可以看出通过卷积神经网络学习得到的特征鉴别能力更强。

在这里插入图片描述

3. 文字行识别流程

传统OCR将文字行识别划分为字符切分和单字符识别两个独立的步骤,尽管通过训练基于卷积神经网络的单字符识别引擎可以有效提升字符识别率,但切分对于字符粘连、模糊和形变的情况的容错性较差,而且切分错误对于识别是不可修复的。因此在该框架下,文本行识别的准确率主要受限于字符切分。假设已训练单字符识别引擎的准确率p=99%,字符切分准确率为q= 95%,则对于一段长度为L的文字行,其识别的平均准确率为P= (pq)的L次方,其中L=10时,P=54.1%。

由于独立优化字符切分提升空间有限,因此有相关方法试图联合优化切分和识别两个任务。现有技术主要可分为基于切分的方法(Segmentation-Based)和不依赖切分的方法(Segmentation- Free)两类方法。

基于切分的方法

该类方法还是保留主动切分的步骤,但引入了动态合并机制,通过识别置信度等信息来指导切分,如图所示。

在这里插入图片描述
过切分模块将文字行在垂直于基线方向上分割成碎片,使得其中每个碎片至多包含一个字符。通常来说,过切分模块会将字符分割为多个连续笔划。过切分可以采用基于规则或机器学习的方法。规则方法主要是直接在图像二值化的结果上进行连通域分析和投影分析来确定候补切点位置,通过调整参数可以控制粒度来使得字符尽可能被切碎。基于规则的方法实现简单,但在成像/背景复杂的条件下其效果不好。机器学习方法通过离线训练鉴别切点的二类分类器,然后基于该分类器在文字行图像上进行滑窗检测。

动态合并模块将相邻的笔划根据识别结果组合成可能的字符区域,最优组合方式即对应最佳切分路径和识别结果。直观来看,寻找最优组合方式可转换为路径搜索问题,对应有深度优先和广度优先两种搜索策略。深度优先策略在每一步选择扩展当前最优的状态,因此全局来看它是次优策略,不适合过长的文字行。广度优先策略在每一步会对当前多个状态同时进行扩展,比如在语音识别领域广泛应用的Viterbi解码和Beam Search。但考虑到性能,Beam Search通常会引入剪枝操作来控制路径长度,剪枝策略包含限制扩展的状态数(比如,每一步只扩展TopN的状态)和加入状态约束(比如,合并后字符形状)等。

由于动态合并会产生多个候选路径,所以需要设计合适的评价函数来进行路径选择。评价函数的设计主要从路径结构损失和路径识别打分两方面出发。路径结构损失主要从字符形状特征方面衡量切分路径的合理性,路径识别打分则对应于特定切分路径下的单字平均识别置信度和语言模型分。

该方案试图将字符切分和单字符识别融合在同一个框架下解决,但由于过分割是独立的步骤,因此没有从本质上实现端到端学习。

不依赖切分的方法

该类方法完全跨越了字符切分,通过滑动窗口或序列建模直接对文字行进行识别。

滑窗识别借鉴了滑动窗口检测的思路,基于离线训练的单字识别引擎,对文字行图像从左到右进行多尺度扫描,以特定窗口为中心进行识别。在路径决策上可采用贪心策略或非极大值抑制(NMS)策略来得到最终的识别路径。图6给出了滑窗识别的示意流程。可见滑窗识别存在两个问题:滑动步长的粒度过细则计算代价大,过粗则上下文信息易丢失;无论采用何种路径决策方案,它们对单字识别的置信度依赖较高。

在这里插入图片描述
序列学习起源于手写识别、语音识别领域,因为这类问题的共同特点是需要对时序数据进行建模。尽管文字行图像是二维的,但如果把从左到右的扫描动作类比为时序,文字行识别从本质上也可归为这类问题。通过端到端的学习,摒弃矫正/切分/字符识别等中间步骤,以此提升序列学习的效果,这已经成为当前研究的热点。

基于现有技术和美团业务涉及的OCR场景,我们在文字检测和文字行识别采用如图所示的深度学习框架。

在这里插入图片描述

基于深度学习的文字检测

对于美团的OCR场景,根据版面是否有先验信息(卡片的矩形区域、证件的关键字段标识)以及文字自身的复杂性(如水平文字、多角度),图像可划分为受控场景(如身份证、营业执照、银行卡)和非受控场景(如菜单、门头图),如图所示。
![在这里插入图片描述](https://img-blog.csdnimg.cn/192e0068d334429db474839133a9f532.png
考虑到这两类场景的特点不同,我们借鉴不同的检测框架。由于受控场景文字诸多约束条件可将问题简化,因此利用在通用目标检测领域广泛应用的Faster R-CNN框架进行检测。而对于非受控场景文字,由于形变和笔画宽度不一致等原因,目标轮廓不具备良好的闭合边界,我们需要借助图像语义分割来标记文字区域与背景区域。

  1. 受控场景的文字检测

对于受控场景(如身份证),我们将文字检测转换为对关键字目标(如姓名、身份证号、地址)或关键条目(如银行卡号)的检测问题。基于Faster R-CNN的关键字检测流程如图9所示。为了保证回归框的定位精度,同时提升运算速度,我们对原有框架和训练方式进行了微调。

  • 考虑到关键字或关键条目的类内变化有限,网络结构只采用了3个卷积层。
  • 训练过程中提高正样本的重叠率阈值。
  • 根据关键字或关键条目的宽高比范围来适配RPN层Anchor的宽高比。

在这里插入图片描述
Faster R-CNN框架由RPN(候选区域生成网络)和RCN(区域分类网络)两个子网络组成。RPN通过监督学习的方法提取候选区域,给出的是无标签的区域和粗定位结果。RCN引入类别概念,同时进行候选区域的分类和位置回归,给出精细定位结果。训练时两个子网络通过端到端的方式联合优化。图10以银行卡卡号识别为例,给出了RPN层和RCN层的输出。

在这里插入图片描述
对于人手持证件场景,由于证件目标在图像中所占比例过小,直接提取微小候选目标会导致一定的定位精度损失。为了保证高召回和高定位精度,可采用由粗到精的策略进行检测。首先定位卡片所在区域位置,然后在卡片区域范围内进行关键字检测,而区域定位也可采用Faster R-CNN框架,如图11所示。

在这里插入图片描述
2. 非受控场景的文字检测

对于菜单、门头图等非受控场景,由于文字行本身的多角度且字符的笔画宽度变化大,该场景下的文字行定位任务挑战很大。由于通用目标检测方法的定位粒度是回归框级,此方法适用于刚体这类有良好闭合边界的物体。然而文字往往由一系列松散的笔画构成,尤其对于任意方向或笔画宽度的文字,仅以回归框结果作为定位结果会有较大偏差。另外刚体检测的要求相对较低,即便只定位到部分主体(如定位结果与真值的重叠率是50%),也不会对刚体识别产生重大影响,而这样的定位误差对于文字识别则很可能是致命的。

为了实现足够精细的定位,我们利用语义分割中常用的全卷积网络(FCN)来进行像素级别的文字/背景标注,整体流程如图12所示。

在这里插入图片描述
多尺度全卷积网络通过对多个阶段的反卷积结果的融合,实现了全局特征和局部特征的联合,进而达到了由粗到精的像素级别标注,适应于任意非受控场景(门头图、菜单图片)。

基于多尺度全卷积网络得到的像素级标注,通过连通域分析技术可得到一系列连通区域(笔划信息)。但由于无法确定哪些连通域属于同一文字行,因此需要借助单链聚类技术来进行文字行提取。至于聚类涉及的距离度量,主要从连通域间的距离、形状、颜色的相似度等方面提取特征,并通过度量学习自适应地得到特征权重和阈值,如图13所示。

在这里插入图片描述
图14分别给出了在菜单和门头图场景中的全卷积网络定位效果。第二列为全卷积网络的像素级标注结果,第三列为最终文字检测结果。可以看出,全卷积网络可以较好地应对复杂版面或多角度文字定位。

在这里插入图片描述

基于序列学习的文字识别

我们将整行文字识别问题归结为一个序列学习问题。利用基于双向长短期记忆神经网络(Bi-directional Long Short-term Memory,BLSTM)的递归神经网络作为序列学习器,来有效建模序列内部关系。为了引入更有效的输入特征,我们采用卷积神经网络模型来进行特征提取,以描述图像的高层语义。此外在损失函数的设计方面,考虑到输出序列与输入特征帧序列无法对齐,我们直接使用结构化的Loss(序列对序列的损失),另外引入了背景(Blank)类别以吸收相邻字符的混淆性。

整体网络结构分为三层:卷积层、递归层和翻译层,如图15所示。其中卷积层提取特征;递归层既学习特征序列中字符特征的先后关系,又学习字符的先后关系;翻译层实现对时间序列分类结果的解码。

在这里插入图片描述
对于输入的固定高度h0= 36的图像(宽度任意,如W0 = 248),我们通过CNN网络结构提取特征,得到9×62×128的特征图,可将其看作一个长度为62的时间序列输入到RNN层。RNN层有400个隐藏节点,其中每个隐藏节点的输入是9×128维的特征,是对图像局部区域的描述。考虑到对应于某个时刻特征的图像区域,它与其前后内容都具有较强的相关性,所以我们一般采用双向RNN网络,如图16所示。

在这里插入图片描述
双向RNN后接一个全连接层,输入为RNN层(在某个时刻)输出的特征图,输出为该位置是背景、字符表中文字的概率。全连接层后接CTC(联结主义时间分类器)作为损失函数。在训练时,根据每个时刻对应的文字、背景概率分布,得到真值字符串在图像中出现的概率P(ground truth),将-log(P(ground truth))作为损失函数。在测试时,CTC可以看作一个解码器,将每一时刻的预测结果(当前时刻的最大后验概率对应的字符)联合起来,然后去掉空白和重复的模式,就形成了最终的序列预测结果,如图17所示。

在这里插入图片描述
从图17中也可以看出,对应输入序列中的每个字符,LSTM输出层都会产生明显的尖峰,尽管该尖峰未必对应字符的中心位置。换句话说,引入CTC机制后,我们不需要考虑每个字符出现的具体位置,只需关注整个图像序列对应的文字内容,最终实现深度学习的端到端训练与预测。

由于序列学习框架对训练样本的数量和分布要求较高,我们采用了真实样本+合成样本的方式。真实样本以美团业务来源(例如,菜单、身份证、营业执照)为主,合成样本则考虑了字体、形变、模糊、噪声、背景等因素。

基于上述序列学习框架,我们给出了在不同场景下的文字行识别结果,如图18所示。其中前两行的图片为验证码场景,第三行为银行卡,第四行为资质证件,第五行为门头图,第六行为菜单。可以看到,识别模型对于文字形变、粘连、成像的模糊和光线变化、背景的复杂等都有较好的健壮性。

在这里插入图片描述
基于上述试验,与传统OCR相比,我们在多种场景的文字识别上都有较大幅度的性能提升,如图19所示:

在这里插入图片描述
与传统OCR相比,基于深度学习的OCR在识别率方面有了大幅上升。但对于特定的应用场景(营业执照、菜单、银行卡等),条目准确率还有待提升。一方面需要融合基于深度学习的文字检测与传统版面分析技术,以进一步提升限制场景下的检测性能。另一方面需要丰富真实训练样本和语言模型,以提升文字识别准确率。


如果我们的标签序列,就是真实的数据“水煮肉片22元”,长度设为L
加入blank空格之后,长度为多少?
水_煮_肉_片_2_2_元
2*L+1

最终将预测的序列:

  1. 连续相同的字符去重!
  2. 去除空字符!

所以我们要想我们的预测序列可以经过上述的去重去空格得到正确答案
我们是不是在训练模型的时候,就要给RNN准备各种可能的路径~

各种可能的路径是不是要根据之前的“水_煮_肉_片_2_2_元”来构建

为了最终去重去空格可以不会错,那么我们在构建各种可能的路径时候就需要加入一些约束条件!!!

  1. 方向只能向下和向右
  2. 相同的字符之间要有一个空字符
  3. 非空字符不能被跳过
  4. 起点必须从前两个字符开始
  5. 终点必须在结尾两个字符结束

CTC loss == 求的是所有可能路径的概率的对数之和最大

会用到动态规划思想,把大问题拆分为小问题,像滚雪球似的求解

对概率求总和和进行递归求解,动态规划需要初始条件状态转移方程,CTC中也有状态转移方程

前向传播

  • 情况一:第s个字符是blank
    s=3,t=3,a33状态依赖于a23和a22
    a33 = (a23+a22)*y_3
    推广 At(s) = (At-1(s) + At-1(s-1))*Yt(seq(s))

  • 情况二:第s个字符和第s-2个字符相同
    推广 At(s) = (At-1(s) + At-1(s-1))*Yt(seq(s))

  • 情况三:其他情况
    推广 At(s) = (At-1(s) + At-1(s-1) + At-1(s-2))*Yt(seq(s))

后向传播

CTC算法特性:

  1. CTC经常被吐槽一个特性是条件独立性
    CTC loss最开始是用在语言识别的,后来OCR
    比如一个人去说“三个A”,输出有两个,AAA,triple A
    不会学到任何语言模型的知识
  2. CTC算法不需要训练数据对齐
    CTC要求对齐的方式是单调的,像机器翻译,不适合
    CTC要求输入和输出是多对一的关系,有的任务是需要严格一对一关系,比如词性标注,不适合
    CTC要求输出要比输入短

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

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

相关文章

【数据结构】二叉树经典oj题

🚀write in front🚀 📜所属专栏:初阶数据结构 🛰️博客主页:睿睿的博客主页 🛰️代码仓库:🎉VS2022_C语言仓库 🎡您的点赞、关注、收藏、评论,是对…

B. Make Them Equal(Codeforces Round 673 (Div. 1))

传送门 题意: 思路: 首先判断是否能够操作达到目的:即所有的数都相等。 不能达到有两种情况: 1:所有数之和对n取余不等于0 2: 每个ai都是小于i的,例如n5, a[]{0,1,2,3,4}。因为每个数都是小于 i 的&am…

idea中的 debug 中小功能按钮都代表的意思

1.step over 步过----->一行一行的往下走,如果这一行中有方法那么不会进入该方法,直接一行一行往下走,除非你在该方法中打入断点 2.step into 步入—>可以进入方法内部,但是只能进入自己写的方法内部,而不会进入方法的类库中 3.Force step into 强制步入---->可以步…

编译livox ros driver2(ROS2、livox、rviz、ubuntu22.04)

1. 编译Livox-SDK2 官方地址:https://github.com/Livox-SDK/Livox-SDK2 执行一下命令: git clone https://github.com/Livox-SDK/Livox-SDK2.git cd ./Livox-SDK2/ mkdir build cd build cmake .. && make sudo make install 如上就安装完成了…

嵌入式【CPLD】5M570ZT100C5N、5M1270ZF256C5N、5M2210ZF256C5N采用独特的非易失性架构,低成本应用设计。

英特尔MAX V CPLD 采用独特的非易失性架构,提供低功耗片上功能,适用于以边缘为中心的应用。MAX V CPLD系列能够在单位空间中提供大量 I/O 和逻辑。这些设备还使用了低成本绿色封装技术,封装大小只有 20 毫米。 MAX V系列的关键应用包括&…

PCL点云库(1) - 简介与数据类型

目录 1.1 简介 1.2 PCL安装 1.2.1 安装方法 1.2.2 测试程序 1.3 PCL数据类型 1.4 PCL中自定义point类型 1.4.1 增加自定义point的步骤 1.4.2 完整代码 1.1 简介 来源:PCL(点云库)_百度百科 PCL(Point Cloud Library&…

个推打造消息推送专项运营提升方案,数据驱动APP触达效果升级

“数智化运营”能力已成为企业的核心竞争力之一。借助数据和算法,构建完善的数智化运营体系,企业可增强用户洞察和科学决策能力,提高日常运营效率和投入产出比。近半年,个推精准把握行业客户的切实需求,将“数智化运营…

分析型数据库:MPP 数据库的概念、技术架构与未来发展方向

随着企业数据量的增多,为了配合企业的业务分析、商业智能等应用场景,从而驱动数据化的商业决策,分析型数据库诞生了。由于数据分析一般涉及的数据量大,计算复杂,分析型数据库一般都是采用大规模并行计算或者分布式计算…

css的属性选择器

文章目录 属性选择器的原理简单的语法介绍子串值(Substring value)属性选择器 CSS 属性选择器的最基本用法复杂一点的用法层叠选择多条件复合选择伪正则写法配合 **:not()** 伪类重写行内样式 组合用法:搭配伪元素提升用户体验角标功能属性选…

基于51单片机的智能晾衣架的设计与实现(源码+论文)_kaic

【摘要】随着社会和市场的变化,我国经济的快速发展和房地产行业的快速扩张,使得装修家居行业飞速发展,在行业高速发展的同时,消费者家居智能化要求也在日益发展。随着科学技术的进步和电子技术的发展,单片机作为智能控…

Stable Diffusion一键安装器,只有2.3M

最近AI画图真的是太火了,但是Midjourney收费之后大家就不知道去哪里能用AI画图了, Stable Diffusion很多人听过,但是安装特别麻烦。所以为大家介绍一款软件,一键安装SD。 Stable Diffusion一键安装器_SD一键启动器-Stable Diffus…

LeetCode:459. 重复的子字符串 —【2、KMP算法】

🍎道阻且长,行则将至。🍓 🌻算法,不如说它是一种思考方式🍀 算法专栏: 👉🏻123 一、🌱459. 重复的子字符串 题目描述:给定一个非空的字符串 s &…

Docker数据管理与Docker镜像的创建

目录 1.管理数据的方式 1.数据卷 2.数据卷容器 3.容器互联(使用centos镜像) 2.Docker镜像的创建 1.基于现有镜像创建 2.基于本地模板创建 3.基于Dockerfile创建 4.Dockerfile案例 总结 1.管理数据的方式 容器中管理数据主要有两种方式&#xff1…

c++作业

自己定义mystring类实现string功能 #include <iostream> #include<cstring> using namespace std;class myString {private:char *str; //记录c风格的字符串int size; //记录字符串的实际长度public://无参构造myString():size(10){str new …

tomcat服务搭建

系列文章目录 文章目录 系列文章目录一、Tomcat1.核心功能 二、Tomcat服务搭建1.Tomcat服务2.Tomcat 虚拟主机配置1.创建 kgc 和 benet 项目目录和文件2.修改 Tomcat 主配置文件 server.xml3.客户端浏览器访问验证 三、Tomcat多实例部署 一、Tomcat 1.核心功能 1.connector&a…

Spring Bean生命周期源码之包扫描、创建BeanDefinition、合并BeanDefinition源码

文章目录 Bean生命周期源码生成BeanDefinitionSpring容器启动时创建单例Bean合并BeanDefinition Bean生命周期源码 我们创建一个ApplicationContext对象时&#xff0c;这其中主要会做两件时间&#xff1a;包扫描得到BeanDefinition的set集合&#xff0c;创建非懒加载的单例Bea…

体验ChatGPT在具体应用场景下的能力与表现——vuedraggable的move多次触发问题

当下人工智能模型在满天飞&#xff0c;今天拿一个具体的应用场景&#xff0c;来体验下ChatGPT的能力与表现&#xff0c;看看是否能解决实际问题。 顺便填一下之前遇到的一个具体的坑&#xff1a;vuedraggable的move多次触发问题。 背景 背景是这样的&#xff0c;实现低代码开…

Hadoop启动相关命令

Hadoop启动相关配置 文章目录 Hadoop启动相关配置格式化节点的情况什么情况下Hadoop需要进行格式化节点&#xff1f; Hadoop启动步骤Hadoop的启动步骤只是start-dfs.sh即可吗 *hdfs*的web管理页面参数说明参数的评价场景 格式化节点的情况 什么情况下Hadoop需要进行格式化节点…

赛效:怎么用改图鸭进行一键Logo设计?

改图鸭工具是一款在线图像处理工具&#xff0c;可以对图片进行大小调整、添加色彩、滤镜等&#xff0c;用户使用改图鸭可快速轻松地对多种图像进行处理操作&#xff0c;另外&#xff0c;改图鸭工具还支持一键进行Logo设计&#xff0c;很多人对改图鸭工具比较陌生&#xff0c;不…

rsync 服务器备份代码

rpm -qa | grep rsync #检查rsync软件是否存在 yum -y install rsync #安装rsync服务 systemctl start rsyncd #启动rsync服务 systemctl enable rsyncd #加入rsync开机启动 systemctl reload rsyncd #重新加载rsync netstat -lnp|grep 873 #检查是否已经成功启动 firewall…