使用SVM在数字验证码识别中的应用研究课程报告

news2025/1/16 2:03:28

第1章 概要设计

1.1 设计目的

支持向量机作为一类强大的监督学习模型,以其出色的泛化能力,在手写数字识别、面部检测、图像分类等多个领域展现出了其优越性。其在处理小样本、非线性及高维模式识别任务中表现尤为突出。SVM通过构造最优超平面,在保证分类准确性的同时,最大限度地提高了分类决策的置信度。此外,其核技巧有效地解决了线性不可分问题,使得SVM在图像识别领域尤为适用。

本研究旨在探索SVM在特定应用场景——数字验证码图像训练和识别——中的有效性及可行性。具体而言,本研究将基于Python语言,使用sklearn库中的SVM模块开发一套数字验证码的识别程序。研究的主要目的是验证SVM在数字验证码图像识别任务上的准确率和泛化性能,同时对比不同核函数对模型性能的影响,以寻找最优的模型配置。

1.2 选题

验证码(CAPTCHA)是一种常见的用于区分人类和机器的技术,常用于网站、APP用户登陆时输入一些数字或字符以验证其身份。本文将介绍如何使用SVM来识别常见的字符验证码。

选择使用支持向量机进行验证码识别方向的原因具体如下:

1. 卓越的泛化能力:SVM在设计时就是以最小化结构风险为目标,而不仅仅是经验风险,这赋予了SVM模型极好的泛化能力,即对于未见样本的预测能力。在验证码识别任务中,能够正确识别新的、未经过训练的验证码图片是至关重要的。

2. 处理小样本的优势:相比于深度学习等其他机器学习方法,SVM在小样本情况下依然能够保持较好的分类性能,这对于验证码这种较难获取大量标注数据的场景尤为重要。

3. 高维空间的效率:由于SVM能够有效处理高维数据,并且通过核技巧隐式地在高维空间中寻找最优的线性划分,使得其在图像识别任务中,即使面对大量特征的情形下仍具有高效的计算性能。

4. 灵活的核函数选择:SVM可以通过选择不同的核函数来适应不同的数据分布,如线性核、多项式核、径向基核等,使得其对各种类型的验证码都有很好的识别潜力。

5. 成熟的理论和实践基础:SVM作为一种经典的机器学习算法,拥有成熟的理论基础和广泛的应用场景,这意味着在实施过程中可以借鉴丰富的先前研究和实践经验,降低开发难度并加快开发周期。

6. 字符识别方面显著表现:在以往的研究中,SVM在字符型图片验证码识别任务上已经展现出了显著的性能,包括高准确率和良好的泛化性,这使得SVM成为了解决此类问题的有效工具。

综上所述,SVM在验证码识别领域的应用具有多方面的优势,从理论基础到实践应用都显示出其适用于该领域的特性。因此,选择SVM进行验证码识别不仅基于其技术上的优势,也在于其在实际应用中所展现出来的高效性和准确性。

1.3 支持向量机(SVM)算法的原理

支持向量机(SVM)是一种监督学习算法,主要用于解决二分类问题,其核心思想是通过在特征空间中找到最优的超平面来进行分类,同时使间隔最大化。

(1) 超平面与间隔:

SVM算法的核心思想是在特征空间中寻找一个最优的超平面,该超平面能够将不同类别的样本分隔开。

这个超平面可以被定义为在n维空间中的一个(n-1)维子空间,其中n是特征的数量。

SVM通过最大化两个类别之间的间隔来确定这个超平面。间隔是指超平面到最近的样本距离的两倍。这个间隔越大,模型的泛化能力通常越强。

(2) 核函数与映射:

当数据在原始空间中不可分时,SVM算法会将数据映射到一个更高维的空间中,使得数据在该空间中变得线性可分。

这种映射通常是通过核函数来实现的,核函数可以计算两个样本在高维空间中的相似度。常见的核函数包括线性核、多项式核、高斯核等。

