基于PP-OCRv3的车牌检测和识别

news2024/11/25 13:02:14

本项目基于百度飞桨AI Studio平台进行实现,百度出品的深度学习平台飞桨(PaddlePaddle)是主流深度学习框架中一款完全国产化的产品,与Google TensorFlow、Facebook Pytorch齐名。2016 年飞桨正式开源,是国内首个全面开源开放、技术领先、功能完备的产业级深度学习平台。相比国内其他平台,飞桨是一个功能完整的深度学习平台,也是唯一成熟稳定、具备大规模推广条件的深度学习平台。

文章目录

  • 背景介绍
  • 一、PaddleOCR介绍
      • 📑1.1 简介
      • 🌟1.2 特性
      • ⚡1.3 快速开始
  • 二、 数据集简介和预处理
      • 2.1 数据集简介
      • 2.2 数据集处理
  • 三、环境配置
  • 四、训练
      • 4.1 检测模型训练
        • 4.1.1 预训练模型直接预测
        • 4.1.2 CCPD车牌数据集fine-tune训练
        • 4.1.3 CCPD车牌数据集fine-tune+量化训练
      • 4.2 识别模型训练
        • 4.2.1 预训练模型直接预测
        • 4.2.2 CCPD车牌数据集fine-tune训练
        • 4.2.3 CCPD车牌数据集fine-tune+量化训练
  • 五、模型导出
      • 5.1 检测非量化模型的导出
      • 5.2 识别非量化模型的导出
  • 六、模型部署
  • 总结

平台主界面如下:
在这里插入图片描述

在飞桨平台上,我们在使用paddle深度学习框架的基础上,可以免费使用平台的服务器,具体如下:
在这里插入图片描述
接下来我们进入正文~

背景介绍

车牌识别技术是一种利用计算机视觉技术对车辆车牌进行自动检测、识别的技术。它可以通过摄像头实时捕获车辆车牌信息,并经过算法处理后得到车牌号码信息,实现对车辆的自动识别、管理和监控。车牌识别技术被广泛应用于城市交通管理、安防监控行业、停车场管理等领域,可以提高交通管理效率,降低人工劳动成本,保障公共安全。
随着自动驾驶技术的快速发展,车辆自主性越来越高,丰富的实时数据也为车牌识别技术的运用提供了更多可能性。未来,车牌识别技术将会更加智能化、精准化,成为城市交通管理、智慧安防等领域的重要组成部分。

本项目主要基于PaddleOCR套件中的PP-OCR进行车牌的检测与识别,PP-OCR是PaddleOCR自研的实用的超轻量OCR系统。在实现前沿算法的基础上,考虑精度与速度的平衡,进行模型瘦身和深度优化,使其尽可能满足产业落地需求。该系统包含文本检测和文本识别两个阶段,其中文本检测算法选用DB,文本识别算法选用CRNN,并在检测和识别模块之间添加文本方向分类器,以应对不同方向的文本识别。我们这次使用的模块为PP-OCRv3,在PP-OCRv2的基础上,针对检测模型和识别模型,进行了共计9个方面的升级,进一步提升了模型效果。

一、PaddleOCR介绍

📑1.1 简介

PaddleOCR是一套丰富、领先、且实用的OCR工具库,旨在助力开发者训练出更好的模型,并应用落地。

部分应用场景如下:

🌟1.2 特性

PaddleOCR支持多种OCR相关前沿算法,在此基础上打造产业级特色模型PP-OCR和PP-Structure,并打通数据生产、模型训练、压缩、预测部署全流程。

⚡1.3 快速开始

  • 在线网站体验:超轻量PP-OCR mobile模型体验地址:https://www.paddlepaddle.org.cn/hub/scene/ocr
  • 移动端demo体验:安装包DEMO下载地址(基于EasyEdge和Paddle-Lite, 支持iOS和Android系统)
  • 一行命令快速使用:快速开始(中英文/多语言/文档分析)

更多关于PaddleOCR套件的详细信息请访问此地址

二、 数据集简介和预处理

2.1 数据集简介

所使用的数据集为 CCPD2020 新能源车牌数据集,该数据集为

该数据集分布如下:

数据集类型数量
训练集5769
验证集1001
测试集5006

