OpenCV实战(31)——基于级联Haar特征的目标检测

OpenCV实战(31)——基于级联Haar特征的目标检测

    • 0. 前言
    • 1. Haar 特征图像表示
    • 2. 基于级联 Haar 特征的二分类分类器
    • 3. 级联分类器算法流程
    • 4. 使用 Haar 级联检测器进行人脸检测
    • 5. 完整代码
    • 小结
    • 系列链接

0. 前言

在机器学习基础一节中,我们介绍了机器学习的一些基本概念,并通过使用不同类别的样本来构建分类器。但这种方法训练分类器需要存储所有样本的表示,然后通过查看最近标记点(最近邻居)来预测新实例的标签。对于大多数机器学习方法,训练是一个迭代过程,在此过程中通过循环遍历样本来构建机器学习模型。通过使用更多的样本,得到的分类器性能会逐渐提高。当模型性能达到预设值或者当无法从当前训练数据集中获得更多改进时,学习过程将停止。本节中,我们将介绍一种遵循以上过程的机器学习算法,即级联分类器。

1. Haar 特征图像表示

在我们继续学习该分类器之前,首先将介绍 Haar 特征图像表示。我们已经知道,良好的图像表示是生成鲁棒性分类器的基本要素。
生成分类器的第一步是获取大量图像样本集合,这些样本包含要识别的对象类别的不同实例,样本的表示方式对利用样本构建的分类器的性能具有重要影响。像素级表示通常由于过于低级,而无法鲁棒地描述每一类对象的内在特征。相反,可以在多个尺度上描述图像中存在的独特图案的表示能够更好的表示图像特征。这就是 Haar 特征 (Haar features) 的基本思想,也称为类 Haar 特征 (Haar-like features),因为它们都源自 Haar 变换基函数 (Haar transform basis functions)。
Haar 特征定义了像素的小矩形区域,稍后通过简单的减法进行比较。通常可以使用三种不同的配置,即 2-矩形3-矩形4-矩形特征:

矩形区域

这些特征可以是任意大小并应用于要表示的图像的任何区域。例如,下图中包括两个应用于人脸图像的 Haar 特征:

应用于人脸图像的 Haar 特征
构建 Haar 表示包括选择任何给定类型、大小和位置的多个 Haar 特征,并将它们应用于图像。从选定的一组 Haar 特征中获得的一组特定值构成了图像表示。接下来,面临的挑战是确定要选择哪一组特征。事实上,为了区分不同对象,使用其中某些 Haar 特征可能比其他特征更有效。例如,在人脸图像样本中,在眼睛之间应用 3-矩形 Haar 特征(如上图所示)可能更有效。当然,由于存在数十万个可能的 Haar 特征,因此手动进行选择是十分困难的,我们需要使用机器学习方法来为给定的对象类别选择最相关的特征。

2. 基于级联 Haar 特征的二分类分类器

在本节中,我们将学习如何使用 OpenCV 构建增强的级联特征以生成二分类分类器。二分类分类器是一种可以从其他类别(例如,不包含人脸的图像)中识别出指定类(例如,人脸图像)实例的分类器,即分类任务中仅存在两个类别。在这种情况下,我们使用正样本(即人脸图像)和负样本(即非人脸图像)表示两种类别。本节使用的分类器由一系列简单的分类器组成,一次应用这些分类器。级联分类器的每一阶段都将根据为一小部分特征获得的值快速决定是否拒绝对象。在每个阶段通过做出更准确的决策来改进(或提升)前一个阶段的分类器性能,这种级联结构提升了分类器性能。这种方法的主要优点是级联的早期阶段由简单的检测组成,然后可以快速拒绝无关的类实例,使得级联分类器的计算更快,因为当通过扫描图像搜索一类对象时,大多数要测试的子窗口不属于我们感兴趣的类别。这样,只有少数窗口需要通过所有阶段才能决定被接受或拒绝。

(1) 为了训练增强级联分类器,OpenCV 提供用于执行这些操作的工具。安装 OpenCV 库时,会创建两个可执行程序并位于 bin 目录中:opencv_createsamplesopencv_traincascade

可执行程序

(2) 在训练分类器时,首先需要收集样本。正赝本由目标类实例的图像组成,在本节中,我们旨在训练一个分类器来识别交通标志,使用的正样本如下:

正样本

(3) 使用的正样本列表在名为 sign.txt 的文本文件中指定,文件包含图像文件名和边界框坐标:

1.png 1 0 0 64 64
2.png 1 0 0 64 64
3.png 1 0 0 64 64
4.png 1 0 0 64 64
5.png 1 0 0 64 64
6.png 1 0 0 64 64
7.png 1 0 0 64 64
8.png 1 0 0 64 64
9.png 1 0 0 64 64

(4) 文件名后的第一个数字是图像中包含的正样本数,紧接着的两个值是包含正样本的边界框的左上角坐标,最后两个值是目标的宽度和高度。在本节中,我们已经在原始图像中提取了正样本,因此每个文件中有且仅有一个样本并且左上角坐标为 (0, 0)。接下来,通过运行提取器工具来创建正样本文件:

opencv_createsamples -info sign.txt -vec sign.vec -w 24 -h 24 -num 9

(5) 以上代码将创建 stop.vec 输出文件,其中包含输入文本文件中指定的所有正样本。需要注意的是,我们使样本大小 (24×24) 小于原始大小 (64×64),提取器工具将所有样本的大小调整为指定的大小。通常,Haar 特征与较小的模板能够更好的配合,但这必须根据具体情况进行验证。

(6) 负样本是不包含感兴趣类别实例的图像(在本节中,指不包含交通标志的图像)。除此之外,这些图像应该包含分类器期望获得的各类图像。这些负样本可以是任意大小,因为训练工具可以从这些图像中提取随机负样本:

负样本

(7) 一旦正负样本准备完毕,就可以训练级联分类器了:

opencv_traincascade -data classifier -vec sign.vec -bg neg.txt -numPos 9 -numNeg 18 -numStages 20 -minHitRate 0.95 -maxFalseAlarmRate 0.5 -w 24 -h 24

需要注意的是,训练过程可能需要很长时间,在涉及数千个样本的复杂分类器中,训练过程甚至可能需要数天时间。运行训练程序时,级联分类器会在每次完成一个阶段的训练时打印出性能报告,给出分类器当前的命中率 (hit rate, HR),这是级联分类器当前接受的正样本的百分比(即,它们被正确识别为正样本,这种情况也称为真正例),我们希望该数字尽可能接近 1.0。报告还会提供当前的误报率 (false alarm rate, FAR),即被错误分类为正样本(也称为假正例)的已测试负样本的数量,我们希望该数字尽可能接近 0.0
在我们的分类器中训练只需几秒钟,生成的分类器的结构在训练阶段产生的 XML 文件中进行描述。训练完成后,就可以使用分类器了,我们可以向它输入任意样本,分类器将输出预测结果。

(8) 在本节中,我们用 24×24 的图像训练了级联分类器,但是,一般来说,我们需要找出任意尺寸图像的任意位置是否有类对象的实例。为了实现这一目标,我们需要扫描输入图像并提取样本大小的所有可能窗口。如果分类器足够准确,则只有包含目标对象的窗口才会返回正样本预测。但是,这仅在正样本具有合适大小时才有效,要在多个尺度上检测对象实例,必须通过构建图像金字塔,在每个级别将原始图像的大小进行缩放。通过这种方式,沿着金字塔向下,更大的目标示例最终将缩放至合适的大小。这是一个漫长的过程,但是 OpenCV 提供了实现此过程的类。首先,需要通过加载合适的 XML 文件来构建分类器:

    cv::CascadeClassifier cascade;if (!cascade.load("classifier/cascade.xml")) { std::cout << "Error when loading the cascade classfier!" << std::endl; return -1; }

(9) 然后,使用输入图像调用检测方法:

    // 预测图片标签std::vector<cv::Rect> detections;cascade.detectMultiScale(inputImage,    // 输入图像detections,     // 检测结果1.1,            // 尺度缩放因子1,              // 所需邻居检测数0,              // 标志位cv::Size(48, 48),       // 要检测的最小对象大小cv::Size(200, 200));    // 要检测的最大对象大小std::cout << "detections= " << detections.size() << std::endl;for (int i = 0; i < detections.size(); i++)cv::rectangle(inputImage, detections[i], cv::Scalar(255, 255, 255), 2);cv::imshow("Sign detection", inputImage);