(3) 分类与软间隔:

SVM算法主要用于二分类问题,但也可以通过多次训练和组合来解决多分类问题。

在处理线性不可分的数据时,SVM允许一些样本在超平面的错误一侧,即引入软间隔的概念。这可以通过引入惩罚参数来平衡间隔的大小和分类错误的容忍度。

(4) 优化与求解:

SVM算法的训练过程可以转化为一个凸优化问题,通常被表述为一个二次规划问题。

由于二次规划问题具有全局最优解,因此可以使用现有的优化算法来求解SVM的最优超平面。

(5)优点与缺点:

优点:SVM能够处理高维数据,具有较强的泛化能力,适用于小样本数据,可以处理非线性问题,具有较好的鲁棒性和可解释性。

缺点:SVM对参数的敏感性较高,计算复杂度较高,尤其是当数据集较大或特征维度较高时。此外,SVM对数据的缩放和噪声也比较敏感。

综上所述,SVM算法通过寻找最优超平面来实现数据分类,其性能受到核函数、软间隔以及惩罚参数等因素的影响。在实际应用中,需要根据具体的数据和任务来选择合适的SVM模型和参数设置。

1.4 程序概要设计

验证码(CAPTCHA)是一种常见的用于区分人类和机器的技术,常用于网站、APP用户登陆时输入一些数字或字符以验证其身份。使用支持向量机(SVM)来识别常见的字符验证码,主要步骤流程如下。

(1)数据收集与预处理

数据收集:收集包含不同字符、字体、背景、噪点、扭曲等变化的验证码图像数据集。

数据标注:对每个验证码图像进行人工标注,确定其对应的字符序列。

图像预处理:对图像进行去噪、二值化等处理,以便后续的特征提取

(2)特征值提取

基于像素的特征:可以使用图像的原始像素值或像素的统计信息(如直方图)作为特征。

基于形状的特征:对于字符验证码,可以提取字符的轮廓、边缘、角点等形状特征。

基于纹理的特征:利用局部二值模式(LBP)、灰度共生矩阵(GLCM)等方法提取字符的纹理特征。

(3)支持向量机(SVM)模型训练

核函数选择:根据数据特点选择合适的核函数,如线性核、多项式核、径向基函数(RBF)核等。

参数优化:使用交叉验证和网格搜索等方法优化SVM的惩罚参数C和核函数参数(如RBF核的gamma)。

模型训练:使用标注好的数据集训练SVM模型,得到字符分类器。

(4)评估模型和改进

评估指标:使用准确率指标评估模型的性能。

错误分析:对识别错误的验证码进行错误分析,找出模型存在的问题和改进方向。

模型改进:根据错误分析的结果,调整特征提取方法、优化SVM参数、使用更先进的模型等方法来改进模型的性能。

第2章 程序整体设计说明

2.1  数据收集与预处理

        首先,我们需要收集带有字符验证码的图片数据,并将其分为训练集和测试集。确保每张图片都标记了正确的字符。

很多网站都有验证码功能,可以先写个爬取验证码图片的脚本,采集了500份目标网站的验证码图片;80%用于训练数据集,20%用于测试数据集;然后人工打上标签,把答案作为验证码图片的文件名前4个字符。

然后需要将采集的500份验证码图片进行字符切割预处理,分割成单个字符的图片保存,这些分割后的图片才是训练数据集和测试数据集,单个字符图片更适合于SVM算法训练,训练的模型准确度更高。

# 数据集目录结构示例:

# ├── data

# │   ├── image_train

# │   │        ├── 0

# │   │        ├── 1

# │   │        ├── 2

# │   │        ├── ...

# │   ├── image_test

# │   │        ├── 0

# │   │        ├── 1

# │   │        ├── 2

# │   │        ├── ...

(1)    标签列表

使用单个数字整数作为样本的标签值,保证是统一的整数分类形式。

(2)    导入数据集方法