数据集图片示例如下:

2.2 数据集处理

# 解压数据集
!tar -xvf /home/aistudio/data/data148343/CCPD2020.tar
import cv2
import os
import json
from tqdm import tqdm
import numpy as np

provinces = ["皖", "沪", "津", "渝", "冀", "晋", "蒙", "辽", "吉", "黑", "苏", "浙", "京", "闽", "赣", "鲁", "豫", "鄂", "湘", "粤", "桂", "琼", "川", "贵", "云", "藏", "陕", "甘", "青", "宁", "新", "警", "学", "O"]
alphabets = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'O']
ads = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'O']

def make_label(img_dir, save_gt_folder, phase):
    crop_img_save_dir = os.path.join(save_gt_folder, phase, 'crop_imgs')
    os.makedirs(crop_img_save_dir, exist_ok=True)

    f_det = open(os.path.join(save_gt_folder, phase, 'det.txt'), 'w', encoding='utf-8')
    f_rec = open(os.path.join(save_gt_folder, phase, 'rec.txt'), 'w', encoding='utf-8')

    i = 0
    for filename in tqdm(os.listdir(os.path.join(img_dir, phase))):
        str_list = filename.split('-')
        if len(str_list) < 5:
            continue
        coord_list = str_list[3].split('_')
        txt_list = str_list[4].split('_')
        boxes = []
        for coord in coord_list:
            boxes.append([int(x) for x in coord.split("&")])
        boxes = [boxes[2], boxes[3], boxes[0], boxes[1]]
        lp_number = provinces[int(txt_list[0])] + alphabets[int(txt_list[1])] + ''.join([ads[int(x)] for x in txt_list[2:]])

        # det
        det_info = [{'points':boxes, 'transcription':lp_number}]
        f_det.write('{}\t{}\n'.format(os.path.join(phase, filename), json.dumps(det_info, ensure_ascii=False)))

        # rec
        boxes = np.float32(boxes)
        img = cv2.imread(os.path.join(img_dir, phase, filename))
        # crop_img = img[int(boxes[:,1].min()):int(boxes[:,1].max()),int(boxes[:,0].min()):int(boxes[:,0].max())]
        crop_img = get_rotate_crop_image(img, boxes)
        crop_img_save_filename = '{}_{}.jpg'.format(i,'_'.join(txt_list))
        crop_img_save_path = os.path.join(crop_img_save_dir, crop_img_save_filename)
        cv2.imwrite(crop_img_save_path, crop_img)
        f_rec.write('{}/crop_imgs/{}\t{}\n'.format(phase, crop_img_save_filename, lp_number))
        i+=1
    f_det.close()
    f_rec.close()

def get_rotate_crop_image(img, points):
    '''
    img_height, img_width = img.shape[0:2]
    left = int(np.min(points[:, 0]))
    right = int(np.max(points[:, 0]))
    top = int(np.min(points[:, 1]))
    bottom = int(np.max(points[:, 1]))
    img_crop = img[top:bottom, left:right, :].copy()
    points[:, 0] = points[:, 0] - left
    points[:, 1] = points[:, 1] - top
    '''
    assert len(points) == 4, "shape of points must be 4*2"
    img_crop_width = int(
        max(
            np.linalg.norm(points[0] - points[1]),
            np.linalg.norm(points[2] - points[3])))
    img_crop_height = int(
        max(
            np.linalg.norm(points[0] - points[3]),
            np.linalg.norm(points[1] - points[2])))
    pts_std = np.float32([[0, 0], [img_crop_width, 0],
                          [img_crop_width, img_crop_height],
                          [0, img_crop_height]])
    M = cv2.getPerspectiveTransform(points, pts_std)
    dst_img = cv2.warpPerspective(
        img,
        M, (img_crop_width, img_crop_height),
        borderMode=cv2.BORDER_REPLICATE,
        flags=cv2.INTER_CUBIC)
    dst_img_height, dst_img_width = dst_img.shape[0:2]
    if dst_img_height * 1.0 / dst_img_width >= 1.5:
        dst_img = np.rot90(dst_img)
    return dst_img