(10) 返回 cv::Rect 实例的向量,要可视化检测结果,只需在输入图像上绘制这些矩形:

    for (int i = 0; i < detections.size(); i++)cv::rectangle(inputImage, detections[i], cv::Scalar(255, 255, 255), 2);cv::imshow("Sign detection", inputImage);

使用分类器在图像上进行测试,可以得到以下结果:

分类器测试结果

3. 级联分类器算法流程

在上一小节中,我们介绍了如何使用正负样本构建 OpenCV 级联分类器,接下来,我们将介绍训练级联分类器的基本步骤。我们介绍的级联分类器使用了 Haar 特征进行训练,但是,我们也可以使用其他图像特征构建级联分类器。
级联分类器背后包含两个核心思想。第一个是可以通过将几个性能较弱的分类器(即基于简单特征的分类器)组合在一起来构建得到性能较强的分类器;其次,在机器视觉中,负样本出现的概率比正样本更频繁,因此可以通过划分阶段进行有效的分类。早期阶段迅速拒绝明显的负实例,后期阶段对更复杂的样本做出更精细的决策。基于以上思想,我们继续介绍提升级联学习算法 (boosted cascade learning algorithm),我们所使用的算法基于 boosting 的变体算法 AdaBoost
在本节中,我们使用 Haar 特征来构建弱分类器。当应用一个 Haar 特征(给定类型、大小和位置)时,将获得一个值。然后通过找到最能根据该特征值对负实例和正实例进行分类的阈值来获得一个简单的分类器。为了找到最佳阈值,我们可以使用一些正样本和负样本 (opencv_traincascade 使用的正样本和负样本的数量由 -numPos-numNeg 参数指定)。由于有大量可能的 Haar 特征,检查所有特征并选择能够对样本集进行分类的最佳特征,显然,这个基础的分类器可能出错,即出现错误分类的情况,因此我们需要构建数个这种分类器,这些分类器是迭代添加的,每次搜索新的 Haar 特征时都会给出最佳分类。但是,由于在每次迭代中,我们都希望关注当前被错误分类的样本,因此通过对错误分类的样本赋予更高的权重来衡量分类性能。因此,最终将获得一组简单的分类器,然后根据这些弱分类器的加权和构建强分类器(即,性能更好的分类器被赋予更高的权重)。使用这种方法,可以通过组合数百个简单的特征来获得具有良好性能的强分类器。
然而,训练早期我们不希望由大量弱分类器组成强分类器。相反,我们需要找到仅使用少量 Haar 特征的简单分类器,以便快速拒绝明显的负样本,同时保留所有正样本。在经典形式中,AdaBoost 旨在通过计算假阴性(即被错误分类为负样本的正样本)和假阳性(即错误分类为正样本的负样本)的数量来最小化总分类误差。我们的目标是将绝大多数甚至全部正样本正确分类,同时最小化误报率,可以通过修改 AdaBoost 以便在预测真正例时给予更高的奖励。因此,在训练级联分类器的每个阶段,必须设置两个标准——最小命中率和最大误报率;在 opencv_traincascade 中,使用 -minHitRate (默认值为 0.995) 和 -maxFalseAlarmRate (默认值为 0.5) 参数指定。在各个阶段添加 Haar 特征,直到满足这两个性能标准。必须将最小命中率设置得较高,以确保正实例能够进入下一阶段;需要注意的是,如果某个正实例在某个阶段被拒绝,则无法恢复被拒绝的正实例。因此,为了便于生成低复杂度的分类器,应将最大误报率设置得较高。否则,将需要较多的 Haar 特征才能满足性能标准,这与早期训练弱分类器的思想相矛盾。
因此,一个好的级联分类器在早期应使用较少特征的组成,随着级联的增加,每个阶段的特征数量随之增加。在 opencv_traincascade 中,每个阶段的最大特征数使用 -maxWeakCount (默认值为 100) 参数设置,阶段数使用 -numStages (默认值为 20) 参数设置。
当开始新阶段的训练时,必须收集新的负样本,可以从提供的负样本图像中提取。难点是找到通过所有前期阶段的负样本(即那些被错误分类为正样本的样本)。训练的阶段越多,收集这些负样本就越困难,这就是需要为分类器提供大量负样本图像的原因,从难以分类的图像块中提取样本(因为它们类似于正样本)。此外,如果在给定阶段,在不添加任何新特征的情况下满足了两个性能标准,那么级联训练将在停止,这意味着我们可以按原样使用该模型,或者通过提供更多复杂样品。反之,如果无法达到性能标准,则训练也会停止,在这种情况下,我们应该使用更简单的性能标准尝试新的训练过程。
通过由 n 个阶段组成的级联分类器,可以很容易地证明分类器的全局性能至少会优于 minHitRatemaxFalseAlarmRate,这是由于每个阶段都建立在先前级联阶段的结果之上。例如,我们考虑 opencv_traincascade 的默认值,期望分类器具有 0.99 5 20 0.995^{20} 0.99520 的准确率(命中率)和 0. 5 20 0.5^{20} 0.520 的误报率。这意味着 90% 的正样本能被正确识别,0.001% 的负样本将被错误地归类为正样本。需要注意的是,当进行级联时,一部分正样本将丢失,我们必须提供比每个阶段使用的指定样本数量更多的正样本。在以上示例中,我们将 numPos 设置为可用正样本数量的 90%
一个重要的问题是应该使用多少样本进行训练?这需要根据具体应用判断,但显然,正样本集必须足够大才能涵盖大部分类实例。负样本图片也应该是相关的,通常的经验法则是令 numNeg = 2 * numPos
本节中,我们已经介绍了如何使用 Haar 特征构建级联分类器。此类特征也可以使用其他特征来构建,例如 LBP 特征或定向梯度直方图等,在 opencv_traincascade 程序中可以使用 -featureType 参数选择不同的特征类型。
OpenCV 库包含了许多预训练的级联分类器,可以使用这些分类器来检测人脸、面部特征等,我们可以在源目录的数据目录中找到这些 XML 文件。