根据目录导入数据集,统一处理样本集,获取图片的特征值,将特征值添加到特征列表中;图片标签需要统一转换下,然后添加到标签列表中返回。

# 加载数据集(这里已经有一个包含标签的图片文件夹)

def load_dataset(data_folder):
    labels = []
    features = []
    for label in os.listdir(data_folder):
        label_dir = os.path.join(data_folder, label)
        for filename in os.listdir(label_dir):
            if filename.endswith('.png'):
                image_path = os.path.join(label_dir, filename)
                # 提取特征
                feat = extract_features(image_path)
                # 将图像特征值添加到列表中
                features.append(feat)
                # 将图像标签值添加到列表中
                labels.append(int(label))
    return np.array(features), np.array(labels)

(3)    加载训练数据和测试数据

# 加载训练数据和测试数据
train_features, train_labels = load_dataset('./data/image_train')
test_features, test_labels = load_dataset('./data/image_test')
print(f"训练集特征值列表:{train_features}")
print(f"测试集特征值列表:{test_features}")
print(f"训练集标签:{train_labels}")
print(f"测试集标签:{test_labels}")
print(f"训练集数量:{train_labels.size}")
print(f"测试集数量:{test_labels.size}")
2.2  特征值提取

数字验证码有位置、方向、周长、面积、矩形度、宽长比、球状性、圆形度、不变矩、偏心率等各种特征。对图像进行灰度化再经过二值化等处理可以得到图像中数字的轮廓,利用该轮廓可以求得各种特征,利用一些特征构造模型可以实现对数字种类的检测识别,通过多次筛选,选出性能最优的几种特征值列表。

# 提取特征
def extract_features(image_path):
    # 步骤 1: 读取图像
    image = cv2.imread(image_path)
    # 步骤 2: 转换为灰度图像
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    # 步骤 3: 二值化
    _, thresh = cv2.threshold(gray, 8, 255, cv2.THRESH_BINARY)
    # 步骤 4: 轮廓提取
    contours, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    features = []
    if len(contours) > 0:
        # 获取最大长度轮廓列表值,去除干扰点轮廓
        max_length_contour = max(contours, key=lambda x: len(x))
        # print(f'max_length_contour :{max_length_contour}')
        M = cv2.moments(max_length_contour)
        M = cv2.HuMoments(M)  # 计算轮廓的HU矩
        # print(f'轮廓的HU矩 :{M}')
        rect = cv2.minAreaRect(max_length_contour)
        box = cv2.boxPoints(rect)
        box = np.int0(box)
        (x, y), radius = cv2.minEnclosingCircle(max_length_contour)
        center = (int(x), int(y))
        # print(f'中心点 :{center}')
        radius = int(radius)
        # print(f'半径 :{radius}')
        w = min(rect[1][0], rect[1][1])  # 宽度
        h = max(rect[1][0], rect[1][1])  # 长度
        wh = w / h  # 宽长比例
        # print(f'宽长比例 :{wh}')
        s = cv2.contourArea(max_length_contour)  # 面积
        # print(f'面积 :{s}')
        l = cv2.arcLength(max_length_contour, True)  # 周长
        # print(f'周长 :{l}')
        radius_area = radius / s  # 半径面积比
        # print(f'半径面积比 :{radius_area}')
        radius_arc = radius / l  # 半径周长比
        # print(f'半径周长比 :{radius_arc}')
        l_wh = l / (w * h)  # 周长长宽比
        # print(f'周长长宽比 :{l_wh}')
        ls = l / s  # 周长面积比
        # print(f'周长面积比 :{ls}')
        roundness = (4 * np.pi * s) / (l * l)  # 圆形度
        # print(f'圆形度 :{roundness}')
        r = s / (w * h)  # 矩形度
        # print(f'矩形度 :{r}')
        # 根据不同类型图片数据,最后选择几种组合的特征值作为提升准确率
        features_name = ['周长长宽比', '周长面积比', '宽长比例', '矩形度', '圆形度']
        features = [l_wh, ls, wh, r, roundness]
        # 使用列表推导式和round函数格式化列表数据,保留4位小数
        features = [round(num, 4) for num in features]
    else:
        exit(0)
    return features