img_dir = '/home/aistudio/data/CCPD2020/ccpd_green'
save_gt_folder = '/home/aistudio/data/CCPD2020/PPOCR'
# phase = 'train' # change to val and test to make val dataset and test dataset
for phase in ['train','val','test']:
    make_label(img_dir, save_gt_folder, phase)

以上是官网对该数据集的处理,本项目由于数据集已经处理好了,所以不再进行处理,这里仅分享。
数据集格式如下:

|- CCPD2020
    |-ccpd_green
        |-small
               |-img1.jpg
               |-img2.jpg
               |-...
        |-test
               |-img1.jpg
               |-img2.jpg
               |-...
        |-train
               |-img1.jpg
               |-img2.jpg
               |-...
        |-val
               |-img1.jpg
               |-img2.jpg
               |-...
    |-PPOCR
        |-test
            |-crop_imgs
            |-det.txt
            |-rec.txt
        |-train
            |-crop_imgs
            |-det.txt
            |-rec.txt
        |-val
            |-crop_imgs
            |-det.txt
            |-rec.txt

三、环境配置

在左边的套件里面下载PaddleOCR套件。

# 安装相关依赖
!pip install -r /home/aistudio/requirements.txt

四、训练

4.1 检测模型训练

4.1.1 预训练模型直接预测

# 下载预训练模型
import os
!mkdir models
os.chdir('/home/aistudio/models')
!wget https://paddleocr.bj.bcebos.com/PP-OCRv3/chinese/ch_PP-OCRv3_det_distill_train.tar
!tar -xf ch_PP-OCRv3_det_distill_train.tar
os.chdir('/home/aistudio/PaddleOCR-2.6.0')
!python tools/eval.py -c /home/aistudio/ch_PP-OCRv3_det_student.yml -o \
    Global.pretrained_model=/home/aistudio/models/ch_PP-OCRv3_det_distill_train/student.pdparams \
    Eval.dataset.data_dir=/home/aistudio/CCPD2020/ccpd_green \
    Eval.dataset.label_file_list=[/home/aistudio/CCPD2020/PPOCR/test/det.txt]


通过上述评估结果我们可以发现,直接使用预训练检测模型的hmean为0.76。

hmean是一个综合指标,从下面的表达式可以看出其值介于精度和回调之间,其表达式为:
h m e a n = 2 × p r e c i s i o n × r e c a l l p r e c i s i o n + r e c a l l hmean=\frac{2\times precision\times recall}{precision+recall} hmean=precision+recall2×precision×recall

4.1.2 CCPD车牌数据集fine-tune训练

# 训练
!python tools/train.py -c /home/aistudio/ch_PP-OCRv3_det_student.yml -o \
    Global.pretrained_model=/home/aistudio/models/ch_PP-OCRv3_det_distill_train/student.pdparams \
    Global.save_model_dir=/home/aistudio/output/CCPD/det \
    Global.eval_batch_step="[0, 772]" \
    Optimizer.lr.name=Const \
    Optimizer.lr.learning_rate=0.0005 \
    Optimizer.lr.warmup_epoch=0 \
    Train.dataset.data_dir=//home/aistudio/CCPD2020/ccpd_green \
    Train.dataset.label_file_list=[/home/aistudio/CCPD2020/PPOCR/train/det.txt] \
    Eval.dataset.data_dir=/home/aistudio/CCPD2020/ccpd_green \
    Eval.dataset.label_file_list=[/home/aistudio/CCPD2020/PPOCR/test/det.txt]
!python tools/eval.py -c /home/aistudio/ch_PP-OCRv3_det_student.yml -o \
    Global.pretrained_model=/home/aistudio/output/CCPD/det/best_accuracy.pdparams \
    Eval.dataset.data_dir=/home/aistudio/CCPD2020/ccpd_green \
    Eval.dataset.label_file_list=[/home/aistudio/CCPD2020/PPOCR/test/det.txt]


我训练了100轮左右,发现训练46轮后效果最好,这时候hmean达到了99.2%。

使用预训练模型和CCPD车牌数据集fine-tune,指标分别如下:

方案hmeans
PP-OCRv3中英文超轻量检测预训练模型直接预测76.12%
PP-OCRv3中英文超轻量检测预训练模型 fine-tune99.00%

4.1.3 CCPD车牌数据集fine-tune+量化训练