4. 使用 Haar 级联检测器进行人脸检测

OpenCV 中已经提供了预训练的人脸检测模型,我们要做的就是使用适当的 XML 文件创建 cv::CascadeClassifier 类的实例:

    cv::CascadeClassifier faceCascade;if (!faceCascade.load("haarcascade_frontalface_default.xml")) {std::cout << "Error when loading the face cascade classfier!" << std::endl;return -1;}

然后,要检测具有 Haar 特征的人脸:

   faceCascade.detectMultiScale(picture,   // 输入图像detections,                 // 检测结果1.1,                        // 尺度缩放因子3,                          // 所需邻居检测数0,                          // 标记位cv::Size(48, 48),           // 要检测的最小对象大小cv::Size(200, 200));        // 要检测的最大对象大小std::cout << "detections= " << detections.size() << std::endl;

也可以使用相同的过程检测人物眼睛:

人脸检测

5. 完整代码

完整代码 detectObjects.cpp 如下所示:

#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/objdetect.hpp>int main() {// 打开正样本std::vector<cv::Mat> referenceImages;referenceImages.push_back(cv::imread("1.png"));referenceImages.push_back(cv::imread("2.png"));referenceImages.push_back(cv::imread("3.png"));referenceImages.push_back(cv::imread("4.png"));referenceImages.push_back(cv::imread("5.png"));referenceImages.push_back(cv::imread("6.png"));referenceImages.push_back(cv::imread("7.png"));referenceImages.push_back(cv::imread("8.png"));referenceImages.push_back(cv::imread("9.png"));// 组合图像cv::Mat positveImages(2 * referenceImages[0].rows, 4 * referenceImages[0].cols, CV_8UC3);for (int i = 0; i < 2; i++)for (int j = 0; j < 4; j++) {referenceImages[i * 2 + j].copyTo(positveImages(cv::Rect(j*referenceImages[i * 2 + j].cols, i*referenceImages[i * 2 + j].rows, referenceImages[i * 2 + j].cols, referenceImages[i * 2 + j].rows)));}cv::imshow("Positive samples", positveImages);cv::Mat negative = cv::imread("n1.jpg");cv::resize(negative, negative, cv::Size(), 0.33, 0.33);cv::imshow("One negative sample", negative);cv::Mat inputImage = cv::imread("sign.png");cv::resize(inputImage, inputImage, cv::Size(), 0.5, 0.5);cv::CascadeClassifier cascade;if (!cascade.load("classifier/cascade.xml")) { std::cout << "Error when loading the cascade classfier!" << std::endl; return -1; }// 预测图片标签std::vector<cv::Rect> detections;cascade.detectMultiScale(inputImage,    // 输入图像detections,     // 检测结果1.1,            // 尺度缩放因子1,              // 所需邻居检测数0,              // 标志位cv::Size(48, 48),       // 要检测的最小对象大小cv::Size(200, 200));    // 要检测的最大对象大小std::cout << "detections= " << detections.size() << std::endl;for (int i = 0; i < detections.size(); i++)cv::rectangle(inputImage, detections[i], cv::Scalar(255, 255, 255), 2);cv::imshow("Sign detection", inputImage);// 人脸检测cv::Mat picture = cv::imread("girl.png");cv::CascadeClassifier faceCascade;if (!faceCascade.load("haarcascade_frontalface_default.xml")) {std::cout << "Error when loading the face cascade classfier!" << std::endl;return -1;}faceCascade.detectMultiScale(picture,   // 输入图像detections,                 // 检测结果1.1,                        // 尺度缩放因子3,                          // 所需邻居检测数0,                          // 标记位cv::Size(48, 48),           // 要检测的最小对象大小cv::Size(200, 200));        // 要检测的最大对象大小std::cout << "detections= " << detections.size() << std::endl;// 绘制检测到的对象边界框for (int i = 0; i < detections.size(); i++)cv::rectangle(picture, detections[i], cv::Scalar(255, 255, 255), 2);// 检测眼睛cv::CascadeClassifier eyeCascade;if (!eyeCascade.load("haarcascade_eye.xml")) {std::cout << "Error when loading the eye cascade classfier!" << std::endl;return -1;}eyeCascade.detectMultiScale(picture,    // 输入图像detections,                 // 检测结果1.1,                        // 尺度缩放因子3,                          // 所需邻居检测数0,                          // 标记位cv::Size(24, 24),           // 要检测的最小对象大小cv::Size(36, 36));          // 要检测的最大对象大小std::cout << "detections= " << detections.size() << std::endl;// 绘制检测到的对象边界框for (int i = 0; i < detections.size(); i++)cv::rectangle(picture, detections[i], cv::Scalar(0, 0, 0), 2);cv::imshow("Detection results", picture);cv::waitKey();return 0;
}