2.3  支持向量机(SVM)模型训练

根据训练数据集使用支持向量机(SVM)作为分类器,训练SVM模型。

(1)核函数选择:

根据数据特点选择合适的核函数,如线性核、多项式核、径向基函数(RBF)核等。

线性核函数(Linear Kernel):

    表达式:K(x,z) = x ∙ z,即普通的内积。

    使用场景:当数据是线性可分时,或者你想使用线性模型时。

    备注:LinearSVC 和 LinearSVR 只能使用线性核函数。

   

多项式核函数(Polynomial Kernel):   

    表达式:K(x,z) = (γx∙z + r)^d,其中γ, r, d都需要自己调参定义。

    使用场景:当数据有一定程度的非线性,并且你想通过增加多项式的阶数来捕捉更多的非线性关系时。

   

径向基函数核(Radial Basis Function Kernel,RBF),也称为高斯核函数(Gaussian Kernel):   

    表达式:K(x,z) = exp(−γ||x−z||^2),其中γ大于0,需要自己调参定义。

    使用场景:对于大多数非线性问题,默认的高斯核函数通常都有比较好的效果。

    备注:这是SVC的默认核函数。

(2)惩罚参数C优化:

SVM算法主要用于二分类问题,但也可以通过多次训练和组合来解决多分类问题。在处理线性不可分的数据时,SVM允许一些样本在超平面的错误一侧,即引入软间隔的概念。这可以通过引入惩罚参数来平衡间隔的大小和分类错误的容忍度。

惩罚参数C : 浮点数, 默认值为1.0

正则化参数。正则化的强度与C成反比。必须严格为正。惩罚项是平方的次l2惩罚。

from sklearn import svm
# 选择最优参数
clf = svm.SVC(C=0.5, kernel='poly')
clf.fit(train_features, train_labels)
print("使用支持向量机(SVM)作为分类器,训练SVM模型")
2.4  评估模型

评估一个训练好的模型在测试数据集上的性能,计算预测结果标签列表和真实结果标签列表的准确率,是一个通用的评估模型性能指标。

# 预测测试集
y_pred = clf.predict(test_features)
print('预测测试集标签:', y_pred)
# 计算准确率
accuracy = accuracy_score(test_labels, y_pred)
print('计算准确率:', accuracy)
2.5  模型参数调优

通过不断的优化特征值和SVM模型参数调优,最终选择准确率最高的模型作为结果。

# 获取特征值列表的所有可能子集列表
def get_all_child_list(train_features_np, test_features_np):
    # 获取列数
    num_cols = train_features_np.shape[1]

    # 初始化一个空列表来存储所有子集
    all_subsets_train = []
    all_subsets_test = []

    # 遍历从1列到所有列的所有组合
    for r in range(1, num_cols + 1):
        # 生成所有r列的组合索引
        combinations_r_cols = list(itertools.combinations(range(num_cols), r))

        # 遍历每个组合索引并提取数据
        for cols in combinations_r_cols:
            # 使用NumPy索引从train_features_np中提取列
            subset_train = train_features_np[:, list(cols)].tolist()
            # 使用相同的索引从test_features_np中提取列
            subset_test = test_features_np[:, list(cols)].tolist()

            # 将子集添加到列表中
            all_subsets_train.append(subset_train)
            all_subsets_test.append(subset_test)

    # 打印test_features的子集数量(与train_features相同)
    print(f"all_subsets_train总共有 {len(all_subsets_train)} 个子集列表")
    print(f"test_features总共有 {len(all_subsets_test)} 个子集列表")
return all_subsets_train, all_subsets_test