!python3.7 deploy/slim/quantization/quant.py -c /home/aistudio/ch_PP-OCRv3_det_student.yml -o \
    Global.pretrained_model=/home/aistudio/output/CCPD/det/best_accuracy.pdparams \
    Global.save_model_dir=/home/aistudio/output/CCPD/det_quant \
    Global.eval_batch_step="[0, 772]" \
    Optimizer.lr.name=Const \
    Optimizer.lr.learning_rate=0.0005 \
    Optimizer.lr.warmup_epoch=0 \
    Train.dataset.data_dir=/home/aistudio/CCPD2020/ccpd_green \
    Train.dataset.label_file_list=[/home/aistudio/CCPD2020/PPOCR/train/det.txt] \
    Eval.dataset.data_dir=/home/aistudio/CCPD2020/ccpd_green \
    Eval.dataset.label_file_list=[/home/aistudio/CCPD2020/PPOCR/test/det.txt]

4.2 识别模型训练

4.2.1 预训练模型直接预测

import os
os.chdir('/home/aistudio/models')
!wget https://paddleocr.bj.bcebos.com/PP-OCRv3/chinese/ch_PP-OCRv3_rec_train.tar
!tar -xf ch_PP-OCRv3_rec_train.tar

PaddleOCR提供的PP-OCRv3识别模型采用蒸馏训练策略,因此提供的预训练模型中会包含Teacher和Student模型的参数,详细信息可参考knowledge_distillation.md。 因此,模型下载完成后需要使用如下代码提取Student模型的参数:

import paddle
# 加载预训练模型
all_params = paddle.load("../models/ch_PP-OCRv3_rec_train/best_accuracy.pdparams")
# 查看权重参数的keys
print(all_params.keys())
# 学生模型的权重提取
s_params = {key[len("Student."):]: all_params[key] for key in all_params if "Student." in key}
# 查看学生模型权重参数的keys
print(s_params.keys())
# 保存
paddle.save(s_params, "../models/ch_PP-OCRv3_rec_train/student.pdparams")
import os
os.chdir('/home/aistudio/PaddleOCR-2.6.0')
!python tools/eval.py -c configs/rec/PP-OCRv3/ch_PP-OCRv3_rec.yml -o \
    Global.pretrained_model=/home/aistudio/models/ch_PP-OCRv3_rec_train/student.pdparams \
    Eval.dataset.data_dir=/home/aistudio/CCPD2020/PPOCR \
    Eval.dataset.label_file_list=[/home/aistudio/CCPD2020/PPOCR/test/rec.txt]


如果出现了acc精度为0的情况,那么我们需要到/home/aistudio/PaddleOCR-2.6.0/ppocr/postprocess/rec_postprocess.py文件里,在第98行加入text = text.replace('·','')代码,这是因为我们识别出的结果里面将车牌号字母和数字之间的点·也给识别出来了,所以要将其替换掉进行评估。

具体操作如下:

我们可以先识别一张图片,比如:

import os
os.chdir('/home/aistudio/PaddleOCR-2.6.0')
!python tools/infer_rec.py -c /home/aistudio/ch_PP-OCRv3_rec.yml -o \
    Global.pretrained_model=/home/aistudio/models/ch_PP-OCRv3_rec_train/student.pdparams \
    Global.infer_img=/home/aistudio/car1.jpg

4.2.2 CCPD车牌数据集fine-tune训练

import os
os.chdir('/home/aistudio/PaddleOCR-2.6.0')
!python tools/train.py -c /home/aistudio/ch_PP-OCRv3_rec.yml -o \
    Global.pretrained_model=/home/aistudio/models/ch_PP-OCRv3_rec_train/student.pdparams \
    Global.save_model_dir=/home/aistudio/output/CCPD/rec/ \
    Global.eval_batch_step="[0, 90]" \
    Optimizer.lr.name=Const \
    Optimizer.lr.learning_rate=0.0005 \
    Optimizer.lr.warmup_epoch=0 \
    Train.dataset.data_dir=/home/aistudio/CCPD2020/PPOCR \
    Train.dataset.label_file_list=[/home/aistudio/CCPD2020/PPOCR/train/rec.txt] \
    Eval.dataset.data_dir=/home/aistudio/CCPD2020/PPOCR \
    Eval.dataset.label_file_list=[/home/aistudio/CCPD2020/PPOCR/test/rec.txt]
