90+目标跟踪算法&九大benchmark!基于判别滤波器和孪生网络的视觉目标跟踪:综述与展望(上)
准确和鲁棒的视觉目标跟踪是最具挑战性和最基本的计算机视觉问题之一。它需要估计图像序列中目标的轨迹,仅考虑其初始位置和分割,或者以边界框的形式粗略近似。鉴别相关滤波器(DCF)和深度Siamese 网络(SNs)已经成为主要的跟踪范例,这促进了领域的重大发展。随着视觉目标跟踪在过去十年中的快速发展,本次综述基于九个跟踪基准的结果,对90多个DCF和Siamese 跟踪器进行了系统和全面的审查。首先介绍了DCF和Siamese 跟踪核心公式的背景理论。然后,区分并全面回顾了这两种跟踪范式中的共享和特定开放研究挑战。此外,论文还深入分析了DCF和Siamese 跟踪器在九个基准上的性能,涵盖了视觉跟踪的不同实验方面:数据集、评估指标、性能和速度比较。在分析的基础上,针对突出的开放挑战提出建议,从而完成调查。视觉目标跟踪(VOT)是计算机视觉中的一个基本开放问题,任务是估计图像序列中目标的轨迹和状态。VOT具有广泛的应用,包括自动驾驶、机器人、智能视频监控、运动分析和医学成像。给定任意目标对象的初始状态,VOT中的主要挑战是学习在后续帧中搜索目标对象时使用的外观模型。近年来,由于引入了多种跟踪基准,如TrackingNet、VOT2018和GOT-10K,VOT受到了极大的关注。尽管最近取得了进展,VOT仍然是一个开放的研究问题,可能比以往任何时候都更加活跃。通用目标跟踪的核心挑战是在线学习任意目标的外观模型,仅考虑其初始状态。几个现实世界的因素使学习准确的外观模型变得复杂,例如,目标对象可能经历部分或完全遮挡、比例变化和变形。此外,还有影响目标外观的环境因素,包括照明变化和运动模糊,另一个因素是场景通常包括具有相似外观的对象或背景结构,这些对象或背景容易与目标本身混淆。为了应对这些挑战,文献中提出了大量的跟踪器,这些跟踪器有助于提高跟踪的技术水平(SOTA)!在过去十年中,鉴别相关滤波器(DCF)和深度Siamese 网络(SN)一直是VOT的两个最突出的范例。在基于DCF的跟踪中,通过最小化最小二乘损失,在感兴趣区域上在线训练相关滤波器。然后通过快速傅里叶变换(FFT)卷积训练滤波器,在连续帧中检测目标。在深度Siamese 跟踪框架中,通过最大化目标和背景外观之间的距离,同时最小化两个补丁与目标本身之间的距离来离线学习嵌入空间。SN由两个相同的子分支组成:一个用于目标模板,另一个用于搜索区域。网络将模板和搜索区域都作为输入,并输出搜索区域中每个位置与目标的局部相似度。随着DCF和SN的设计,近年来跟踪界主要关注这两种范式,多年来,这两个框架显著提高了若干数据集的跟踪性能,如VOT数据集的性能改善,如图1所示。本文对流行的基于DCF和Siamese 的跟踪范式进行了系统的回顾。两种范式都有相同的目标,即学习一个准确的目标外观模型,该模型可以有效地将目标对象与背景区分开来。尽管在解决上述目标方面出现了不同的基本范式,但深度学习给这两种范式带来了一些重要的相似之处和共同的挑战。例如,(i)特征表示:两种范式都利用不同的特征表示来估计目标平移和尺度变化,利用从预训练网络中提取的深度特征表示是两种范式共享的最近趋势。然而,在这两种跟踪范式中,深度架构和特征层次的选择仍然是一个开放的问题。(ii)目标状态估计:DCF和Siamese 跟踪器的核心公式仅涉及如何估计目标对象的平移。因此,两种范式都没有提供用于估计完整目标状态的显式方法,例如,处理由边界框参数化的细长对象,这在大多数应用中至关重要。(iii)离线培训:虽然最初只有Siamese 跟踪受益于端到端离线培训,但最近的DCF跟踪[5]、[24]也利用大规模离线学习,将其与高效且可区分的在线学习模块集成,以实现稳健的跟踪!这两种流行的范式虽然有共同的属性,但也有特定的问题。例如,(i)边界伪影:DCF跟踪器通常利用训练样本的周期性假设来学习在线分类器,这引入了严重降低目标模型质量的不期望的边界效应。(ii)优化:损失函数最小化也给DCF跟踪器带来了挑战,特别是当目标特定约束(如空间或时间等)在回归损失内正则化时。(iii)在线模型适应性:当目标外观因照明条件或快速运动等的变化而发生变化时,预计学习的模型能够应对这些变化。DCF跟踪器具有通过损失函数随时间更新外观模型的能力。在第一帧,DCF通过FFT有效地建立前景和背景的模型,保证目标周围的高斯峰值响应。另一方面,Siamese跟踪没有继承这种在线模型更新机制。Siamese 跟踪器要么依赖于预训练的特征空间的适合性以及其中的互相关,要么通过微调深度网络来适应当前对象和背景,这在计算上是昂贵的操作,因此,在线适应性是Siamese 跟踪器的一个重要问题!此外,还有一些概念可以在两种范式之间相互转化。例如,可以在端到端DCF跟踪pipelines中使用基于深度anchor的或anchor-free的边界框回归,DCF跟踪器利用了更深层次网络的潜力,ResNet驱动的DCF跟踪器可以进一步用于稳健的外观建模。虽然只有DCF跟踪器具有在线更新外观模型的能力,但该组件也可用于Siamese跟踪管道中的时间外观建模。Siamese跟踪器采用了鲁棒的多通道特征融合,其中离线优化了权重,DCF跟踪器缺乏这种能力,因此可能利用这种技术。Siamese跟踪器可以从空间或时空正则化中受益,以在计算互相关层内的相关响应图时惩罚背景像素。这些见解为基于两种范式中的最佳模式开发强大的跟踪框架开辟了新的可能性。本次调查与之前的VOT调查之间的主要差异如下。与以往的VOT调查不同,本文仅关注两种表现最好的跟踪范式,即DCF和SN。论文提出了DCF和Siamese跟踪核心点以及广泛的背景理论。然后,提供了90多个DCF和Siamese跟踪器的概述,以及这两种范式向基于分割的跟踪演变。DCFS和Siamese跟踪范式介绍1.鉴别相关滤波器判别相关滤波器(DCF)是一种用于学习线性回归的监督技术。近年来,基于DCF的跟踪器在多个跟踪基准上表现出优异的性能,DCF成功的关键是通过循环移位训练样本实现的密集采样的计算效率近似,这允许在学习和应用相关滤波器时使用快速傅里叶变换(FFT)。通过利用傅里叶变换的特性,DCF在线学习相关滤波器,通过有效地最小化最小二乘输出误差来在连续帧中定位目标对象。为了估计下一帧中的目标位置,之后将学习滤波器应用于最大响应的目标位置的感兴趣区域。然后通过用该估计值注释新样本,以迭代方式更新过滤器。标准DCF跟踪pipelines对于跟踪,DCF首先在线学习滤波器w,然后通过检测执行跟踪。一旦在当前帧中跟踪目标,则递归地学习模型,DCF跟踪pipelines的框图如图2所示。目标检测:设m为当前图像帧的编号,在其中定位目标。从上一帧中,得到滤波器w_{m-1},其自初始帧以来已被递归更新。提取以预测目标位置为中心的图像块z,这里,z具有与训练补丁x_j相同的大小N_1×N_2。然后通过应用学习滤波器使用卷积预测每个位置n的目标分数s(n)∈ Ω !Model update:2.Siamese Tracking深度学习模型彻底改变了许多机器学习应用,成功的关键是在大量数据上离线学习功能。这种离线训练模型能够从大量注释数据中学习复杂而丰富的关系,通过将其作为相似性学习问题,端到端离线训练模型也被用于通用目标跟踪。深度SNs已被广泛用于学习目标图像和搜索图像区域之间的相似性,SNs首先用于签名验证任务,然后适用于其他应用,包括指纹识别、立体匹配、地面到空中图像匹配和局部补丁描述符学习。在VOT中,离线深度网络在大量目标图像对上进行训练,以在训练期间学习匹配函数,然后在跟踪期间在线评估该网络作为函数。Bertineto等人揭示了SN的威力,并提出了VOT的完全卷积SN(SiamFC),SiamFC使用了主干特征提取器,并比较了相似性以确定目标对象在每个帧中的位置。它还利用了使搜索可行的完全卷积特性,并被大多数后续基于SNs的跟踪器采用。SiamFC由两个分支组成,模板分支和检测分支。模板分支接收前一帧中的目标图像块作为输入,而检测分支接收当前帧中的图像块作为输出。这两个分支共享CNN参数,使得两个图像块编码适合于跟踪的相同变换,SiamFC的跟踪pipelines如图3所示。SN的主要目的是克服预训练的深度神经网络的局限性,并充分利用端到端学习的优势在实时应用上。离线训练视频用于指导Siamese 跟踪器处理各种跟踪挑战,包括旋转、视点变化和照明变化等,并在连续帧中定位目标对象!训练pipelines在SiamFC中,考虑一对训练图像(x,z),大小为127×127×3的输入x是从第一帧中目标的GT框导出的参考图像。大小为255×255×3的输入z是每个帧的较大搜索区域。将这些对(x,z)输入到CNN中以获得两个特征图(例如,使用主干架构的最后一层)。通过使用相同权重的相同子网络,参考图像被编码为大小6×6×128的特征向量,搜索区域被嵌入为大小为22×22×128的特性向量,然后使用互相关来匹配两个特征图!目标是响应图g_ρ(x,z)的最大值对应于目标位置,为了实现这一目标,网络在从视频集合中提取的数百万对随机对上进行离线训练,以跟踪通用对象,logistic loss的平均值通常用于训练网络:测试pipelines为了证明SiamFC的有效性及其在大规模数据集上训练时的泛化能力,采用了一种简单的跟踪算法,首先提取新帧中x和z的特征表示。然后将x的特征表示与z的特征表示进行比较,这是通过提取以先前估计为中心的窗口在每个新帧中获得的位置,面积为目标大小的四倍。然后对两个特征图进行互相关,得到大小为17×17×1的分数,还对相关图使用余弦窗来惩罚大位移。分数图中最高分数的位置被恢复到其相应位置,该位置被选为该帧的预测边界框中心。最初的SiamFC跟踪器在GPU上以140FPS的实时速度获得了令人惊讶的好结果。但是,它不会更新模型,因此无法处理较大的外观变化。本着同样的精神,Tao等人提出了SINT,其中欧几里得距离被用作相似性度量,而不是互相关,Held等人提出了GOTURN,其中使用了边界框回归。类似地,Valmadre等人提出了CFNET,其中相关滤波器作为匹配函数中的单独块添加到x中,并使该网络更浅但更有效。凭借这些跟踪优势,SiamFC还缺少目标规模估计组件。为了解决这个问题,区域建议网络(RPN)用于预测传统SiamFC跟踪器内的目标规模,RPN获取输入图像并估计一组矩形目标建议,每个建议都有一个对象性得分,为此,在最后一个卷积层输出的卷积特征图上滑动一个小网络。Li等人提出了SiamRPN跟踪器,该跟踪器包含RPN组件。SiamRPN的输出包括一个分类和一个回归分支,用于对位置和尺度估计的目标边界框进行回归。与经典SiamFC跟踪器相比,SiamRPN显示出更高的精度,因此,SNs在推理和离线学习中都具有计算效率。SNs已经证明了SOTA跟踪性能,因此在跟踪社区中受到了很多关注,图4显示了文献中有影响力的Siamese 追踪器!DCFS和Siamese 跟踪范式的常见开放问题本节主要讨论两种范式的共同挑战,包括主干架构、目标状态估计、这些跟踪器向基于分割的跟踪器演变,以及将这些跟踪器集成到多目标跟踪pipelines中。主干结构在离线训练中,骨干特征提取网络在捕获目标的低级细粒度和高级语义信息方面起着主导作用。这里,骨干网络,如AlexNet、VGG-16或VGG-19和ResNet18或ResNet50,用于优化跟踪数据集上的深度特征。与依赖于预训练的网络不同,任务特定的深度特征学习有助于改进跟踪问题本身的表示,这两种跟踪模式都证明了使用强大骨干网络取得了令人鼓舞的性能。例如,Valmadre等人提出了一种CFNET,它以离线方式跟踪相关滤波器的端到端学习。CFNET采用AlexNet模型的变体,并利用所有卷积层进行消融研究。第二个卷积层显示了有希望的跟踪结果。其他跟踪器,如CREST[118]和ACFN[18]也以在线方式遵循相同的策略。CREST利用VGG-16模型从conv4-3层提取特征图,使用PCA降维将特征通道减少到64个。在这些跟踪器中,目标是改进目标回归。与利用从预训练网络中提取的深度特征的跟踪器相比,这些方法表现出了相当的性能。最近,ATOM中引入了端到端目标尺度估计组件,而DiMP和PrDiMP中改进了经典DCF模型的分辨强度,ATOM利用ResNet-18预训练模型作为骨干网络。对于目标分类,它使用块4特征,而目标估计组件同时使用块3和4特征。DiMP和PrDiMP采用ResNet-18和ResNet-50 backbone架构,他们利用从第三块提取的特征进行模型预测。DCF跟踪器中端到端特征学习的最新趋势[5],[24],[26]在多个基准上产生了优异的跟踪性能,为探索DCF中更复杂的端到端特性学习铺平了道路。在早期的Siamese 跟踪器(例如,SiamFC、GOTURN、SINT、SiamRPN)中,对修改的预训练AlexNet进行了微调。SiamFC使用五层提取卷积特征,并利用最后一层特征进行离线训练。GOTURN使用所有层提取特征,并利用最后一个完全连接层的特征来训练目标函数。使用从主干提取的一组不同特征,SINT显示出显著的性能改进。SiamRPN固定了前三个卷积层,仅微调了最后两个卷积层。各种跟踪器(FlowTrack、MemTrack和EAST)也使用了AlexNet。然而,据观察,这些跟踪器的性能仍然有限,因为AlexNet是一个相对较浅的网络,并且不会产生非常强的特征表示。Li等人提出了ResNet驱动的SiamRPN++跟踪器,在SNs中,当在没有零填充的情况下使用修改的AlexNet时,目标的学习空间特征表示不满足空间平移不变性约束。SiamRPN++采用了ResNet-50架构,并对其进行了一些改进,以适应跟踪任务,SiamRPN++利用conv3、conv4和conv5块的输出,并将它们送入三个SiamRPN模块。对于多层特征融合,还引入了加权和和深度互相关模块,提出了一种融合不同卷积块的丰富特征表示的分层聚合。三个RPN模块的输出具有相同的空间大小。三个输出的加权和用于生成最终特征图,权重与网络一起离线端到端优化。由于深度架构,SiamRPN++可能具有更多的参数,这些参数需要更多的计算资源,并降低了跟踪速度。因此,与前代相比,跟踪器还配备了深度互相关层以提高效率。在搜索区域和模板区域之间执行深度方向的互相关,以获得多通道响应图,然后将响应与1×1核卷积,以将其维数减少到更少的信道。使用该技术,通过降维显著减少了参数的数量,并稳定了训练过程,最后的降维响应图被用作分类和回归分支的输入。利用深度ResNet架构,许多Siamese 跟踪器的性能得到了改善。Zhang等人也研究了相同的问题,并提出了SiamDW,其中浅骨干AlexNet被深度网络取代,包括Inception、VGG-19和ResNet。据调查,除了特征填充之外,神经元的感受野和网络跨步也是这样一个更深的网络不能直接取代浅层网络的主要原因。此外,还评估了来自不同层和不同架构的特征,并将性能最佳的候选特征和架构用于跟踪器。这两项研究中的结果表明,与经典的基于SNs的跟踪器相比,具有优异的性能。有了这些基础,包括SiamCAR、Ocean和SiamBAN等在内的最新跟踪器也采用了强大的深度架构。这些最近的跟踪器从ResNet-50的最后三个残余块中提取特征,并融合以获得多通道响应图。ResNet骨干网由于其简单性和强大的性能,已成为Siamese 跟踪的既定首选方案。此外,深度互相关对于获得多通道特征图也引起了极大的关注。然而,视觉transformer网络的最新进展预计将在未来几年对跟踪社区产生重大影响。目标状态估计这两种跟踪范式在准确性和鲁棒性方面都显示了很有希望的结果。但是,当目标移动时,其模板大小(也称为边界框大小)也会发生变化,这两种范式都面临严重的scale变化挑战。因此,准确的尺度估计对这些跟踪器提出了巨大的挑战,处理bounding box大小以实现精确的目标尺度估计是一个既定的研究方向。跟踪社区在这方面取得了显著进展,并提出了处理这一问题的潜在解决方案,本文讨论了为两种范式提出的尺度估计方法!多分辨率尺度搜索方法:DCF中的一种直接策略是在不同的图像尺度上应用学习的平移滤波器w。也就是说,首先通过不同的比例因子调整图像的大小,然后进行特征提取。将每个尺度上的特征图与学习滤波器w卷积以计算目标分数,就可以通过找到所有尺度上的最大得分来估计目标位置和尺度的变化。这是一种常见的策略,通常应用于跟踪和检测。Li等人提出了SAMF跟踪器,其中使用标准DCF公式联合训练平移和缩放滤波器,结果表明,与标准DCF相比,性能显著提高。这种比例自适应组件已用于许多基于DCF的跟踪器,如CACF、CFAT和FD-KCF。然而,这种方法具有较高的计算成本,因为必须以多个分辨率应用平移滤波器以实现缩放精度。Siamese 跟踪器也受益于这种scale估计方法,在经典SiamFC中,通过组合一小批缩放图像,在一次前向扫描中搜索多个尺度,然后计算最大响应。包括RASNET、SA Siam、StructSiam、UDT、UDT++、TADT、GradNet、RTINET和FlowTrack在内的早期跟踪器都采用了这种方法。判别尺度空间搜索方法:Danelljan等人提出了DCF跟踪中精确尺度估计的替代策略。与[79]不同,目标估计分两步进行,以避免exhaustive search在尺度和平移上。由于两个帧之间的尺度变化通常较小或中等,因此首先通过在当前尺度估计处应用正常平移滤波器w来找到目标平移。然后,在比例维度中应用单独的一维filter来更新目标大小。尺度滤波器类似于平移滤波器进行训练,但通过从一组不同尺度中提取目标外观的样本来在尺度维度上操作。上述比例滤波器方法的优点有两方面。首先,通过减少搜索空间来提高计算效率;第二,训练尺度滤波器以区分不同尺度下目标的外观,这可以导致更准确的估计。所提出的比例滤波器组件已用于多种跟踪器,包括STAPLE、MUSTer、ASRCF、CACF、BACF、CSR-DCF、MCCT和LCT。此外,后续的fDSST跟踪器通过应用PCA和子网格插值减少了DSST的计算成本。Siamese tracker无法探索这种scale估计技术!边界框回归方法:上述方法显示了改进的性能,然而,它们取决于比例因子参数和在线准确的滤波器响应,这些方法不会以离线方式利用深度特征表示。因此,这些方法在出现突然的scale变化时表现出性能下降。精确的目标尺度估计是一项复杂的任务,需要高层次的先验知识。边界框取决于目标的姿态和view,不能将其建模为简单的图像变换(例如,统一图像缩放),因此,在线学习准确的目标估计非常困难!在目标检测方法中,box回归已被广泛用于目标精确定位。为了利用端到端深度特征学习的优势进行目标尺度估计,该组件最近被用于基于DCFs的跟踪器。在ATOM中,受IoU Net的启发,训练了特定于目标的特征。由于原始IoU Net是类特定的,因此不适合通用跟踪,因此提出了一种新的架构,用于将目标特定信息集成到IoU预测中。这是通过引入基于调制的网络组件来实现的,该组件将目标外观结合在参考图像中以获得目标特定的IoU估计,这进一步使目标估计组件能够在大规模数据集上离线训练。在跟踪期间,通过简单地最大化每个帧中的预测IoU重叠来找到目标边界框。结果表明,与经典的多尺度搜索方法相比,性能有了显著提高。最近的几个DCF跟踪器,包括DiMP、PrDiMP和KYS,也使用了这种策略进行状态估计。在PrDiMP中,它使用基于能量的模型来预测边界框的非归一化概率密度,而不是预测IoU。这是通过最小化KL散度到标签噪声的高斯模型来训练的。Siamese tracker还探索了用于尺度估计的bounding box方法。文献中提出了两种不同类型的方法,包括基于anchor的和anchor-free的box回归。Anchor-based Bounding Box Regression Method:Li等人提出了RPN驱动的Siamese 跟踪器,其输出分类(Lcls)和回归(Lreg)分量,用于估计位置和比例。与采用多尺度搜索进行尺度估计的SiamFC不同,SiamRPN首先在每个卷积特征地图位置初始化不同尺度和纵横比的前K个方案(即所谓的锚),并应用一些策略来确定其中的最佳方案。它丢弃了生成的距离中心太远的边界框,并通过对分数应用余弦窗口和比例变化惩罚来重新排列提案。RPN共享特征,从而实现高效的区域建议计算。与经典的多尺度空间搜索方法相比,该方法改进了Siamese 跟踪范式。许多最新的跟踪器,如DaSiamRPN、SiamRPN++、SiamDW、SPLT、C-RPN、SiamAttn、CSA和SPM等,也基于相同的概念。Anchor-free Bounding Box Regression Method: Chen等人提出了SiamBAN跟踪器,其中使用anchor-free box回归来估计目标scale。跟踪器避免了与没有任何预设锚框的目标边界框关联的超参数。跟踪器利用全卷积网络的表达能力对目标进行分类,并以统一的方式回归其边界框。与SiamRPN类似,SiamBAN包括分类模块,其对相关层的每个点执行前景背景分类,回归模块对相应位置执行边界框预测。虽然基于anchor的边界框回归可以处理Siamese 跟踪器中的比例和纵横比变化,但它主要有两个缺点。首先,它通常需要一组非常大的anchor来覆盖图像中的几乎所有对象,并且由于图像中的目标可能只占据很小的区域,在正样本和负样本之间产生巨大的差距,这会大大降低预测模型的性能。其次,anchor的使用引入了许多超参数和选择,包括anchor的数量、尺寸和纵横比。在某种程度上,更好的跟踪结果在很大程度上取决于预设的anchor。另一方面,基于anchor-free边界框回归的跟踪器不需要选择具有先验知识的框。它的最大优点是根据网络的输出直接预测对象的类别和位置信息,而无需设置先验框的繁琐过程。由于其简单和方便,与基于anchor的RPN尺度估计方法相比,anchor-free跟踪器进一步提高了跟踪性能。Ocean和SiamCAR跟踪器也使用了相同的方法进行尺度估计,目标检测能力在两种范式的目标状态估计组件中都取得了显著进展。使用RPN和anchor-free边界框回归的最新趋势揭示了在端到端模式中进一步探索这些技术。基于深度DCF的跟踪器还可以利用这些基于anchor的和anchor-free的回归方法进行鲁棒跟踪。Offline Training为了解决这个问题,跟踪社区通过利用外部图像和视频数据集学习外观模型,取得了显著进展。目标检测、图像分类和目标分割数据集(包括ImageNet ILSVRC2014、ILSVRC2015、COCO、YouTubeBB和YouTube VOS)已被这两个跟踪器家族广泛使用。这些数据集充分覆盖了大量的语义,并且不关注特定的对象,否则,调整后的网络参数将过度适合离线训练中的特定对象类别,数据集通常用每帧中目标对象的边界框进行注释。端到端DCF跟踪器充分利用大规模训练数据集来学习稳健的判别模型。例如,CFNET、ATOM、DiMP和PrDiMP使用了TrackingNet、LaSOT、GOT10K、ILSVRC2014和COCO数据集以及一些增强技术。DiMP从序列中输入一组多个训练样本,并在成对的训练和测试集上进行训练。每组由与其边界框配对的图像组成,然后使用训练样本预测目标模型,在测试帧上进行评估,ATOM和PrDiMP跟踪器采用了相同的策略。在Siamese 跟踪中,使用图像对训练网络,使用一幅图像预测目标模板,另一幅图像评估跟踪器。与DCF范式不同,标准Siamese 公式不能在跟踪过程中利用已知干扰物的外观。因此,当与目标本身相似的物体出现时,Siamese 的方法往往会遇到困难。例如,当视图中有相同语义类的其他对象时,就会发生这种情况。早期Siamese tracker在训练期间仅从同一视频中采集训练图像对,这种抽样策略不关注具有语义相似的干扰物对象的挑战性案例。为了解决这个问题,文献中已经开发了hard negative开采技术。例如,Zhu等人在DaSiamRPN中引入了hard negative挖掘技术,通过在训练过程中加入更多的语义hard negative对来克服数据不平衡问题。构建的负对由相同和不同类别的标记目标组成,该技术帮助DaSiamRPN通过更多地关注细粒度表示来克服漂移。Voigtlander等人提出了另一种使用嵌入网络和最近邻近似的hard negative挖掘技术。对于每个GT边界框,使用预训练的网络为相似的目标外观提取嵌入向量。然后使用索引结构来估计近似最近邻居,并使用它们来估计嵌入空间中目标对象的最近邻居。利用更多训练数据和设计数据挖掘技术的这一最新趋势已在多个基准上显示出优异的跟踪性能,为探索离线训练中更复杂的技术打开了许多大门!两种范式向基于分割的跟踪器演变精确的目标分割为跟踪提供了可靠的对象观察,分割和跟踪的结合可以解决几个跟踪问题,包括旋转边界框、遮挡、变形和缩放等,并从根本上避免跟踪失败。因此,分割分支可以充当跟踪器的补充组件。在文献中,基于分割的方法已被纳入DCF和基于Siamese的跟踪器中,用于在存在非矩形目标的情况下改进滤波器学习。例如,在DCF跟踪中,Bertineto等人使用基于颜色直方图的分割方法来改善在变化的照明变化、运动模糊和目标变形下的跟踪。Lukezic等人提出了一种使用基于颜色的分割方法来正则化滤波器学习的空间可靠性图,提出了一种使用手工特征的实时跟踪器,并使用深度特征实现了类似的性能。Kart等人将CSR-DCF跟踪器扩展为基于颜色和深度分割的RGB深度跟踪,因为深度线索提供了更可靠的分割图。Lukezic等人提出了一种单镜头分割跟踪器,以解决联合框架内的VOT和视频目标分割问题。目标用两个判别模型编码,用于联合跟踪以及分割任务。许多跟踪和分割基准都报告了结果,并证明了其好处。最近,Robinson等人使用从ATOM借来的快速优化方案,为视频对象分割任务采用了一种强大的判别模型,Bhat等人也使用目标模型辨别能力进行更稳健的视频目标分割。最近,SNs也被扩展以执行视频对象分割和跟踪。Siamese跟踪器速度很快,提供实时性能,而视频分割方法速度慢且不实时,因此,将这两个问题结合起来,可以为跟踪和分割提供有效的解决方案。Wang等人提出了一个SN来同时估计二进制掩码、边界框和相应的背景前景得分,这种多级深度网络缺乏联合处理视觉跟踪和目标分割以提高鲁棒性的机会。Lu等人采用了无监督视频对象分割任务,其中基于SN[90]内的共同关注机制提出了一种新的架构。多目标跟踪pipelines中两种范式的集成多目标跟踪(MOT)是估计视频序列中多个目标的轨迹的任务。MOT具有挑战性,因为成功的方法不仅需要在每一帧中准确检测感兴趣的对象,还需要在整个视频中关联它们。尽管DCF和Siamese跟踪器有希望朝着单目标跟踪的方向发展,但这两种范式也已集成到MOT管道中,以定位每帧中的多个目标。例如,Zhu等人在统一框架中集成了ECO跟踪器,以处理鲁棒目标关联的噪声检测[173]。Chu等人将区分性实例感知KCF跟踪器集成到MOT框架中[20]。最近,Zhou等人,基于综合分割的判别跟踪器用于多对象分割[171]。跟踪器分支在线训练每个目标的单独单个目标跟踪模型,以将目标与其周围目标区分开来。Taixe等人提出了MOT中第一批用于目标关联的SN。Yin等人整合了经典的SiamFC跟踪器,并提供了一个统一的模型来估计对象运动和亲和网络。最近的研究还成功地整合了SiamRPN和GOTURN跟踪器,以在存在闭塞的情况下提高MOT性能。上述MOT方法提高了鲁棒性,并减轻了在存在单个对象跟踪器的情况下对外部检测器的依赖。利用单目标跟踪范式作为MOT模型的一个组成部分的这一最新趋势在多个基准上表现出了优异的性能,为进一步探索DCF和SN的固有特性开辟了新的方向!原文首发微信公众号【自动驾驶之心】:一个专注自动驾驶与AI的社区(https://mp.weixin.qq.com/s/NK-0tfm_5KxmOfFHpK5mBA)
HTTP 常见认证方式
常见的核对身份方法有:1.密码2.动态令牌,比如OTP3.数字证书,U 盾之类的4.生物认证,指纹,面部识别,虹膜等5.IC 卡等。常见的HTTP 认证方式有哪些呢?1.Basic 认证2.DIGEST 认证3.SSL 客户端认证4.FormBase 认证一. Basic 认证 步骤客户端说我要这个资源。服务器端返回没有认证,需要认证。客户端发送Base64编码后的用户名和密码给服务器端,服务端校验,通过200, 失败401. 安全级别不高,所以大多数网站不使用。二. DIGEST 认证客户端发送请求,服务端给个质询码,和没有认证的401. 客户端发送质询码, 服务端校验,通过200, 失败401.DIGEST 认证安全级别也不高,所以很多网站都没有使用。三. SSL 客户端认证步骤步骤 1:客户端发送需要认证的请求。步骤 2: 服务器会发送 Certificate Request 报文,要求客户端提供客户端证书。步骤 3:客户端会把客户端证书信 息以 Client Certificate 报文方式发送给服务器。 步骤 4:服务器验证通过,获取证书内客户端的公开密钥,然后开始 HTTPS 加密通信也有SSL的双因子认证。虽然安全,但是费用过高。四. 基于表单的认证客户端给服务器端发送登录信息,根据登录信息的验证结果进行验证。因为表单认证方法的标准规范不像SSH 或者FTP 协议,所以Web 应用程序实现的基于表单的认证方法各不相同。因为实现方式不同,所以安全级别也各不相同。以上就是HTTP认证相关内容, 你学会了吗?如果觉得阿萨的内容对你有帮助,欢迎围观点赞。
数据结构上机实践第八周项目5 - 计数的模式匹配
计数的模式匹配模式匹配在生活中运用广泛,日常所见的指纹识别,人脸识别......无一不用到模式匹配,为了体现模式匹配的基本思想,本次实践将实现简单的字符串的计数模式匹配。项目要求如下:采用顺序结构存储串,编写一个算法计算指定子串在一个字符串中出现的次数,如果该子串不出现则为0。本次实践所用到的算法库点击此处参考实现源代码如下://*Copyright (c)2017,烟台大学计算机与控制工程学院*
//*All rights reservrd.*
//*文件名称 :main.cpp*
//*作者:田长航*
//*完成时间:2017年10月23日*
//*版本号:v1.0*
//*问题描述:算法库测试函数*
//*输入描述:无*
//*程序输出:测试结果*
#include <stdio.h>
#include "sqString.h"
int str_count(SqString s,SqString t)
{
int i=0,j=0,count=0;
while (i<s.length && j<t.length)
{
if (s.data[i]==t.data[j]) //继续匹配下一个字符
{
i++; //主串和子串依次匹配下一个字符
j++;
}
else //主串、子串指针回溯重新开始下一次匹配
{
i=i-j+1; //主串从下一个位置开始匹配
j=0; //子串从头开始匹配
}
//在BF算法中,没有下面的这一部分
//这里增加一个判断,可以“捕捉”到已经产生的匹配
if (j>=t.length) //如果j已经达到了子串的长度,产生了一个匹配
{
count++; //匹配次数加1
i=i-j+1; //主串从下一个位置开始继续匹配
j=0; //子串从头开始匹配
}
}
return(count);
}
int main()
{
SqString s,t;
StrAssign(s,"accaccacacabcacbab");
StrAssign(t,"accac");
printf("s:");
DispStr(s);
printf("t:");
DispStr(t);
printf("%d\n",str_count(s,t));
return 0;
}运行结果截图如下:
IIFAA技术探索-无感控车
IIFAA是互联网金融身份认证联盟“Internal Internet Finance Authentication Alliance”的简称,成立于2015年,致力于围绕身份认证及生物识别技术,推出“金融级、全链路、标准化”的行业安全解决方案,现阶段已覆盖设备超过16亿。蚂蚁金服作为IIFAA联盟的主要发起方,除手机终端外,积极探索IoT场景下的认证技术,并在数字车钥匙等场景落地。本文对数字车钥匙领域常见的无感入车技术进行介绍,主要包括行业现状、技术发展方向以及IIFAA团队在探索中遇到的问题和相应的解决思路。数字车钥匙汽车钥匙的变迁大约经过了如下图几个阶段,由摇摆钥匙(也称工型钥匙)、机械钥匙到后面的芯片钥匙、遥控钥匙。钥匙的发展,除了提供给用户更丰富的功能外,还显著提高了钥匙的安全水位。随着移动互联网的发展,以手机为代表的数字车钥匙技术日渐成熟,并有替代实体钥匙的趋势。相较于实体钥匙,数字车钥匙的功能更丰富,比如定位、分享、远程控车等,在使用体验上具有明显的优势。除了四轮汽车,数字车钥匙也应用到二轮电瓶车领域,小牛、九号、哈罗等厂商把车辆智能化作为产品主打方向。IIFAA团队基于在手机生物认证等安全领域的沉淀,于2020年推出了四轮车数字车钥匙,主要面向四轮车后期改装的场景(简称:后装);在2021年和雅迪合作推出了二轮车的数字钥匙方案,并上线了“雅迪智享”小程序,助力雅迪向智能化迈进;2022年,团队继续深耕数字车钥匙领域,并在设备认证、行业标准化等方向取得了显著成绩。下图左侧是面向四轮车的“数字车钥匙”小程序,适配大部分主流车型;右侧是和雅迪合作开发的“雅迪智享”小程序,已经应用到雅迪的多个车型。无感入车中高端的四轮汽车,无感入车几乎已经成为标配功能。用户携带手机或者实体钥匙在车辆周围时,车机端根据近场通信信号,进行用户认证和距离判断,进而自动触发解落锁。按照发展历史,无感入车依赖的底层技术主要包括射频、蓝牙和UWB三个阶段。现阶段仍在广泛使用的实体钥匙基于射频信号进行信号传输;得益于蓝牙的低功率特性以及手机端的全面覆盖,数字钥匙主要基于蓝牙进行通信;在未来,随着手机终端的支持,UWB会广泛应用到数字钥匙的无感入车领域。射频无感四轮车和二轮车的实体钥匙,底层基于 433MHz 或 315MHz 的射频信号进行信号传输,因此也被称为射频钥匙。由于射频模块的功耗相对较高,射频无感车机端的处理模式主要分为以下两种:1、车辆中的基站单元不停地发送一条编码为125kHz的低频报文以搜寻并唤醒一定范围内的应答器。该信号范围内的所有应答器都能够接收到该报文,对编码的数据字段进行验证。一旦钥匙上的应答器识别成功,它会自动发送一条频率为433.92MHz的射频Keeloq编码报文,车机端的基站单元在收到该报文后对其进行解码,如果识别成功,将控制指令执行机构打开车门。2、车辆中的基站单元一般处于休眠状态或掉电状态,只有当触发事件发生时才能将其唤醒,该触发事件一般是车门把手上的红外信号或者是由车门把手装置激活的微动开关。车主必须碰一下车门才能触发系统,从而打开车门。车辆感应区域划分上比较简单,主要分为车门区域和后备箱区域:实体钥匙的无感,在使用体验上经过了大量用户的验证,但由于使用的加密算法复杂度相对不高,被攻克的概率较大,安全性是一个潜在风险。蓝牙无感基于蓝牙的数字钥匙在最近几年得到了快速发展,对标实体钥匙的无感功能,基于蓝牙的无感被广泛的研究和应用。蓝牙无感的工作原理入下图所示,核心包括两点:1. 基于数字钥匙进行身份认证,2. 基于蓝牙进行测距。根据车机端蓝牙模块(天线)的数量和蓝牙工作模式的差异,蓝牙无感主要可以有多种组合方式,并有相应的应用场景:车机端天线数量单天线:定位精度低,空旷情况下可以达到1-2米,适用于二轮车以及后期改装的四轮车(简称:后装)。多天线:定位精度高,可以达到0.3米。但由于成本、安装工艺的限制,适用于产线集成无感的四轮车(简称:前装)。手机端蓝牙工作模式保活:通过手机应用的保活,进行数据传输和蓝牙工作模式的切换。但由于保活难度高而且蓝牙多桩定位需要手机端蓝牙开启从机模式(Slave)进行蓝牙广播,因此主要应用于前装四轮车。配对:基于蓝牙的HID协议,实现手机和车机蓝牙的快速连接。配对不需要应用保活,也就无法控制手机侧蓝牙的工作模式,进而无法进行业务数据传输,因此主要适用于车机端单蓝牙场景,通常是二轮车以及后装四轮车。概括起来,二轮车和四轮车采用的方案主要有以下几种组合方式:技术前装四轮车后装四轮车二轮车单天线✅✅多天线✅保活✅配对✅✅本文后续会针对单天线、多天线、App保活和配对展开介绍。UWB无感概念介绍UWB(Ultra Wideband) 是一种无载波通信技术,利用纳秒至微秒级的非正弦波窄脉冲传输数据,通过在较宽的频谱上传送极低功率的信号,它能够非常准确地测量无线电信号的飞行时间,从而实现厘米精度的距离/位置测量。和WIFI、蓝牙对比,UWB的在多方面有了显著提升,尤其在定位精度上具有广阔的应用前景:应用场景UWB作为一种新型技术,现阶段只有苹果、小米部分手机机型支持。在应用场景上,2021年苹果发布了支持UWB技术的Airtag,同年8月小米随着小米Mix4手机发布了“一指连”功能。头部手机厂商的对UWB技术的探索,带动了更多手机厂商、设备厂商、汽车厂商对UWB技术的研究。下面左图是iphone11系列开始搭载了U1芯片,右图是AirTag搭载了同块芯片。 小米Mix4手机搭载了UWB技术,并且应用到米家IoT场景。2021年,汽车连接协会CCC(Car Connectivity Consortium)发布了《数字车钥匙3.0版本规范》,把低功耗蓝牙(BLE)和超宽带(UWB)技术作为无感入车的基础技术方案。行业内通用的UWB的布局如下图所示,BLE模块负责和手机端进行通信,并唤醒手机端和车机端的UWB模块进行工作,UWB模块进行高精度定位,并通知车机端进行解落锁操作。关键技术前一部分对无感入车的发展历史以及相关技术进行了概括性介绍,这部分主要介绍进行蓝牙无感探索时遇到的一些问题和解决思路。在过去两年的时间里,团队在业务推进中覆盖后装四轮车、前装四轮车、二轮车,也因此对所有无感相关的关键技术进行了比较深入的研究,主要包括单蓝牙测距、多蓝牙(UWB)测距、手机App保活和蓝牙配对。单蓝牙测距蓝牙信号处于2.4G共用频段,干扰比较多,而且12CM的波长容易被阻挡,因此通过蓝牙信号进行测距精度误差比较大。实测下来,在空旷场所,单蓝牙测距精度能做到1-2米。我们在基于单蓝牙实现无感入车时,主要创新有两点:基于信号强度RSSI进行模糊化测距和更快捷的设置交互。测距算法蓝牙信号强度RSSI和物理距离的转换,有一个经验公式:计算公式:
d = 10^((abs(RSSI) - A) / (10 * n))
其中:
d - 计算所得距离
RSSI - 接收信号强度(负值)
A - 发射端和接收端相隔1米时的信号强度
n - 环境衰减因子从参数可知,这种测距的误差会比较大,而且蓝牙信号的RSSI值一直处于跳变状态。为此在工程上,只对RSSI信号进行处理,把处理后的RSSI值作为距离的表征值。 通过多次优化,我们找到了一个效果比较好的平滑算法,可以“削峰抑谷”,较好地反应信号强度的变化趋势。下图蓝色是实际蓝牙信号强度,橙色是平滑后的信号强度:RSSI的平滑处理算法,概括起来包括分为以下几类:限幅。通过限定信号的变化幅度,降低信号突变的影响中位值。排序取中间值。算术平均。通过一定量的信号强度进行平均,作为实际值中位值平均。采一组队列去掉最大值和最小值,然后取均值。根据蓝牙协议,1秒钟能采集到20-50个信号强度,采样频率足够高。综合上述几种算法的特点,加上蓝牙高频率采样值,我们在工程上综合多种多种算法,实测下来平滑效果满足期望。交互优化依据RSSI设置开落锁的距离,在交互上对用户有较大的困扰。用户并不知道“-80”或者“80”的数值代表什么,为此我们在交互上进行优化。一方面通过引导用户在一个期望位置进行信号强度采集,完成开落锁位置的设定;另一方面提供“远中近”的经验设定,满足用户不同体验的需要: 发展方向为了提高蓝牙的测距精度,蓝牙V5.1引入了AoA和AoD高精度定位法。AoA定位是基于到达角度进行定位,AoD是基于出发角度进行定位。由于蓝牙模块成本和工艺的上升,以及手机端蓝牙模块的覆盖度还不够高,这两种方法现阶段还处于实验室阶段。随着更多设备的支持,在不远的将来单蓝牙模块测距精度会提升到10cm的量级。 多蓝牙测距产线集成数字钥匙的四轮车采用多天线模块进行定位,现阶段主要是蓝牙模块,随着UWB技术的普及,其会取代蓝牙被更广泛地应用。以理想One为例,车机端蓝牙模块的经典分布如下图所示,这就是所谓的1+5模式。1个蓝牙天线工作在从机模式,持续进行蓝牙广播,负责和手机端的数据交互。A柱、B柱以及后备箱共装有5个蓝牙天线,工作在主机模式,负责监听手机侧的蓝牙广播。车机端根据5个蓝牙广播模块采集到的信号进行定位。在我们项目推进过程中,对UWB的多桩定位技术进行研究。实测下来,精度可以在10-20CM,并在多次展会上进行演示。由于多桩定位更多是算法层面的研究,这部分就不再展开。应用保活背景在介绍保活之前,先介绍下为什么在蓝牙无感需要应用保活。四轮车的无感入车,为了实现多蓝牙定位,需要手机蓝牙模式打开从模式进行广播。由于手机平台、车钥匙安全性的限制,手机蓝牙从模式不可能一直打开,需要特定时机进行唤起,此时应用保活就是一个前提基础条件:行业现状应用保活是指在用户退出应用,或者系统基于当前内存不足状态而触发清理进程后,该进程设法让自己免于被杀或者被杀后能自动拉起的手段。由于系统对运行内存和能耗的控制,iPhone和安卓对应用保活的限制主要有以下几点:iPhone主要是对内存使用的限制,在运行一些高内存应用时(比如抖音),杀死后台应用。安卓的问题比较复杂,除了内存限制外,还有耗电优化策略。相较于原生的安卓系统,国内厂商华米OV引入了省电模式,而且会默认开启。实测下来,大部分情况下,应用处于后台10分钟左右就会被杀死。鉴于应用高概率被系统杀死的现状,业内对应用保活进行了多种尝试。苹果系统相对封闭,黑科技比较少,安卓经历了多种方式的变迁,比如进程拉活、创建子进程、白名单等,但现阶段大部分都不适用。如下是一些保活的hack方法以及现状:以微信、支付宝为代表的一些大型App,由于和国内安卓厂商的合作更加密切,会有一些独特的通道实现应用的拉活。支付宝内的一些业务场景,比如语音播报和运动也有保活的诉求,比较可行的保活方式主要包括以下几类:蓝牙类:通过蓝牙的近场能力,进行拉活,这个在安卓和IOS上表现都比较稳定,但是有局限性。系统设置类:引导用户关闭省电模式、开启应用自动权限以及开启前台服务等。推送类:通过厂商提供的通道,通过push通道下发拉活应用。探索基于行业沉淀的经验以及车钥匙团队在此方面的探索,现阶段比较通用的保活方案是蓝牙拉活。以支付宝App为例,概括起来有以下几点:IOS:基于蓝牙拉活,可以满足大部分场景。安卓:a. 基于蓝牙进行拉活,成功率比较高,b. 引导用户去设置能耗策略、开启通过前台服务,实现更好的保活效果。单纯从手机App出发进行保活有较大的局限性,这也促使车企和手机厂商合作(宝马和苹果、理想和荣耀等):蓝牙配对介绍The Human Interface Device (HID)定义了蓝牙在人机接口设备中的协议、特征和使用规程。典型的应用包括蓝牙鼠标、蓝牙键盘、蓝牙游戏手柄等。设备配对的过程,主要是基于HID协议和SMP(Security Manager Protocol)进行密钥的交换,最终建立一个可自动回连的安全链路。配对的优点在车机端搭载单蓝牙的二轮车或者后装四轮车领域,配对是一个常见的方案。基于蓝牙的HID协议,可以实现蓝牙的自动连接,摆脱了对应用保活的限制。进行配对安卓系统提供了开放的配对Api,可以在应用内快速进行配对。IOS系统没有提供配对Api,需要手机和蓝牙模块进行配合,现行比较成熟的配对方式有两个:从机发起和改变服务安全等级。从机发起是指,蓝牙设备主动发起配对请求,手机端响应从机请求实现配对。改变服务端安全等级是指,通过改变蓝牙模块基础服务D_I_S(device information service)的安全等级,触发手机端进入配对流程。两种方式在手机应用侧交互形式一致,唯一的差别的是前者可以做到不需要蓝牙断连,而后者需要进行一次蓝牙断连。配对回连虽然配对基于蓝牙的HID协议,而且不同手机都默认支持,但是实测下来,回连的稳定性并没有预期的那么高。也就是配对后,手机和蓝牙模块靠近时,并不能保证100%建立连接。华为和苹果手机出现回连失败的概率比较高,他们自家生产的蓝牙耳机也有类似问题。在数字车钥匙这个场景,如果配对不回连,无感功能就无法正常运行,给用户带来比较大的体验问题。通过抓包分析,回连失败的原因是手机侧没有发起主动连接,而核心原因推测是由于蓝牙频繁断连触发了手机侧的安全和能耗策略。为此我们在蓝牙协议上进行优化,同时针对不同机型,在开通无感时对回连策略进行动态化配置,经过实测,华为、iphone等手机上,回连稳定性有了明显的提升。总结文章介绍了蚂蚁金服IIFAA团队在数字车钥匙无感入车领域一些经验和探索,欢迎大家交流。
C/C++ PeView 结构解析器
PeView 结构解析器,是一款使用C/C++开发实现的命令行交互式 WindowsPE 程序结构解析器,目前可解析32位可执行程序的绝大部分通用参数,并内置各种结构查询转换阅览工具,目前已基本可在工作中使用。GitHUB地址: https://github.com/lyshark/PeView打开PE文件: 使用Open一次性打开文件,只有打开后才可以对其进行其他操作,打开文件需要使用Open命令跟路径。[Pe View] # Open --path d://Win32Project.exe
[+] 已读入文件查询PE头数据: PE头查询命令有两个,使用Dos可查询DOS头部,使用Nt命令则可查询NT头部,目前只列出了常用字段。[Pe View] # Dos
----------------------------------------------------------------------
十六进制 十进制
----------------------------------------------------------------------
DOS标志: 00005A4D 00023117
IP入口: 00000000 00000000
CS入口: 00000000 00000000
PE指针: 000000E8 00000232
----------------------------------------------------------------------
[Pe View] #
[Pe View] # Nt
----------------------------------------------------------------------
十六进制 十进制
----------------------------------------------------------------------
NT标志: 0x00004550 00017744
运行平台: 0x0000014C 00000332
入口点: 0x0001121C 00070172
镜像基址: 0x00400000 04194304
镜像大小: 0x0001F000 00126976
代码基址: 0x00001000 00004096
内存对齐: 0x00001000 00004096
文件对齐: 0x00000200 00000512
子系统: 0x00000002 00000002
区段数目: 0x00000007 00000007
时间日期标志: 0x62D76132 1658282290
首部大小: 0x00000400 00001024
特征值: 0x00000102 00000258
校验和: 0x00000000 00000000
可选头部大小: 0x000000E0 00000224
RVA 数及大小: 0x00000010 00000016
----------------------------------------------------------------------查询数据目录表: 查询数据目录表可执行DataDirectory命令获取,其中包括了RVA,FOA,Size等基本信息。[Pe View] # DataDirectory
-------------------------------------------------------------------------------------------------------
编号 目录RVA 目录FOA Size长度(十进制) Size长度(十六进制) 功能描述
-------------------------------------------------------------------------------------------------------
001 0x00000000 0xFFFFFFFF 00000000 0x00000000 Export symbols
002 0x0001A1E0 0x00006DE0 00000080 0x00000050 Import symbols
003 0x0001B000 0x00007800 00009612 0x0000258C Resources
004 0x00000000 0xFFFFFFFF 00000000 0x00000000 Exception
005 0x00000000 0xFFFFFFFF 00000000 0x00000000 Security
006 0x0001E000 0x00009E00 00000972 0x000003CC Base relocation
007 0x00016820 0x00005020 00000056 0x00000038 Debug
008 0x00000000 0xFFFFFFFF 00000000 0x00000000 Copyright string
009 0x00000000 0xFFFFFFFF 00000000 0x00000000 Globalptr
010 0x00000000 0xFFFFFFFF 00000000 0x00000000 TLS
011 0x00017560 0x00005D60 00000064 0x00000040 Loadconfiguration
012 0x00000000 0xFFFFFFFF 00000000 0x00000000 Bound Import
013 0x0001A000 0x00006C00 00000480 0x000001E0 IAT
014 0x00000000 0xFFFFFFFF 00000000 0x00000000 Delay Import
015 0x00000000 0xFFFFFFFF 00000000 0x00000000 COM descriptor
016 0x00000000 0xFFFFFFFF 00000000 0x00000000 NoUse
-------------------------------------------------------------------------------------------------------查询节表: 查询程序中的节表可使用Section命令查询。[Pe View] # Section
----------------------------------------------------------------------------------------------------
编号 节区名称 虚拟偏移 虚拟大小 实际偏移 实际大小 节区属性
----------------------------------------------------------------------------------------------------
1 .textbss 0x00001000 0x00010000 0x00000000 0x00000000 0xE00000A0
2 .text 0x00011000 0x00004366 0x00000400 0x00004400 0x60000020
3 .rdata 0x00016000 0x00002069 0x00004800 0x00002200 0x40000040
4 .data 0x00019000 0x00000769 0x00006A00 0x00000200 0xC0000040
5 .idata 0x0001A000 0x00000AB9 0x00006C00 0x00000C00 0x40000040
6 .rsrc 0x0001B000 0x0000258C 0x00007800 0x00002600 0x40000040
7 .reloc 0x0001E000 0x00000599 0x00009E00 0x00000600 0x42000040
----------------------------------------------------------------------------------------------------查询所有导入表: 导入表的查询有多个命令,其中ImportAll用于查询所有导入过的模块以及该模块的导入函数。[Pe View] # ImportAll
---------------------------------------------------------------------------------------------------
Hint值 API序号 文件RVA VA地址 函数名称 模块: [ USER32.dll ]
---------------------------------------------------------------------------------------------------
[ 547] 000107838 0000713E 0041A53E LoadIconW
[ 545] 000107824 00007130 0041A530 LoadCursorW
[ 233] 000107812 00007124 0041A524 EndPaint
[ 14] 000107798 00007116 0041A516 BeginPaint
[ 855] 000107782 00007106 0041A506 UpdateWindow
[ 829] 000107758 000070EE 0041A4EE TranslateAcceleratorW
-----------------------------------------------------------------------------------------------------
Hint值 API序号 文件RVA VA地址 函数名称 模块: [ KERNEL32.dll ]
-----------------------------------------------------------------------------------------------------
[ 615] 000108820 00007514 0041A914 GetModuleHandleW
[ 611] 000108798 000074FE 0041A8FE GetModuleFileNameW
[ 414] 000108784 000074F0 0041A8F0 FreeLibrary
[ 1443] 000108768 000074E0 0041A8E0 VirtualQuery
[ 674] 000108750 000074CE 0041A8CE GetProcessHeap
[ 819] 000108738 000074C2 0041A8C2 HeapFree查询所有导入库: 查询该程序中导入了那些动态链接库,可使用ImportDll命令来获取到。[Pe View] # ImportDll
----------------------------------------------------------------------
序号 文件偏移FOA 相对偏移RVA DLL名称
----------------------------------------------------------------------
1 0x0000714A 0x00000000 USER32.dll
2 0x000072AE 0x00000000 MSVCR120D.dll
3 0x00007528 0x00000000 KERNEL32.dll
----------------------------------------------------------------------查询特定DLL导入表: 查询该程序中指定的动态链接库内导入过的导入函数,可使用ImportByName命令来获取到。[Pe View] # ImportByName -dll KERNEL32.dll
---------------------------------------------------------------------------------
序号 文件偏移FOA 相对偏移RVA 导入函数 [ 当前模块: KERNEL32.dll ]
---------------------------------------------------------------------------------
615 0x00007514 0x0001A914 GetModuleHandleW
611 0x000074FE 0x0001A8FE GetModuleFileNameW
414 0x000074F0 0x0001A8F0 FreeLibrary
1443 0x000074E0 0x0001A8E0 VirtualQuery
674 0x000074CE 0x0001A8CE GetProcessHeap
819 0x000074C2 0x0001A8C2 HeapFree
815 0x000074B6 0x0001A8B6 HeapAlloc
254 0x000074A6 0x0001A8A6 DecodePointer
---------------------------------------------------------------------------------查询特定函数所在位置: 用于验证指定的程序中是否引入了指定函数,可使用ImportByFunction命令来获取到。[Pe View] # ImportByFunction --function HeapAlloc
-------------------------------------------------------------------
序号 FOA地址 VA地址 所在DLL
-------------------------------------------------------------------
[ 815] 000074B6 0041A8B6 KERNEL32.dll
-------------------------------------------------------------------
[Pe View] #
[Pe View] # ImportByFunction --function wcscpy_s
-------------------------------------------------------------------
序号 FOA地址 VA地址 所在DLL
-------------------------------------------------------------------
[ 1990] 00007368 0041A768 MSVCR120D.dll
-------------------------------------------------------------------查询导出表: 用于查询程序中的导出表,可使用Export命令查询,此处我们需要切换到DLL上然后再查询。[Pe View] # Open --path d://SecurityPE.dll
[+] 已读入文件
[Pe View] #
[Pe View] # Export
-----------------------------------------------------------------------
序号 导出RVA地址 导出VA地址 导出FOA地址 导出函数
-----------------------------------------------------------------------
1 00003760 0x10003760 0x00002B60 CreateObject
-----------------------------------------------------------------------查询重定位项: 用于查询该程序中所有的重定位项,可使用FixReloc命令查询。[Pe View] # FixReloc
--------------------------------------------------------------------
起始RVA 类型 重定位RVA 重定位地址 修正RVA
--------------------------------------------------------------------
00011000 3 0001151C 0041A178 0001A178
00011000 3 00011592 00419138 00019138
00011000 3 000115B6 00419140 00019140
00011000 3 000115BB 00419208 00019208
00011000 3 000115C3 0041A188 0001A188
00011000 3 000115E7 0041A180 0001A180
00011000 3 000115FA 0041A16C 0001A16C
00011000 3 0001166F 00419000 00019000
00011000 3 00011689 00411195 00011195
--------------------------------------------------------------------查询重定位表分页: 用于显示重定位分页情况,可使用FixRelocPage命令查询。[Pe View] # FixRelocPage
----------------------------------------------------------------------
映像基址: 00400000 虚拟偏移: 0001E000 重定位表基址: 001C9E00
----------------------------------------------------------------------
起始RVA: 00011000 块长度: 0200 重定位个数: 0096
起始RVA: 00012000 块长度: 0292 重定位个数: 0142
起始RVA: 00013000 块长度: 0296 重定位个数: 0144
起始RVA: 00014000 块长度: 0108 重定位个数: 0050
起始RVA: 00016000 块长度: 0028 重定位个数: 0010
起始RVA: 00017000 块长度: 0048 重定位个数: 0020
----------------------------------------------------------------------查询重定位页内分页: 用于查询重定位RVA页内的页,此功能需要得到RVA时再使用。[Pe View] # FixRelocRVA --rva 00017000
----------------------------------------------------------------------
起始RVA 类型 重定位RVA 重定位地址 修正RVA
----------------------------------------------------------------------
00017000 3 00017014 00419350 00019350
00017000 3 00017018 004193A0 000193A0
00017000 3 00017020 00417038 00017038
00017000 3 00017024 00417058 00017058
00017000 3 00017028 0041708C 0001708C
00017000 3 0001702C 004170A8 000170A8
00017000 3 00017030 004170DC 000170DC
00017000 3 0001759C 00419000 00019000
----------------------------------------------------------------------查询资源表: 用于查询程序内的资源,使用Resource命令获取,目前只能获取到一级资源。[Pe View] # Resource
------------------------------------------------------------
资源类型ID 类型
------------------------------------------------------------
00000003 图标
00000004 菜单
00000005 对话框
00000006 字符串列表
00000009 快捷键
0000000E 图标组
00000018 24
------------------------------------------------------------检查函数内存地址: 用于验证特定模块中的内存地址,使用GetProcAddr命令验证。[Pe View] # GetProcAddr --dll user32.dll --function MessageBoxA
0x76B12D90
[Pe View] #
[Pe View] # GetProcAddr --dll user32.dll --function MessageBoxW
0x76B132B0
[Pe View] #
[Pe View] # GetProcAddr --dll user32.dll --function MessageBox
0x0检查保护模式: 用于检查当前打开进程所开启的保护模式。[Pe View] # CheckSelf
--------------------------------------------------
基址随机化: 是
DEP保护兼容: 是
强制完整性: 否
SEH异常保护: 否
证书签名: 否
--------------------------------------------------十六进制输出: 用于得到程序的十六进制机器码,通常传入的是文件路劲,文件偏移,以及读取大小。[Pe View] # GetHexAscii --path d://Win32Project.exe --offset 498 --len 100
-------------------------------------------------------------------------------
Offset | 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | ASCII
-------------------------------------------------------------------------------
00000498 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
00000514 | 00 00 A0 00 00 E0 2E 74 65 78 74 00 00 00 66 43 | ?text fC
00000530 | 00 00 00 10 01 00 00 44 00 00 00 04 00 00 00 00 | D
00000546 | 00 00 00 00 00 00 00 00 00 00 20 00 00 60 2E 72 | `.r
00000562 | 64 61 74 61 00 00 69 20 00 00 00 60 01 00 00 22 | data i ` "
00000578 | 00 00 00 48 00 00 00 00 00 00 00 00 00 00 00 00 | H
00000594 | 00 00 40目标指纹识别: 检测目标程序硬盘特征指纹,从而判断是那个编译器生成的程序,目前特征库不全仅用于测试。[Pe View] # Fingerprint --path d://Win32Project.exe
---------------------------------------------------------------------------------------------------------
原始数据: 55 8B EC 81 EC C4 00 00 00 53 56 57 8D BD 3C FF FF FF B9 31 00 00 00 B8 CC CC CC CC F3 AB 8B 45
磁盘映像: 55 8B EC 81 EC C4 00 00 00 53 56 57 8D BD 3C FF FF FF B9 31 00 00 00 B8 CC CC CC CC F3 AB 8B 45
检测结果: Microsoft Visual C/C++ x86 (2013)
---------------------------------------------------------------------------------------------------------十六进制计算器: 此处是一个小功能,用于计算两个十六进制数的加减法。[Pe View] # Add --x 1c --y 2d
1c + 2d =>
HEX= 00000049
DEC= 73
OCT= 111
BIN= 1001001
[Pe View] #
[Pe View] # Sub --x 1c --y 2d
1c - 2d =>
HEX= FFFFFFEF
DEC= -17
OCT= 37777777757
BIN= 11111111111111111111111111101111文件地址转虚拟地址: 将当前打开程序机器码所在地址转换成载入内存中的虚拟地址。[Pe View] # FoaToVa --foa 420
--------------------------------------------------------------------------------
基址: 0x00400000 文件偏移开始: 0x00000400 文件偏移结束: 0x00004800
--------------------------------------------------------------------------------
FOA地址: 0x00000420
---> RVA地址: 0x00011020
---> VA地址: 0x00411020
--------------------------------------------------------------------------------虚拟地址转文件地址: 将当前打开程序的内存虚拟地址转换为所在文件地址。[Pe View] # VaToFoa --va 0x00411020
--------------------------------------------------------------------------------
基址: 0x00400000 所在节区: .text 节开始地址: 0x00411000 节结束地址: 0x00415366
--------------------------------------------------------------------------------
VA地址: 0x00411020
---> RVA地址: 0x00011020
---> FOA地址: 0x00000420
--------------------------------------------------------------------------------相对地址转文件地址: 将当前打开程序的RVA相对内存地址,转换成一个文件偏移地址。[Pe View] # RvaToFoa --rva 1024
--------------------------------------------------------------------------------
基址: 0x00400000 所在节区: .textbss 节开始地址: 0x00001000 节结束地址: 0x00011000
--------------------------------------------------------------------------------
RVA地址: 0x00001024
---> VA地址: 0x00401024
---> FOA地址: 0x00000024
--------------------------------------------------------------------------------
Python 实现Web容器指纹识别
当今的Web安全行业在进行渗透测试时普遍第一步就是去识别目标网站的指纹,从而进一步根据目标框架进行针对性的安全测试,指纹识别的原理其实很简单,目前主流的识别方式有下面这几种。1.识别特定网页中的关键字,比对关键字识别框架.2.通过计算特定的相对独立的页面的Hash值,比对实现鉴别.3.通过指定URL的TAG模式,鉴别目标容器类型.以上的三种模式就是常见的指纹识别工具的工作原理,这里我就给大家演示第二种方式,HASH枚举。首先在识别网站指纹之前,先要尝试读取到该目标网站的标题信息,该功能实现非常简单,只需要读入页面,并去除我们所需要的"Date","Server","X-Powered-By","title"字段即可,由于代码较为简单此处就直接放出代码部分。import re,socket,threading,requests
import argparse
header = {'user-agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) LySharkTools'}
def Banner():
print(" _ ____ _ _ ")
print(" | | _ _/ ___|| |__ __ _ _ __| | __")
print(" | | | | | \___ \| '_ \ / _` | '__| |/ /")
print(" | |__| |_| |___) | | | | (_| | | | < ")
print(" |_____\__, |____/|_| |_|\__,_|_| |_|\_\\")
print(" |___/ \n")
print("E-Mail: me@lyshark.com")
def GetIPAddress(domain):
try:
url = str(domain.split("//")[1])
sock = socket.getaddrinfo(url,None)
result = re.findall("(?:[0-9]{1,3}\.){3}[0-9]{1,3}", str(sock[0][4]))
return str(result[0])
except Exception:
pass
def GetServerTitle(url):
try:
address = GetIPAddress(url)
Respon = requests.get(url=url,headers=header,timeout=5)
print("--" * 80)
print(url + " ",end="")
print(address + " ", end="")
if Respon.status_code == 200:
RequestBody = [item for item in Respon.headers]
for item in ["Date","Server","X-Powered-By"]:
if item in RequestBody:
print(Respon.headers[item] + " ",end="")
else:
print("None" + " ",end="")
title = re.findall("<title>.*</title>", Respon.content.decode("utf-8"))
print(title)
except Exception:
pass
if __name__ == "__main__":
Banner()
parser = argparse.ArgumentParser()
parser.add_argument("-f","--file",dest="file",help="")
args = parser.parse_args()
# 使用方法: main.py -f url.log
if args.file:
fp = open(args.file,"r")
for item in fp.readlines():
url = item.replace("\n","")
thread = threading.Thread(target=GetServerTitle,args=(url,))
thread.start()
else:
parser.print_help()程序运行时,需要指定一个文件列表,里面包括网址每行一个以换行隔开,并使用-f指定运行参数即可。我们继续实现指纹识别功能,首先利用Requests库将目标页面读入到字符串中,然后调用MD5算法计算出该页面的HASH值并比对,由于特定框架中总是有些页面不会变动,我们则去校验这些页面的HASH值,即可实现对框架的识别,代码很简单这里就直接放出源代码。import requests
import os,sys,hashlib
import argparse
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) LySharkTools'}
def Banner():
print(" _ ____ _ _ ")
print(" | | _ _/ ___|| |__ __ _ _ __| | __")
print(" | | | | | \___ \| '_ \ / _` | '__| |/ /")
print(" | |__| |_| |___) | | | | (_| | | | < ")
print(" |_____\__, |____/|_| |_|\__,_|_| |_|\_\\")
print(" |___/ \n")
print("E-Mail: me@lyshark.com")
def CheckFinger(url,flag,keyworld):
if flag == 0:
ret = requests.get(url=url,headers=headers,timeout=1)
text = ret.text
md5=hashlib.md5()
md5.update(text.encode('utf-8'))
print("目标网页Hash值: {}".format(md5.hexdigest()))
else:
fp = open(keyworld,"r")
for i in fp.readlines():
path = url + eval(i.replace("\n", ""))["Path"]
hash = eval(i.replace("\n", ""))["Hash"]
web = eval(i.replace("\n", ""))["WebServer"]
ret = requests.get(url=path, headers=headers, timeout=1)
if ret.status_code == 200:
text = ret.text
md5 = hashlib.md5()
md5.update(text.encode('utf-8'))
if md5.hexdigest() == hash:
print("目标Hash:{} CMS页面类型:{} ".format(hash,web))
else:
continue
if __name__ == "__main__":
Banner()
parser = argparse.ArgumentParser()
parser.add_argument("--mode",dest="mode",help="设置检查类型 [check/get]")
parser.add_argument("-u","--url",dest="url",help="指定需要检测的网站地址")
parser.add_argument("-f","--file",dest="file",help="指定字典数据库 data.json")
args = parser.parse_args()
if args.mode == "get" and args.url:
CheckFinger(args.url,0,args.file)
# 检测目标容器类型: main.py --mode=check -u https://www.xxx.com -f data.json
elif args.mode == "check" and args.url and args.file:
CheckFinger(args.url,1,args.file)
else:
parser.print_help()指纹识别的重点并不在于识别工具的编写,而在于特征库是否健全,我们的工具也需要特征库,可以使用get方式提取指定页面的特征,例如:我们新建一个文件,并依次写入指纹特征以及它的相对路径信息,并增加其所对应的Web容器版本。{"Path":"/about/index.html","Hash": "9e69dd111c6cc873a1f915ca1a331b06","WebServer":"hexo"}
{"Path":"/index.php","Hash": "2457dd111c6cc32461f915ca17789b06","WebServer":"typecho"}当特征库完整时,即可使用-f指定特征文件,循环获取是否匹配特征,从而判断web容器使用了那种容器。
公众号开发之路——为了研究公众号,我注册了公司
现在是北京时间:2022年9月10日23:34,农历八月十五日,2022年的教师节,也是中秋节,祝大家节日快乐~在发文之前,我妈妈还问我,晚上吃了啥,有没有吃月饼,有没有吃水饺?出门在外,总是报喜不报优,虽然我吃了土豆片就馒头,但是还是给我妈说我吃了猪肉大葱的水饺,而且,吃了20多个(以前我可是只吃10多个的),我妈听了之后很是开心,真所谓:儿行千里母担忧1.前言首先提前声明,我不是标题党,不是标题党,不是标题党!!!为了开发小程序和公众号,我真的是注册了个公司,而且现在还在运营,你说迷不迷。事情还得从2017年的时候说起。2.想法那一年,我刚学完计算机毕业,被分配到学校当技术老师,主要是授学生编程知识。那一年,我还没满20岁,瘦小的身材,刚开始从公司上班,领导担心我管不了学生,所以让我先从助教开始做起。做助教嘛,时间多的很,这就正好应了我闲不住喜欢瞎研究的想法,那时候我刚研究出来人脸识别,指纹识别等相关技术,所以正在想着下一步研究什么。(当助教是很闲的,不需要去教室里上课,也不用备课,偶尔去听听老教师们的讲课,然后给学员们解决一下疑难杂症,有大把的时间)那个时候,微信的公众号刚刚开始盛行,各种鸡汤号满屏都是,有中规中矩的,也有花里胡哨的,反正就是眼花缭乱,看的看的,我也心生注册之意,于是三下五除二就开始搞了。3.注册及研究注册很简单,拿着邮箱,找到官网,哐哐哐的就注册完事儿了,注册完之后完善个人信息,头像啥的乱七八糟要完善的。为了避打广告的嫌,内容全部打码了接着就开始研究,本着【先看再点】的原则去研究,比如菜单吧,先看一下有哪些菜单,然后在挨个的点进去看。从发文、评论、留言,到数据分析,广告服务以及设置与开发,都仔细的看了看,发现也没有什么挑战力。于是继续深入了解,主要是看开发的那一部分。作为一个计算机毕业的程序员,用人家的产品,一点技术含量都没有,只有自己去动手研发的,才有点意思。这一看不打紧,基础功能都支持,但是要来点高级一点儿的,都有一个共同要求,那就是账号需要微信认证。那就认证呗,去认证的时候,被告知:只支持企业认证,个人不支持.....如图所示,账号主体为个人,无法开通微信认证。2017年的时候,和现在的公众平台后台还是有所区别的,基本上好多开发的功能都需要认证,做为一个主体是个人的号,可所谓限制多多。俗话说的好,“冲动是魔鬼”,于是乎,我就冲动了,公众号开发不开发的就不管了,开始搜起了公司名....4.注册公司为了让账号的主体不是个人,是企业!我开始想公司名了,苦思冥想,叫个啥名字好呢?这也不行那也不行,最后好容易想到了一个。接着开始在济南政务平台上注册公司....起名,工商局登记,税务局登记,银行开户,一个一个的跑,大概两周左右的时间,终于注册完毕。看看手里的营业执照,若有所思....我为什么要注册个公司?想好怎么运营了吗???难道就为了研究公众号,而搞个公司?想想都不可思议。好了,下面公司都有了,于是以公司为主体,我新注册了个公众号....满足了账号主体必须是企业的要求了。开始认证,交钱300大洋,成功认证!!!一系列的操作弄完之后,终于可以开始正儿八经的看了,但是因为当时的身份是老师,不便透露我还有个公司的情况....这个号只能自己在业余时间研究研究。公众号开发都需要服务器的,又开始搞服务器,搞域名,费了不少精力和时间。好在也研究出来点奇门绝技,哈哈哈,发展到后期,学校的各班公众号都是我牵头创建和推广的,也算是没有白白研究吧。至于公司的情况,当时注册完之后,由于是冲动注册的,完全没有想好如何运营,搞什么产品,所以就一直在闲着,直到2019年,开始正式拉合作伙伴,注资,推广运营,现在正在起步阶段,公司朝气蓬勃的发展,也算是对得起自己早年的不懂事了吧~其实,路啊,没有固定的道,只要有目标,你想怎么走就怎么走!
快速完成单片机毕业设计方法
1.快速做出毕业设计方法单片机如果只是学习到做出一个毕业设计,其实还是很简单的,而且现在网上的例子那么多,找一个相似的稍微修改下就好了。那么下面说下方法:在讲方法之前,首先说明一下,不论什么方法,都是需要了解一些单片机,嵌入式相关知识的。给大家分享一个嵌入式习题练习的网站:单片机、嵌入式知识练习首先你需要知道你的毕业设计都需要用到单片机的哪些外设,比如:io,iic,pwd,定时器等等。如果你不知道你都要用到什么外设的话,那么很简单,你只要把你需要实现的功能告诉学过单片机的同学,然后请帮你分析一波或者请教下你们老师都可以的。之后给对方买杯奶茶或者吃个饭就好了。当然,也可以来咨询我。知道需要什么外设以后,就可以有针对性的去学习。比如,有个毕业设计需要使用到IO口,定时器,IIC,AD转换,那么这里你只需要去找个单片机的课程,然后只学习下这几个外设就好了。如果上面第二步骤,你实在学不会,那么你只需要知道这个外设能够干什么就行了,剩下的就交给我,我还有办法,可以看下后面的 2.毕设借鉴法画电路图,这个就需要一些电路知识了,如果你说我还是不会,那么还是看下后面的 2.毕设借鉴法 另外,如果你想用pcb板子的话,那么还学习一下ad这个软件了,实在不想学的话,这个跳过,之就用洞洞板去用线连接就好了。这一步就需要进行编程了,使用做出来的实物(也可以先使用最小系统或者开发板)进行编程,这一步先一个一个功能的实现,比如上面使用到的外设,先把IO相关的功能实现完以后,再去做定时器的,以此类推。2.毕设借鉴法单片机能够做的毕业设计也就那么多,不管是数据采集类,还是控制类,还是物联网类,这些归根结底还都是使用单片机的外设。只要找到这些外设的电路与程序,那么一切问题就都解决了。所谓的毕设借鉴法,那就是去找到与你设计类似或者包含有你想要的功能的毕业设计,然后把你所需要的程序和电路拿出来,组装下,组装成你需要的就行了。我会在文章的最后会分享一些常用的设计。下面针对电路与程序分开来说:2.1 程序单片机做设计,基本也就那些模块,比如:温湿度传感器:dht11,dht22,sht30温度传感器:ds18b20,PT100,光照传感器:bh750步进电机直流电机wifi模块:esp8266蓝牙模块zigbee显示模块:lcd1602,lcd12864,tft屏幕,oled,数码管烟雾传感器二氧化碳传感器心率传感器:max20102,max20100电子陀螺仪/角度传感器:mpu6050超声波lora模块时钟模块:ds1302,ds1307,ds3231酒精传感器等等。。。比如图片中这些就是我常用的我们只需要能够找到这些模块的程序,那么就简单了,接下来就是程序的组装了。2.1.1 举例说明这里我们以温湿度传感器举例:可以看到温湿度传感器的程序模块有这些函数可以使用,那么我们看下我们会使用到的。第一步:想要使用某个模块,肯定是要初始化的,那么就需要调用一下DHT11_Init()函数第二步:我们使用这个传感器是为了获取温湿度数据,那么这个时候在程序中一直去调用DHT11_Read_Data()函数即可,这样数据就已经得到了,那么这个温湿度采集的功能就已经完成了。其他模块也是类似。2.1 电路设计电路就更简单了,这个只需要打开那些相似设计的电路图,把我们需要的电路拷贝出来即可。下面展示一部分我经常使用到的电路,在我们需要设计电路时,只需要将他们拷贝过去就可以了。常用的单片机毕业设计更多单片机毕业设计项目可查看该文档:001、基于51单片机无线蓝牙APP控LED灯亮灭亮度设计002、基于51单片机老人防跌倒GSM短信报警系统003、基于51单片机老人防跌倒经纬度GPS定位短信GSM上报004、基于51单片机智能停车场管理车位引导系统设计005、STM32单片机生理监控心率脉搏TFT彩屏波形曲线006、基于51单片机环境监测设计 光照 PM2.5粉尘 温湿度 2.4G无线通信007、基于单片机的指纹红外密码电子锁008、基于stm32舞台彩灯控制器设计app控制009、STM32单片机无线ZIGBEE智能大棚土壤湿度光照检测010、基于51单片机WIFI智能家居011、基于STM32的语音IC卡停车管理系统012、基于51单片机自动智能浇花系统设计013、基于STM32F103单片机智能门禁热释人体感应报警设计014、基于51单片机的智能水表水流量计流量报警器温度设计015、基于51单片机霍尔转速测量温度PWM调速设计016、基于STM32单片机远程浇花花盆GSM短信浇水补光设计017、基于51单片机跑步机脉搏心率检测霍尔测速设计018、基于STM32单片机智能手表GSM短信上报GPS定位设计019、STM32单片机智能家居声音人体防盗GSM短信报警020、基于STM32单片机智能药盒定时吃药喂水蓝牙APP设计021、基于毕业51单片机声控灯设计 智能声音+光线控制 楼道灯 声控开关022、基于51单片机步数检测计步器无线蓝牙APP上传设计023、基于STM32单片机直流电机控制加减速正反转系统设计024、基于51单片机太阳能风能风光互补路灯控制器设计025、基于STM32单片机抢答器时间显示设计026、基于51单片机汽车自动照明灯超声波光敏远近光灯设计027、基于STM32单片机FM调频TEA5767功放收音机液晶显示设计028、基于51单片机智能化交通红绿灯堵车流量红外设计029、基于51单片机智能台灯无线WIFI控制LED灯亮灭亮度APP设计030、基于51单片机手机无线蓝牙APP控制风扇PWM调速设计031、基于51单片机水塔水箱液水位WIFI监控报警设计032、基于51单片机WIFI遥控防盗电子密码锁APP控制设计033、基于51单片机红外遥控定时开关智能家电插座设计034、基于51单片机超声波测液位测距仪水位监测报警设计035、基于51单片机太阳能锂电池充电电压电流检测液晶显示设计036、基于51单片机自动浇花1602液晶显示设计037、基于51单片机煤气天然气检测阈值报警风扇设计038、基于51单片机温度控制系统报警器恒温箱水温设计039、基于51单片机智能大棚浇花花盆浇水灌溉补光散热设计040、基于51单片机温湿度检测系统无线蓝牙APP上传设计041、基于51单片机电子称称重压力检测阈值报警系统设计042、基于51单片机倒计时器秒表定时器数码管显示设计043、基于51单片机220V交流电流检测系统过流阈值报警设计044、基于51单片机RFID智能门禁系统红外人流量计数统计045、基于51单片机射频RFID停车刷卡计时收费系统设计046、基于51单片机射频RFID卡考勤上课上班人数计数系统设计047、基于51单片机霍尔测速仪表测转速调速系统设计048、基于51单片机指纹识别管理门禁密码锁系统设计049、基于51单片机红外避障车辆高速汽车测速仪表设计050、基于51单片机WIFI心率计脉搏体温测量仪APP设计051、基于51单片机音乐喷泉设计频谱彩灯音乐盒播放器052、基于STM32单片机大棚温湿度检测无线蓝牙APP控制设计053、基于STM32单片机智能RFID刷卡汽车位锁桩设计054、基于STM32单片机智能电表无线WIFI插座APP交流电压电流检测设计055、基于51单片机智能手环脉搏心率检测GSM短信上报056、基于51单片机智能台灯节能灯热释人体自动感应照明灯057、基于STM32的车牌识别设计058、基于STM32单片机智能手环脉搏心率计步器体温显示设计059、基于MATLAB的车牌识别系统060、基于51单片机智能电子密码锁密码箱保险柜系统设计061、基于51单片机的智能婴儿床设计062、基于51单片机的智能红外温控风扇设计063、基于51单片机的简易逻辑分析仪设计064、基于51单片机的远程wifi浇花系统设计065、基于STM32的无线鼠标设计066、基于STM32的二维码识别云仓库系统067、基于STM32的OneNet物联网环境检测系统068、基于51单片机的超声波视力保护系统设计069、基于STM32的智能语音浴缸设计070、基于51单片机温度控制系统报警器恒温箱app控制设计071、基于STM32单片机智能家居wifi远程监控系统机智云app设计072、基于stm32的智能温室控制系统设计073、基于51单片机的盲人电子助理智能拐杖(语音+震动)设计
手势密码解锁微信小程序项目源码
微信公众号:创享日记发送:手势密码获取完整源码(导入微信开发者工具即可用)以下可以忽略不看!手势密码就是在手机触屏上设置一笔连成的九宫格图案,登录时画一下设定的图形。运行程序,发现各个数字的个数,其中4位的有1624个,5位的有7152个,6位的有26016个,7位的有72912个,8位的有140704个,9位的有140704个,总共有389112种!值得一提的是,6位以下的个数甚至每到10000种,所以设置密码最好设置6位以上的,当然不怕忘记的话,可以设置9位的变态密码。目前app内常用的安全验证,有密码、手势、指纹、面部识别。你会发现从便利性&安全性从高到低的划分是,面部识别、指纹识别、手势、密码。随着时代和技术的进步,安全验证更加趋向于个人生物化。n年前,如果密码被a知道了,a完全可以通过密码/手势来获得和你同样的权利进行相关操作。现在,则可通过生物认证。指纹和面部识别来确定是否是本人进行操作,大大提升了产品的安全性。使用手势密码登录时,如果输入错误,会对用户进行错误提示,提示后用户可以继续输入,当同一个账号输错达5次时,系统会自动退出登录,用户需要输入密码验证身份成功后才能进入app。在手势登录页面,也可以使用忘记手势密码登录,如果点击忘记手势密码,退出登录,输入密码验证身份成功后,页面跳转至手势密码设置页面,设置新的手势密码。设置完成后,会自动登录app。function(){
var wxlocker = function(obj){
this.chooseType = 3; // 3*3的圆点格子
};
wxlocker.prototype.drawCle = function(x, y) { // 初始化解锁密码面板
this.ctx.setStrokeStyle('#10AEFF');
this.ctx.setLineWidth(1);
this.ctx.beginPath();
this.ctx.arc(x, y, this.r, 0, Math.PI * 2, true);
this.ctx.closePath();
this.ctx.stroke();
}
wxlocker.prototype.drawLine = function(po, lastPoint) {// 解锁轨迹
this.ctx.beginPath();
this.ctx.setLineWidth(1);
this.ctx.moveTo(this.lastPoint[0].x, this.lastPoint[0].y);
for (var i = 1 ; i < this.lastPoint.length ; i++) {
this.ctx.lineTo(this.lastPoint[i].x, this.lastPoint[i].y);
}
this.ctx.lineTo(po.x, po.y);
this.ctx.stroke();
this.ctx.closePath();
}
wxlocker.prototype.createCircle = function() {// 创建解锁点的坐标,根据canvas的大小来平均分配半径
var cavW = this.setCanvasSize().w;
var cavH = this.setCanvasSize().h;
var n = this.chooseType;
var count = 0;
this.r = cavW / (2 + 4 * n);// 公式计算
this.lastPoint = [];
this.arr = [];
this.restPoint = [];
var r = this.r;
for (var i = 0 ; i < n ; i++) {
for (var j = 0 ; j < n ; j++) {
count++;
var obj = {
x: j * 4 * r + 3 * r,
y: i * 4 * r + 3 * r,
index: count
};
this.arr.push(obj);
this.restPoint.push(obj);
}
}
// this.ctx.clearRect(0, 0, cavW, cavH);
for (var i = 0 ; i < this.arr.length ; i++) {
this.drawCle(this.arr[i].x, this.arr[i].y);
}
wx.drawCanvas({
canvasId: "locker",
actions: this.ctx.getActions(),
reserve:false
});
//return arr;
}
wxlocker.prototype.getPosition = function(e) {// 获取touch点相对于canvas的坐标
// var rect = e.target;
var po = {
x: e.touches[0].x,
y: e.touches[0].y
};
return po;
}
wxlocker.prototype.update = function(po) {// 核心变换方法在touchmove时候调用
var cavW = this.setCanvasSize().w;
var cavH = this.setCanvasSize().h;
this.ctx.clearRect(0, 0, cavW, cavH);
for (var i = 0 ; i < this.arr.length ; i++) { // 每帧先把面板画出来
this.drawCle(this.arr[i].x, this.arr[i].y);
}
this.drawPoint();// 每帧画圆心
this.drawLine(po , this.lastPoint);// 每帧画轨迹
for (var i = 0 ; i < this.restPoint.length ; i++) {
if (Math.abs(po.x - this.restPoint[i].x) < this.r && Math.abs(po.y - this.restPoint[i].y) < this.r) {
this.drawPoint();
this.lastPoint.push(this.restPoint[i]);
this.restPoint.splice(i, 1);
break;
}
}
}
wxlocker.prototype.checkPass = function(psw1, psw2) {// 检测密码
var p1 = '',
p2 = '';
for (var i = 0 ; i < psw1.length ; i++) {
p1 += psw1[i].index + psw1[i].index;
}
for (var i = 0 ; i < psw2.length ; i++) {
p2 += psw2[i].index + psw2[i].index;
}
return p1 === p2;
}
wxlocker.prototype.storePass = function(psw,cb) {// touchend结束之后对密码和状态的处理
if (this.pswObj.step == 1) {//step==1表示还没有设置密码状态
if (this.checkPass(this.pswObj.fpassword, psw)) {
this.pswObj.step = 2;
this.pswObj.spassword = psw;
this.resetHidden = false;
this.title = "密码保存成功";
this.titleColor = "succ";
this.drawStatusPoint('#09bb07');
wx.setStorageSync('passwordxx', JSON.stringify(this.pswObj.spassword));
// wx.setStorageSync('chooseType', this.chooseType);
} else {
this.title = "两次绘制不一致,重新绘制";
this.titleColor = "error";
this.drawStatusPoint('#e64340');
delete this.pswObj.step;
}
} else if (this.pswObj.step == 2) {
if (this.checkPass(this.pswObj.spassword, psw)) {
this.title = "解锁成功";
this.titleColor = "succ";
this.drawStatusPoint('#09bb07');
cb();
} else {
this.title = "解锁失败";
this.titleColor = "error";
this.drawStatusPoint('#e64340');
}
} else {
if(this.lastPoint.length<4){
this.title="密码过于简单,请至少连接4个点";
this.resetHidden = true;
this.titleColor = "error";
return false;
}else{
this.pswObj.step = 1;
this.pswObj.fpassword = psw;
this.titleColor = "";
this.title = "再次输入";
}
}
}
wxlocker.prototype.makeState = function() {
if (this.pswObj.step == 2) {
this.resetHidden = false;
this.title = "请解锁";
this.titleColor = "";
} else if (this.pswObj.step == 1) {
this.title="请设置手势密码";
this.resetHidden = true;
this.titleColor = "";
} else {
this.title="请设置手势密码";
this.resetHidden = true;
this.titleColor = "";
}
}
wxlocker.prototype.updatePassword = function(){//点击重置按钮,重置密码
wx.removeStorageSync("passwordxx");
// wx.removeStorageSync("chooseType");
this.pswObj = {};
this.title="请设置手势密码";
this.resetHidden = true;
this.titleColor = "";
this.reset();
}
wxlocker.prototype.init = function() {//初始化锁盘
this.pswObj = wx.getStorageSync('passwordxx') ? {
step: 2,
spassword: JSON.parse(wx.getStorageSync('passwordxx'))
} : {};
this.lastPoint = [];//记录手指经过的圆圈
this.makeState();
this.touchFlag = false;
this.ctx = wx.createContext();//创建画布
this.createCircle();//画圆圈
}
wxlocker.prototype.reset = function() {
this.createCircle();
}
//适配不同屏幕大小的canvas
wxlocker.prototype.setCanvasSize = function(){
var size={};
try {
var res = wx.getSystemInfoSync();
var scale = 750/686;//不同屏幕下canvas的适配比例;设计稿是750宽
var width = res.windowWidth/scale;
var height = width;//canvas画布为正方形
size.w = width;
size.h = height;
} catch (e) {
// Do something when catch error
console.log("获取设备信息失败"+e);
}
return size;
}
wxlocker.prototype.bindtouchstart = function(e){
if(e.touches.length==1){
var self = this;
var po = self.getPosition(e);
for (var i = 0 ; i < self.arr.length ; i++) {
//判断手指触摸点是否在圆圈内
if (Math.abs(po.x - self.arr[i].x) < self.r && Math.abs(po.y - self.arr[i].y) < self.r) {
self.touchFlag = true;
self.drawPoint();
self.lastPoint.push(self.arr[i]);
self.restPoint.splice(i,1);
break;
}
}
}
wx.drawCanvas({
canvasId: "locker",
actions: this.ctx.getActions(),
reserve:true
});
}
基于单片机的指纹识别电子密码锁设计
1.1 指纹识别简介1.1.1 指纹识别原理 指纹识别技术的原理和其它生物识别技术的原理相似。它是利用人体的指纹特征对个体身份进行区分和鉴定。在所有的生物识别技术中指纹识别技术是目前最为成熟,也被应用最广的生物识别技术。这主要因为指纹采用的过程对人们来讲非常简单,指纹识别的准确率高的原因。严格来讲,指纹识别的原理包括指纹采集原理、指纹特征提取原理和指纹特征匹配原理三大部分。指纹采集原理主要是根据指纹的几何特性或生理特性,通过各种传感技术把指纹表现出来,形成数字化表示的指纹图案。 由于指纹的嵴和峪的几何特征不同,主要表现为嵴是突起的,峪是凹下的,所以在接触到光线时,其反射光的强度也就不同。在接触到平面时,其在平面上形成的压力也就不同。另一方面,由于指纹的嵴和峪的生理特征不同,主要表现为:嵴和峪的温度不同,其导电性也不同,其对波长的反馈也就不同。通过这些几何的、生理的特性的不同,把人的指纹采集到计算机系统中形成指纹图像。 指纹特征分析的原理是对指纹图案的整体特征和细节特征进行提取、鉴别的原理。其分析的对象包括纹形特征和特征点的分布、类型,以及一组或多组特征点之间的平面几何关系。特征点的平面几何关系表现为某个特征点之间的距离等,或者某三个或更多特征点之间组成的多边形的几何特性。不论是特征点的单体特征,还是特征点的组合特征都是指纹特征的组成部分。把这些指纹特征用数字模板的形式表示出来,就实现了一个指纹特征分析的过程。把人的指纹采集到计算机系统中形成指纹图像。更多单片机毕业设计项目,请点击查看 指纹特征值匹配原理是对指纹图案的整体特征和细节特征按模式识别的原理进行比对匹配。匹配是在已注册的指纹和当前待验证的指纹之间进行的。匹配运算不是对两个指纹图像进行比较,而是对已形成数字模板的指纹特征值进行匹配。1.1.2 指纹识别应用 指纹识别技术是最早的通过计算机实现的身份识别手段,它是应用最为广泛的生物特征识别技术。过去,它主要应用于刑侦系统。近几年来,它逐渐走向市场更为广泛的民用市场。指纹技术在现代生活和工作中的应用已越来越普遍,指纹考勤机、指纹社保、指纹银行、指纹商场、指纹投票、指纹保护电脑、等等生活中和工作中的新现象已广为人知,其应用相当广泛,指纹技术正在日益刷新着我们的现代化生活方式。指纹识别技术是目前国际公认的应用广泛、价格低廉、易用性高的生物认证技术。指纹只是人体皮肤的小部分,但是它却蕴涵了大量的信息。这些皮肤的纹路在图案、断点和交叉点上是各不相同的,在信息处理中将它们称作"特征"。医学上已经证明这些特征对于每个手指都是不同的,而且这些特征具有唯一性和永久性。因此我们就可以把一个人同他的指纹对应起来,通过比较他的指纹特征和预先保存的指纹特征,就可以验证他的真实身份。1.1.3 指纹识别技术的发展 在经历了近 10 年缓慢的自然增长后,指纹识别技术即将迎来一个跳跃性发展的黄金时期。专家们保守估计,未来 5 年,我国将有近百亿元的市场等待着企业去开拓。指纹识别技术的巨大市场前景,将对国际、国内安防产业产生巨大的影响。较小的公司将面临新进入的传统行业大公司的无情竞争。在这些巨无霸面前,现有中小公司很难说有太大的竞争力,行业重新洗牌不可避免,合并与退出可能会成为大部分中小公司的无奈选择。最终可能形成传统行业的公司或大资本在较短时间内主导生物特征识别行业的局面。这也是每一个新兴市场的必然结果。而竞争的结果将会形成一个新兴的大产业。 国内生物识别技术的应用主要集中在企业级应用上,在 2002年总体约为2.5亿元人民币的终端市场中,超过 40%的产品都用于考勤、门禁系统之中。自2002年以来整个生物识别市场中指纹识别占据了超过 98%的份额,从需求看,中国 13 亿人口决定了中国将是未来全球最大的指纹识别认证技术市场。1.2 系统设计的目的 现代社会越来越需要高效可靠的身份识别系统。传统的个人身份鉴别手段如口令、密码、身份-甚至磁卡、IC 卡等识别卡方式。由于其与身份人的可分离性,可假冒、可伪造、可盗用、可破译,已不能完全满足现代社会经济活动和社会安全防范的需要。从消除人为不安全因素看,只有不易被他人代替、仿制、甚至其本人也无法转让的身份误码别凭证才能胜任。因此,基于人体生理特征的身份识别系统逐渐为社会所瞩目。随着识别技术的不断成熟,随着计算机技术的飞速发展,各种基于人体生理特征的身份识别系统如:指纹、手掌、声音、视网膜、瞳孔、面纹等识别技术纷纷从实验室中走出来,由小型机落户微机,走向民用。而从易用性、安全性、成熟性和造价等方面综合比较,指纹识别技术将成为未来人体生理特征身份识别技术的主流之一,指纹自动识别技术开创了个人身份鉴别的新时代,将来我们生活的很多场 合都要用到指纹,指纹使我们的生活更方便、安全。1.3 课题背景 指纹检测可以良好的判断和定义一个人的真实生物身份,从而降低社会活动中的信任成本。从根本上改变经济和社会交往模式,提高效率。未来社会利用生物识别技术的场合将会越来越多,指纹识别技术日趋完善,指纹检测变得越发重要。本次设计指纹识别电子密码锁是基于深圳指昂科技有限公司生产的ZAZ-010指纹模块,可以根据串口通信协议与上位机实现通信,从而实现指纹的录入、存储、比对,并通过HS12864-15C液晶显示出指纹采集存储的过程和比对的结果。指纹电子密码锁安全可靠,使用方便。2 整体设计方案2.1 系统总体设计2.1.1 系统功能描述 本系统是针对指纹采集、识别模块开发出的指纹识别电子密码锁系统。该系统使用指纹模块搜索手指,一旦搜索到手指,立即采集指纹图像,并将采集到的图像转化成数据的形式发送出去。它利用人体指纹各异性和不变性,为用户提供加密手段,使用时只需将手指平放在指纹采集仪的采集窗口上,即可完成采集任务,操作十分方便快捷。主要功能就是用液晶显示出指纹模块采集指纹图像各个流程及比对的结果.采集指纹图像之前,指纹模块必须要检测手指是否放在采集窗口上,所以就要有录入指纹这一项功能。简单的描述本次设计的功能即使用指纹模块检测、录入指纹,将比对的数据显示在液晶屏幕上.本系统拥有一次最多录入三个指纹的能力。该系统的主要功能有以下几个方面: 1.录入指纹:系统预先要有录入指纹的功能,即将个人的指纹通过指纹采集器采集用户指纹的特征信息。 2.合成指纹模板并存储:通过光电转换后,将指纹特征值和对应的 ID 号存储到存储器中。上位机只要有上传指纹的命令,模块可以立即将数据传送到指定位置。 3.搜索指纹库比对指纹:当有指纹录入时,模块会响应上位机指令搜索指纹库比对指纹,同时液晶显示比对结果,继电器动作、发光二极管亮。2.1.2 系统总体框架 系统的总体框架是指根据设计任务要求,对系统所需元件、设备参数进行必要的计算,通过认真研究、分析、比较选定设备型号,再将设备、元件通过可靠的接口电路联系起来构成一个完整的系统。在系统的整体方案确定之前,先要明确设计要求,然后对系统硬件、软件进行设计,其中包括绘制原理框图、电路图,对原理进行必要说明,综合考虑系统的性能和稳定性要求,以保证所设计的系统达到预期的要求。通过查阅大量的文献资料、综合分析考虑 。主控芯片选用Atmeg16单片机。系统总体框图如图2-1所示:系统主要由MCU、液晶屏、指纹模块组成. 系统的工作方式主要是,当检测到有按键按下时先由MCU通过串口通信控制指纹模块对指纹进行采集、录入、存储、比对。然后,根据所得的数据对其它接口器件,如液晶屏、继电器进行响应操作。2.2 系统核心部件单片机2.2.1 单片机的选择 单片机微型计算机是微型计算机的一个重要分支,也是颇具生命力的机种。单片机微型计算机简称单片机,特别适用于控制领域,故又称为微控制器。 通常,单片机由单块集成电路芯片构成,内部包含有计算机的基本功能部件:中央处理器、存储器和I/O接口电路等。因此,单片机只需要和适当的软件及外部设备相结合,便可成为一个单片机控制系统。 20世纪末,电子技术获得了飞速的发展,在其推动下,现代电子产品几乎渗透了社会的各个领域,有力地推动了社会生产力的发展和社会信息化程度的提高,同时也使现代电子产品性能进一步提高,产品更新换代的节奏也越来越快。时间对人们来说总是那么宝贵,工作的忙碌性和繁杂性容易使人忘记当前的时间。忘记了要做的事情,当事情不是很重要的时候,这种遗忘无伤大雅。但是,一旦重要事情,一时的耽误可能酿成大祸。2.3 液晶显示模块 显示模块采用HS12864-15C系列中文图形系列液晶模块。由控制器ST7920控制与驱动。2.3.1 HS12864-15C系列液晶的特点HS12864-15系列硬件特性如下:.提供8位,4位并行接口及传行接口可选.自动电源启动复位功能.内部自建振荡源.6416位字符显示RAM(DDRAM最多16字符4行).2M位中文字型ROM(CGROM),总共8192个中文字型HS12864-15系列软件特性如下:.文字与图形混合显示功能.画面清除功能.光标归位功能.显示开/关功能.反白显示功能.垂直画面旋转功能.休眠模式2.4.3 电源模块 电源模块可以直接提供正5V的直流电压,但是由于在一些工业环境中并不提供直流电源,而都是交流电源,为确保其实用性,在电源这一部分,提供了整流稳压电路,可以把交流电压变成5V的电压,为整个电路板提供电源。 从图2-6可以看出,当开关按下时,电路接通,先通过一个整流电路,使交流电压变成直流电压。为了保证其输出的电压是5V,在后面接一个稳压电路,由一个7805稳压器和一个发光二极管组成,发光二极管作为电源导通的指示灯。当电源导通时二极管发光。其中电容C1起滤波作用,电容C2是抑制高平信号。电容C3, C4直接接地,起到抗干扰的作用,能使电压稳定在5V。有了电源模块避免了因没有直流电源而无法使用的问题,使这个仪表能够在更多的环境中使用。电源模块电路图如图2-6所示:3 系统软件的设计3.1 系统程序工作分析 在本文的电路板中,单片机是作为控制器嵌入到系统中。应用程序的开发主要分为两大部分,即对ZAZ-010指纹识别模块的的应用程序开发以及对HS12864液晶、按键程序的开发。因此,要实现其应用,需要对其进行联合调试。电路软件应用开发根据所设计的硬件。程序开发的方式将主要建立一系列的C语言函数子程序供主程序的随时调用。即对ZAZ-010指纹识别模块或液晶电路分别编制C语言函数子程序。因此,需要有专门的开发工具。本设计中,采用AVRStudio4.0单片机软件开发环境对单片机进行编程,由于该编译器支持模块化程序设计,因此可以先将源程序划分为几个模块分别编写,然后再由编译器生成一个最终文件. 该开发环境可以对程序进行软件仿真调试,因此可以方便地进行程序的编写和调试。调试通过的代码文件通过开发板下载到单片机。单片机在上电后,主程序应该完成相应的初始化工作。依据电路的功能要求,主程序必须对液晶初始化、同时对按键进行检测,如果有对应的按键按下。执行相应的操作,单片机通过串行接口对指纹模块进行读写。