# 遍历所有子集特征值列表,然后训练模型和预测
def all_subsets_svc(all_subsets_train, all_subsets_test, train_labels, test_labels):
    # 打印前几个子集作为示例
    for i, (subset_train_features, subset_test_features) in enumerate(
            zip(all_subsets_train, all_subsets_test)):  # 仅打印前5个作为示例
        print(f"子集 {i + 1}(train_features): {subset_train_features}")
        print(f"子集 {i + 1}(test_features): {subset_test_features}")

        # 使用支持向量机(SVM)作为分类器
        clf = svm.SVC(C=0.5, kernel='poly')
        clf.fit(subset_train_features, train_labels)
        print("使用支持向量机(SVM)作为分类器,训练SVM模型")
        # 预测测试集
        y_pred = clf.predict(subset_test_features)
        print('预测测试集标签:', y_pred)
        print(f"预测测试集数量:{y_pred.size}")
        # 计算准确率
        accuracy = accuracy_score(test_labels, y_pred)
        print('计算准确率:', accuracy)
        print("=========================================")

第3章 程序运行效果

3.1 程序运行结果:

(1) 特征值调优

经过测试对比:特征值列表选择最佳如下:

['周长长宽比', '周长面积比', '宽长比例', '矩形度', '圆形度']

(2) SVM模型参数调优

①核函数选择

经过测试对比:核函数选择kernel='poly'最佳。

kernel='linear', 计算准确率: 0.38202247191011235

kernel='rbf', 计算准确率: 0.6179775280898876

kernel='poly', 计算准确率: 0.6741573033707865

②惩罚参数C调整

经过测试对比:惩罚参数设置C=0.5最佳。

C=1.0, kernel='poly',计算准确率: 0.6741573033707865

C=1.5, kernel='poly',计算准确率: 0.651685393258427

C=0.5, kernel='poly',计算准确率: 0.6966292134831461

(3) 最终模型运行结果

最终模型调优后,计算准确率: 0.6966292134831461。

第4章 设计中遇到的重点及难点

4.1 设计中遇到的重点

在本次的SVM算法识别验证码图片的设计实现过程中,遇到很多难点,主要的难点如下:

(1)数据集的预处理,要保证数据分类统一。

主要的解决步骤分为以下几点:

①   验证码图片需要分割为单个字符图片,直接使用4位字符的验证码图片去训练模型效果很差,而且不好分类;

②   分割后的单个字符图片需要人工标签对应的真实值。

(2)特征值的选择。

数字验证码有位置、方向、周长、面积、矩形度、宽长比、球状性、圆形度、不变矩、偏心率等各种特征,如何选择最优特征值组合:

①   一开始人工选择几种特征值组合测试,发现类似矩形度、圆形度这类小数点特征值训练的模型,准确率更高,选择周长、面积等大于1的特征值训练的模型,准确率更低;

②   然后特地选择了全部由小数点的特征值列表,再计算出特征值列表的所有子集列表,测试出所有特征值子集列表训练模型的准确率,选出其中准确率最高的特征值列表。

(3)SVM模型的参数调整。

SVM模型参数调整有以下几点:

①   核函数选择:根据数据特点选择合适的核函数,如线性核、多项式核、径向基函数(RBF)核等,测试出准确率最高的核函数。

②   惩罚参数C优化:根据默认值1.0,逐步上下调整0.1,测试出准确率最高的核函数。

第5章 本次设计存在不足与改良方案

5.1 本次设计中存在的不足

在本次设计中主要有以下几个方面是不完善的。

(1)数据集分类上存在不足:

由于采集的验证码图片数量有限,最后分割后单个字符图片,数字类只有2-9,缺少0和1。

(2)验证码图片分割后图片需要人工标签真实值:

由于需要分割4位字符的验证码图片为单个字符图片方便CNN模型训练使用,编写了分割图片代码,但是需要人工给这些分割后的图片打标签,图片重新命名。

(3)特征值选择存在不足:

由于选择的特征值都是基于形状的特征:轮廓形状计算出的几种特征值,经过多次调优,准确率也只有69%,一般准确率至少要到达90%才算合格的模型。

5.2 本次设计的改良方案

(1)增加数据集样本量:

保证分割后单个字符图片两大类:数字字符有0-9中的10类和字母字符A-Z中的26类,完善这两种字符数据分类。

(2)验证码图片分割后图片自动打上标签真实值:

编写简易的OCR识别代码,将这些分割后的单个字符图片统一识别文字,自动修改图片名称,打上标签真实值,减少人工耗时。

(3)增加更多的特征值:

基于像素的特征:可以使用图像的原始像素值或像素的统计信息(如直方图)作为特征。

基于纹理的特征:利用局部二值模式(LBP)、灰度共生矩阵(GLCM)等方法提取字符的纹理特征。

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

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

相关文章

WMS仓储管理系统中条码打印管理

1. 条码打印管理概述 1.1WMS系统中条码的作用 在WMS系统中,条码作为一种自动识别技术,对于提高仓库管理效率和准确性起着至关重要的作用。 - 物料追踪:通过为每个物料分配唯一的条码,可以实现对物料从入库到出库的全程追踪。 …

第三天旅游线路预览——从禾木景区入口到景区换乘中心

第三天:从贾登峪到禾木风景区,晚上住宿贾登峪; 从禾木景区入口到景区换乘中心: 进入禾木景区后乘坐景区摆渡车至景区换乘中心,路程约60公里,耗时100分钟; 将上面的的行程安排进行动态展示&am…

终于搞懂TS中的泛型啦! | typescript 入门指南 04

大家好,我是王天~ 今天分享的是《ts入门指南》系列中第四篇,主要讲解ts中的泛型应用 泛型在ts中是比较重要的概念,我花挺长时间才搞明白,整理输出这篇文章,希望能帮助到大家 ~ 《ts入门指南》系列,点击下…

鸿蒙轻内核A核源码分析系列五 虚实映射(7)虚实映射Flag属性