!python tools/eval.py -c /home/aistudio/ch_PP-OCRv3_rec.yml -o \
    Global.pretrained_model=/home/aistudio/output/CCPD/rec/best_accuracy.pdparams \
    Eval.dataset.data_dir=/home/aistudio/CCPD2020/PPOCR \
    Eval.dataset.label_file_list=[/home/aistudio/CCPD2020/PPOCR/test/rec.txt]

4.2.3 CCPD车牌数据集fine-tune+量化训练

!python3.7 deploy/slim/quantization/quant.py -c /home/aistudio/ch_PP-OCRv3_rec.yml -o \
    Global.pretrained_model=/home/aistudio/output/CCPD/rec/best_accuracy.pdparams \
    Global.save_model_dir=/home/aistudio/output/CCPD/rec_quant/ \
    Global.eval_batch_step="[0, 90]" \
    Optimizer.lr.name=Const \
    Optimizer.lr.learning_rate=0.0005 \
    Optimizer.lr.warmup_epoch=0 \
    Train.dataset.data_dir=/home/aistudio/CCPD2020/PPOCR \
    Train.dataset.label_file_list=[/home/aistudio/CCPD2020/PPOCR/train/rec.txt] \
    Eval.dataset.data_dir=/home/aistudio/CCPD2020/PPOCR \
    Eval.dataset.label_file_list=[/home/aistudio/CCPD2020/PPOCR/test/rec.txt]

五、模型导出

5.1 检测非量化模型的导出

!python tools/export_model.py -c /home/aistudio/ch_PP-OCRv3_det_student.yml -o \
    Global.pretrained_model=/home/aistudio/output/CCPD/det/best_accuracy.pdparams \
    Global.save_inference_dir=/home/aistudio/output/det/infer

在这里插入图片描述

5.2 识别非量化模型的导出

!python tools/export_model.py -c /home/aistudio/ch_PP-OCRv3_rec.yml -o \
    Global.pretrained_model=/home/aistudio/output/CCPD/rec/best_accuracy.pdparams \
    Global.save_inference_dir=/home/aistudio/output/rec/infer

在这里插入图片描述

六、模型部署

!python tools/infer/predict_system.py \
    --det_model_dir=/home/aistudio/output/det/infer/ \
    --rec_model_dir=/home/aistudio/output/rec/infer/ \
    --image_dir="/home/aistudio/CCPD2020/ccpd_green/test/04421336206896552-88_265-177&509_550&618-546&600_187&618_177&527_550&509-0_0_3_32_31_32_31_32-87-37.jpg" \
    --rec_image_shape=3,48,320

在这里插入图片描述
推理结果保存在/home/aistudio/PaddleOCR-2.6.0/inference_results路径下。

推理结果如下:

总结

  • 本次车牌识别项目旨在设计和实现一个高效、准确的车牌检测与识别系统,能够在各种复杂的场景下自动完成车牌的识别和记录,并提高城市交通管理的效率。PadlleOCR套件里的PP-OCR在精度和速度上都已经达到了很不错的效果。
  • 在该项目中,我们采用了PaddleOCR套件提供的车牌识别模型并进行了相关的优化和调整。同时,我们还采用了大量的车牌图像数据进行训练和测试,以确保系统的准确性和稳定性。
  • 通过对算法的优化和实验验证,我们成功地实现了车牌号识别的自动化,取得了较高的识别率和较低的误识别率。接下来,我们将设计了一个友好的用户界面,可以方便地进行数据管理和查询,以提升车牌管理的智能化和便捷性。
  • 总体而言,基于PaddleOCR套件的车牌号识别项目在技术和实用性方面取得了很好的成果,为城市交通管理和智慧安防等领域的相关应用提供了可靠的技术支持。未来,我们将继续优化和升级该系统,以满足不断变化的实际需求和挑战。

本项目基于百度AI Studio平台完成,如需要可以到基于PP-OCRv3的车牌检测和识别运行项目导出训练模型权重,并部署到本地使用。

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

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

相关文章