小结

Haar 特征能够在多个尺度上描述图像中存在的独特图案的表示,可以更好的表示图像特征,级联分类器通过将几个性能较弱的分类器组合在一起来构建得到性能较强的分类器,本节介绍了使用 cv::CascadeClassifier 函数实现级联 Haar 特征执行目标检测。

系列链接

OpenCV实战(1)——OpenCV与图像处理基础
OpenCV实战(2)——OpenCV核心数据结构
OpenCV实战(3)——图像感兴趣区域
OpenCV实战(4)——像素操作
OpenCV实战(5)——图像运算详解
OpenCV实战(6)——OpenCV策略设计模式
OpenCV实战(7)——OpenCV色彩空间转换
OpenCV实战(8)——直方图详解
OpenCV实战(9)——基于反向投影直方图检测图像内容
OpenCV实战(10)——积分图像详解
OpenCV实战(11)——形态学变换详解
OpenCV实战(12)——图像滤波详解
OpenCV实战(13)——高通滤波器及其应用
OpenCV实战(14)——图像线条提取
OpenCV实战(15)——轮廓检测详解
OpenCV实战(16)——角点检测详解
OpenCV实战(17)——FAST特征点检测
OpenCV实战(18)——特征匹配
OpenCV实战(19)——特征描述符
OpenCV实战(20)——图像投影关系
OpenCV实战(21)——基于随机样本一致匹配图像
OpenCV实战(22)——单应性及其应用
OpenCV实战(23)——相机标定
OpenCV实战(24)——相机姿态估计
OpenCV实战(25)——3D场景重建
OpenCV实战(26)——视频序列处理
OpenCV实战(27)——追踪视频中的特征点
OpenCV实战(28)——光流估计
OpenCV实战(29)——视频对象追踪
OpenCV实战(30)——OpenCV与机器学习的碰撞

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

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