往期知识点记录: 鸿蒙(HarmonyOS)应用层开发(北向)知识点汇总 轻内核A核源码分析系列一 数据结构-双向循环链表 轻内核A核源码分析系列二 数据结构-位图操作 轻内核A核源码分析系列三 物理内存(1&#xff0…

如果 Android 手机出现数据丢失,如何在Android上恢复丢失的数据

当您的 Android 手机发生数据丢失时,您可能需要检索丢失的文件。为了帮助您完成此过程,以下是执行 Android 数据恢复的一些有效方法: 如何在Android上检索数据 如果您的 Android 手机出现数据丢失,您可能需要检索丢失的文件。为了…

Python批量发邮件:如何批量发个性化邮件?

Python批量发邮件的实用技巧?如何利用Python发邮件? 无论是营销推广、客户关怀,还是内部通知,个性化邮件都能显著提升沟通效果。那么,Python批量发邮件如何实现个性化呢?本文将详细介绍如何使用Python批量…

ESP32 UDP 05

1.在上一文章基础上修改,文章网址 ESP32-Ethernet-04-CSDN博客 2.基本代码 /* Ethernet Basic ExampleThis example code is in the Public Domain (or CC0 licensed, at your option.)Unless required by applicable law or agreed to in writing, thissoftware…

再见Java 8,请掌握最新LTS

简介 在Java开发中,Java 8曾经是无可争议的主流,凭借其稳定性和广泛的社区支持,陪伴了无数开发者走过多年辉煌时刻。然而,随着时间的推移,技术不断革新,企业和开发者们逐渐把目光投向了更新的LTS&#xff0…

LLM时代的transformer参数量、计算量、激活值的分析

导读:本文可以看作是对分析transformer模型的参数量、计算量、中间激活、KV cache的详细说明 定性分析 GPU上都存了哪些东西 首先我们来从全局整体的角度看一看,在训练阶段GPU显存上都有哪些内容: Model States:模型训练过程中…

使用 nuxi upgrade 升级现有nuxt项目版本

title: 使用 nuxi upgrade 升级现有nuxt项目版本 date: 2024/9/10 updated: 2024/9/10 author: cmdragon excerpt: 摘要:本文介绍了如何使用nuxi upgrade命令升级Nuxt 3项目,包括打开终端、运行升级命令、使用选项、测试项目等步骤,以及升级前的注意事项,如备份代码、检…

shader 案例学习笔记之绘制圆

环境搭建:参考glsl vscode环境搭建 先上代码 #ifdef GL_ES precision mediump float; #endifuniform vec2 u_resolution;void main(){vec2 st gl_FragCoord.xy/u_resolution.xy;st - 0.5;st.x * u_resolution.x/u_resolution.y;float r length(st);float d ste…

【面试分享】面试题——网络题目_网络面试题

🤟 基于入门网络安全/黑客打造的:👉黑客&网络安全入门&进阶学习资源包 一、题目 1、网关、网桥、路由器、中继器作用、实现以及对应的osi层? 2、MAC地址是什么? 3、webSocket是什么? 4、常见的协议有哪些? 5、什么…

交换机vlan配置实现

交换机配置 1. 配置交换机速度 进入交换机相应端口。 speed数值: 单位为Mbits;可选10,100,auto duplex参数:参数可选full全双工,half半双工,auto自适应 配置交换机管理IP地址: 在全局模式下: interf…

Qt使用UDP进行单波通信

Qt使用UDP进行单波通信 我们一般学习完基础的一些编程之后就会开始接触网络编程,我们熟悉的网络编程一般会涉及到两个协议一个时TCP,一个是UDP。TCP一般是point to point,UDP一般有单播和广播两种方式,那么我们今天就来学习一下单…

ECRS软件作业分析:提升工厂生产效率的钥匙

在竞争日益激烈的现代工业环境中,如何提升生产效率、降低资源消耗、增加产品价值,成为了每一家制造企业必须面对的重要课题。作业分析,作为一种科学的管理工具,正逐步成为企业优化生产流程、提升竞争力的关键手段。本文旨在深入探…

Unity SRP 可编程渲染管线的基本用法

可编程渲染管线使用教程 SRP 可以处理Canvas为Screen Space - Overlay的渲染 安装插件 首先进入package manager,下载Core RP Lib组件 创建渲染管线 编写渲染管线逻辑脚本 新建脚本取名为MPipeLine,该脚本用于实现渲染管线的处理逻辑 using Unity…

Python计算机视觉 第7章-图像搜索

Python计算机视觉 第7章-图像搜索 7.1 基于内容的图像检索 在大型图像数据库上,CBIR(Content-Based Image Retrieval,基于内容的图像检索)技术用于检索在视觉上具相似性的图像。这样返回的图像可以是颜色相似、纹理相似、图像中…

优秀一点点

在职场中,想要获得晋升,重要的是比其他同事优秀一点点。这就好比百米短跑比赛,第一名比第二名可能之快了0.01秒,这个0.01秒,和跑一百米所花的10秒钟比起来,可能只有千分之一。也就是说,第一名比…

麦汁煮沸工艺

麦汁煮沸是啤酒酿造中至关重要的工艺环节之一,直接影响啤酒的风味。今天,天泰邀您一起深入探讨这一关键的酿造技术。 煮沸麦汁 在煮沸麦汁时,时间和温度控制至关重要。通常,麦汁煮沸持续 40 到 50 分钟,具体时间取决于…

OpenAI Embeddings API: How embeddings work?

题意:OpenAI 嵌入 API:嵌入是如何工作的? 问题背景: There are quite a few tutorials on embeddings in OpenAI. I cant understand how they work. 在OpenAI中有很多关于嵌入的教程,但我无法理解它们是如何工作的。…