【SpringMVC】| 域对象共享数据

目录 前期准备 域对象共享数据 一&#xff1a;向request域共享数据&#xff08;五种方法&#xff09; 1. 使用ServletAPI向request域对象共享数据&#xff08;了解&#xff09; 2. 使用ModelAndView向request域对象共享数据 3. 使用Model向request域对象共享数据 4. 使用…

chatgpt赋能python:Python代码怎么找?这里介绍几种方法

Python代码怎么找&#xff1f;这里介绍几种方法 在编写Python程序的时候&#xff0c;经常会遇到需要查找已有代码的情况。那么&#xff0c;在这里&#xff0c;我们将介绍几种查找Python代码的方法&#xff0c;希望能对大家有所帮助。 使用文本编辑器的查找功能 在大多数文本…

3.场(field)

目录 1.复习 2.引言 3.数量场 1.概念 2.例题 4.矢量场 1.概念 2.例题 5.坐标变换和坐标单位矢 1.坐标变换 2.单位矢 1.复习 2.引言 如果说矢量分析研究的是矢量的时间变化&#xff0c;那么场就是它的空间变化. 场是客观存在的&#xff0c;杨振宁先生在总结20世…

Spring Boot 3.1中如何整合Spring Security和Keycloak

在今年2月14日的时候&#xff0c;Keycloak 团队宣布他们正在弃用大多数 Keycloak 适配器。其中包括Spring Security和Spring Boot的适配器&#xff0c;这意味着今后Keycloak团队将不再提供针对Spring Security和Spring Boot的集成方案。但是&#xff0c;如此强大的Keycloak&…

数据库|TiDB 数据库大版本升级-基于TiCDC异机升级

作者&#xff1a;高文峰 | 神州数码云基地TiDB团队成员 目录 一、前言 二、升级架构图 三、升级流程 1.下游TiDB集群部署过程 2. 上游TiCDC节点的扩容 3. 上游数据全备恢复到下游 4. TiCDC启用正向同步任务 5. 应用停服务&#xff0c;tidb 无业务会话连接 6. 确认数据…

2023年6月跟产品开发专家学NPDP产品经理认证课到这里

NPDP产品经理国际资格认证是国际公认的唯一的新产品开发专业认证&#xff0c;集理论、方法与实践为一体的全方位的知识体系&#xff0c;为公司组织层级进行规划、决策、执行提供良好的方法体系支撑。 我们针对互联网时代的个人、互联网企业、与传统企业推出一系列学习。 课程从…

小车跑迷宫,如何完成?

先看视频1&#xff1a; 先看视频2&#xff1a; 要制作一个能顺利走到迷宫终点&#xff0c;并能按最短路径回来的小车&#xff0c;重中之重就是寻找其最短路径的算法&#xff0c;迷宫情况复杂多变&#xff0c;多个路口交错纵横&#xff0c;想要完美的找出最短路径并不容易&#…

事件相关功能磁共振波谱技术(fMRS)

导读 质子磁共振波谱(MRS)是一种非侵入性脑成像技术&#xff0c;用于测量不同神经化学物质的浓度。“单体素”MRS数据通常在几分钟内采集&#xff0c;然后对单个瞬态进行平均&#xff0c;从而测量神经化学物质浓度。然而&#xff0c;这种方法对更快速的神经化学物质的时间动态…

chatgpt赋能python:Python人脸身份识别:提高安全性和效率的先进技术

Python人脸身份识别&#xff1a;提高安全性和效率的先进技术 随着科技的发展&#xff0c;人类对于安全性和效率的需求逐渐增加。而人脸身份识别技术正是一个能够满足这一需求的先进技术。在过去的几年中&#xff0c;这种技术已经逐渐发展成为一种普及的安全措施&#xff0c;这…

串口组件:ZylSerialPort.NET 1.83 Crack

ZylSerialPort.NET 1.83 .NET 组件 库 ZylSerialPort.NET 是一个基于线程、事件驱动、异步/同步串口的.NET 组件库。 使用 ZylSerialPort.NET 组件可以轻松地通过串行端口连接与外部设备进行通信&#xff0c;例如调制解调器、条形码阅读器、GSM 模块等。 您也可以将它与 USB、…