相关文章

Unity UI与粒子 层级问题Camera depth Sorting Layer Order in Layer RenderQueue

Unity游戏开发中&#xff0c;模型、界面、特效等&#xff0c;需要规划好layer的概念&#xff0c;涉及到摄像机&#xff08;Camera&#xff09;、画布&#xff08;Canvas&#xff09;、Shader等相关内容。 在 Unity 中&#xff0c;渲染顺序是由多个因素共同决定的&#xff0c;大…

【广州华锐互动】数字孪生智慧楼宇3D可视化系统:掌握实时运行状态,优化运营管理

在过去的几年中&#xff0c;科技的发展极大地改变了我们的生活和工作方式。其中&#xff0c;三维数据可视化技术的出现&#xff0c;为我们提供了全新的理解和观察世界的方式。特别是在建筑行业&#xff0c;数字孪生智慧楼宇3D可视化系统的出现&#xff0c;让我们有机会重新定义…

Spring的重试机制-SpringRetry

在我们的日常开发中&#xff0c;经查会遇到调用接口失败的情况&#xff0c;这时候就需要通过一些方法来进行重试&#xff0c;比如通过while循环手动重复调用或&#xff0c;或者通过记录错误接口url和参数到数据库&#xff0c;然后手动调用接口&#xff0c;或者通过JDK/CGLib动态…

分享一些用的上的商务英语

前些天美元汇率有时候去到7.3左右&#xff0c;当时跟一个朋友聊天&#xff0c;是时候去问候一下那些报价的时候汇率在六点多没下单的客户了&#xff0c;也许可以通过汇率变动这个理由给他稍微降点价格把订单拿下。 我们做报价的时候&#xff0c;可以标注固定的汇率&#xff0c…

[dasctf]misc1

不确定何种加密方式 P7NhnTtPUm/L3rmkP/eAhx5Vnbc2YyatkXCePJ0Wh2NYfqXGZCpZdCesMmEAihhUYI1PjoLq6FedZ7MSclA9h0/Dy4CavBwVg5RHr8XJmfbtuWkxK2Gn3sNTEzQi0p 1t_15_s3cR3t_k3y 也许是密钥

uniapp 微信小程序 锚点跳转

uniapp文档 以下是我遇到的业务场景&#xff0c;是点击商品分类的某一类 然后页面滚动至目标分类&#xff0c; 首先第一步是设置锚点跳转的目的地&#xff0c;在目标的dom上面添加id属性 然后给每个分类每一项添加点击事件&#xff0c;分类这里的item数据里面有一字段是和上…

Linux搭建GitLab私有仓库,并内网穿透实现公网访问

目录 前言 1.下载Gitlab 2.安装Gitlab 3.启动Gitlab 4.安装cpolar 5. 创建隧道配置访问地址 6.固定GitLab访问地址 7. 配置二级子域名 8. 测试访问二级子域名 前言 GitLab 是一个用于仓库管理系统的开源项目&#xff0c;使用Git作为代码管理工具&#xff0c;并在此基…

探索未来金融科技 SCF新加坡举办启动盛会

金融科技的热潮涌向新加坡&#xff0c;令人瞩目的SCF金融公链启动会于8月13日隆重举行。这场盛宴不仅为金融科技领域注入了新的活力&#xff0c;更为广大投资者、合作伙伴以及热衷区块链发展的人士提供了一次宝贵的交流机会。 在SCF金融公链启动会上&#xff0c;William Thomps…

Andorid 属性动画ObjectAnimation整理

属性动画相关内容可参考官网 动画资源 属性动画概览 来自官网的说明&#xff0c; 属性动画与视图动画的区别 视图动画系统仅提供为 View 对象添加动画效果的功能&#xff0c;因此&#xff0c;如果您想为非 对象添加动画效果&#xff0c;则必须实现自己的代码才能做到。视图动…

Linux开源防病毒引擎ClamAV

ClamAV官方地址&#xff1a;https://www.clamav.net 它支持Linux、BSD、windows、Mac OS X等系统。 在CentOS 8&#xff08;Tencent OS 3.1&#xff09;安装非常便利&#xff0c;可以使用yum。 yum install clamav 安装成功&#xff0c;就可以使用它进行病毒扫描检查了。 c…