Volatile、Synchronized、ReentrantLock锁机制使用说明

一、Volatile底层原理 volatile是轻量级的同步机制&#xff0c;volatile保证变量对所有线程的可见性&#xff0c;不保证原子性。 当对volatile变量进行写操作的时候&#xff0c;JVM会向处理器发送一条LOCK前缀的指令&#xff0c;将该变量所在缓存行的数据写回系统内存。由于缓…

DJ4-7 请求分页存储管理方式

目录 4.7.1 请求分页中的硬件支持 1、页表机制 2、缺页中断机构 4.7.2 内存分配策略和分配算法 1、最小物理块数的确定 2、物理块的分配策略 3、物理块的分配算法 4.7.3 调页策略 1、系统应当在何时把一个页面装入内存&#xff1f; 2、从何处调入页面&#xff1f;…

机器学习常识 12: SVM

摘要: 支持向量机 (support vector machine, SVM) 有很多闪光点, 理论方面有 VC 维的支撑, 技术上有核函数将线性不可分变成线性可分, 实践上是小样本学习效果最好的算法. 1. 线性分类器 如图 1 所示, 基础的 SVM 仍然是一个线性二分类器, 这一点与 logistic 回归一致. 图 1.…

MATLAB 之 隐函数绘图、图形修饰处理、图像处理与动画制作和交互式绘图工具

这里写目录标题 一、隐函数绘图1. 隐函数二维绘图3. 隐函数三维绘图 二、图形修饰处理1. 视点处理2. 色彩处理2.1 颜色的向量表示2.2 色图2.3 三维曲面图形的着色 3. 图形的裁剪处理 三、图像处理与动画制作1. 图像处理1.1 图像的读/写1.2 图像的显示 2. 动画制作2.1 制作逐帧动…

chatgpt赋能python:Python交流App:提高Python社区交流效率

Python 交流 App: 提高 Python 社区交流效率 Python 是当今流行程度最高的编程语言之一&#xff0c;有着广泛的应用场景和庞大的社区。 作为 Python 工程师&#xff0c;经常有各种问题需要得到解决&#xff0c;同时也希望能与同行进行交流、分享和学习。这时&#xff0c;一款高…

Linux——Centos7进入单用户模式修改密码

本篇文章适用于经常忘记自己root用户密码的初学者&#xff01;&#xff01;&#xff01;&#xff0c;会进入单用户模式修改root密码即可。 系统启动进入到如下界面后输入字母“e”; 2.可以看到进入到如下界面&#xff1b; 3.一直下翻到图中圈起来的这部分&#xff1b; 4.在Lin…

excel 获取指定字符前后的字符串

目录 excel 获取指定字符前后的字符串 1.截取指定字符前的字符串 2.截取指定字符后的字符串 excel 获取指定字符前后的字符串 1.截取指定字符前的字符串 1.1LEFT FIND find:返回一个字符串在另一个字符串中出现的起始位置。 (区分大小写&#xff0c;且不允许使用通配符) …

综合指挥调度系统行业分类汇总

综合指挥调度系统是将语音、视频、GIS进行高度融合&#xff0c;构建“平战结合”的指挥调度模式&#xff0c;既满足平时的应急培训、日常通信、会议会商等要求&#xff0c;也能够应对战时的应急指挥、应急救援、应急决策等需求&#xff0c;达到统一指挥、联合行动的目的&#x…

ArcGIS中实现土地利用转移矩阵

土地利用转移矩阵&#xff0c;就是根据同一地区不同时相的土地覆盖现状的变化关系&#xff0c;求得一个二维矩阵。通过对得到的转移矩阵进行分析&#xff0c;能够得到&#xff12;个时相&#xff0c;不同的地类之间相互转化的情况&#xff0c;它描述了不同的土地利用的类型在不…

新华三的网络脉动:为AI泵血,向产业奔流

AI大模型作为最新的通用技术&#xff0c;今年以来&#xff0c;发展如火如荼。也有很多从业者和专家注意到&#xff0c;AI模型训练和应用过程中&#xff0c;需要优先考虑网络的升级与适配。 如果说数据中心、算力集群是AI的“心脏”&#xff0c;那么网络就犹如AI的“动脉”&…