性能提升5倍!翼支付基于多租户的降本增效实践

作者&#xff1a;王硕 中国电信翼支付 DBA 翼支付是天翼电子商务有限公司旗下第三方服务平台&#xff0c;面向 7000 万月活用户&#xff0c;提供民生缴费、消费购物、金融理财等服务内容&#xff0c;依托云计算、大数据、人工智能等技术&#xff0c;联合合作伙伴&#xff0c;赋…

一、安装GoLang环境和开发工具

一、安装GoLang环境 GoLang中国镜像站 下载后对应的环境包以后&#xff0c;一路下一步就好了&#xff0c;安装路径的话&#xff0c;尽量就安装到默认的文件目录下。 二、配置Go的环境变量 右击此电脑–>属性–>高级系统设置–>环境变量&#xff0c;打开环境变量设置…

苹果电脑mac资源下载工具Folx 5

Folx是一款Mac下载管理器&#xff0c;Folx兼容主流的浏览器&#xff0c;会接替系统成为默认下载工具&#xff0c;不但可以下载网络上的任何文件&#xff0c;而且可以支持断点续传、多线程等功能&#xff0c;而且Folx下载工具经过一次彻底更新之后推出了它的第五代Folx 5&#x…

ChatGPT Prompting开发实战(四)

一、chaining prompts应用解析及输出文本的设定 由于输入和输出都是字符串形式的自然语言&#xff0c;为了方便输入和输出信息与系统设定使用的JSON格式之间进行转换&#xff0c;接下来定义从输入字符串转为JSON list的方法&#xff1a; 定义从JSON list转为输出字符串的方法&…

SPSS统计作图教程:百分条图堆积条图

1、问题与数据 某研究者想看不同年龄分组人群&#xff08;Age_cat&#xff09;中不同程度的维生素D缺乏&#xff08;VD&#xff09;的百分构成比&#xff0c;部分数据如图1。研究者想以条图形式来展现&#xff0c;该如何操作呢&#xff1f; 图1 部分数据 2. 具体操作&#xf…

将 Llama2 中文模型接入 FastGPT,再将 FastGPT 接入任意 GPT 套壳应用,真刺激!

FastGPT 是一个基于 LLM 大语言模型的知识库问答系统&#xff0c;提供开箱即用的数据处理、模型调用等能力。同时可以通过 Flow 可视化进行工作流编排&#xff0c;从而实现复杂的问答场景&#xff01; Llama2 是Facebook 母公司 Meta 发布的开源可商用大模型&#xff0c;国内的…

javaweb入门版学生信息管理系统-增删改查+JSP+Jstl+El

dao public class StudentDao {QueryRunner queryRunner QueryRunnerUtils.getQueryRunner();//查询全部学生信息public List<Student> selectStudent(){String sql "select * from tb_student";List<Student> students null;try {students queryRunn…

关于大模型参数微调的不同方法

Adapter Tuning 适配器模块&#xff08;Adapter Moudle&#xff09;可以生成一个紧凑且可扩展的模型&#xff1b;每个任务只需要添加少量可训练参数&#xff0c;并且可以在不重新访问之前任务的情况下添加新任务。原始网络的参数保持不变&#xff0c;实现了高度的参数共享 Pa…

django/CVE-2017-12794XSS漏洞复现

docker搭建漏洞复现环境 漏洞原理看帮助文档 # Django debug page XSS漏洞&#xff08;CVE-2017-12794&#xff09;分析Django发布了新版本1.11.5&#xff0c;修复了500页面中可能存在的一个XSS漏洞&#xff0c;这篇文章说明一下该漏洞的原理和复现&#xff0c;和我的一点点评…

音视频入门基础理论知识

文章目录 前言一、视频1、视频的概念2、常见的视频格式3、视频帧4、帧率5、色彩空间6、采用 YUV 的优势7、RGB 和 YUV 的换算 二、音频1、音频的概念2、采样率和采样位数①、采样率②、采样位数 3、音频编码4、声道数5、码率6、音频格式 三、编码1、为什么要编码2、视频编码①、…