当前位置: 首页 > article >正文

OpenVINO教程(五):实现YOLOv11+OpenVINO实时视频目标检测

目录

  • 实现讲解
  • 效果展示
  • 完整代码

本文作为上篇博客的延续,在之前实现了图片推理的基础上,进一步介绍如何进行视频推理。

实现讲解

首先,我们需要对之前的 predict_and_show_image 函数进行拆分,将图像显示与推理器(predictor)的初始化解耦。这样做的目的是在进行视频推理前,能够先完成推理器的初始化、模型配置的设置,以及模型与 OpenVINO 优化模型的绑定,从而确保推理过程能够充分利用 OpenVINO 提供的高性能推理引擎。

以下是修改后的代码示例:

def initialize_predictor(det_model: YOLO, compiled_model: ov.CompiledModel, conf=0.25, batch=1, save=False, mode="predict"):"""初始化 det_model 的 predictor,如果尚未初始化,并设置 OpenVINO 编译好的模型。参数:det_model: 模型对象,包含 predictor, model, overrides 等属性。compiled_model: OpenVINO 编译好的模型对象。conf: 置信度阈值,默认 0.25。batch: 批处理大小,默认 1。save: 是否保存结果,默认 False。mode: 推理模式,默认 "predict"。"""if det_model.predictor is None:config = {"conf": conf, "batch": batch, "save": save, "mode": mode}args = {**det_model.overrides, **config}det_model.predictor = det_model._smart_load("predictor")(overrides=args,_callbacks=det_model.callbacks)det_model.predictor.setup_model(model=det_model.model)det_model.predictor.model.ov_compiled_model = compiled_modeldef predict_and_show_image(det_model: YOLO, compiled_model: ov.CompiledModel):"""使用模型对图像进行目标检测,并通过 Tkinter GUI 显示检测结果"""results = det_model(IMAGE_PATH)result_img = Image.fromarray(results[0].plot()[:, :, ::-1])root = tk.Tk()root.title("YOLOv11 (OpenVINO INT8) Detection Result")tk_img = ImageTk.PhotoImage(result_img)label = tk.Label(root, image=tk_img)label.pack()root.mainloop()

接下来,我们需要实现一个函数,用于结合 YOLO 和 OpenVINO 实现对视频的实时目标检测。该函数支持从视频文件或摄像头读取图像帧,并在完成推理处理后,实时显示检测结果、推理耗时和帧率(FPS)。此外,检测结果还可以保存为带有边框标注和帧率信息的视频文件,同时支持将检测信息(如类别、时间戳等)记录为日志文件,便于后续分析。

以下是具体的实现代码:

def run_video_inference(det_model, source=0, flip=True, width=None,save_video=True, save_log=True,output_dir="results"):"""使用 OpenVINO 和 YOLO 模型对视频进行目标检测推理并可视化。参数:det_model:YOLO 推理模型,支持 __call__(image) 方式调用source:视频源,可以是文件路径或摄像头索引, 0 表示默认摄像头flip:是否镜像翻转视频(镜像)width:设置画面宽度(自动等比例缩放), None 表示保持原尺寸save_video: 是否保存检测后的视频(MP4)save_log: 是否记录检测日志output_dir: 输出文件目录"""cap = cv2.VideoCapture(source)if not cap.isOpened():print(f"无法打开视频源: {source}")returnPath(output_dir).mkdir(parents=True, exist_ok=True)# 视频保存设置(保存为 MP4)out_writer = Noneoutput_path = str(Path(output_dir) / "output_yolo.mp4")fourcc = cv2.VideoWriter_fourcc(*"mp4v")# 日志文件准备log_file = open(Path(output_dir) / "detection_log.txt", "w") if save_log else Nonecv2.namedWindow("YOLO OpenVINO Detection", cv2.WINDOW_GUI_NORMAL | cv2.WINDOW_AUTOSIZE)processing_times = collections.deque()try:while True:ret, frame = cap.read()if not ret:print("视频读取失败或结束。")break# 检测窗口是否关闭if cv2.getWindowProperty("YOLO OpenVINO Detection", cv2.WND_PROP_VISIBLE) < 1:print("窗口已关闭,退出推理。")break# 镜像翻转(常用于摄像头)if flip:frame = cv2.flip(frame, 1)# 等比例缩放画面到指定宽度if width:scale = width / max(frame.shape)frame = cv2.resize(frame, None, fx=scale, fy=scale, interpolation=cv2.INTER_AREA)input_image = np.array(frame)# 计时推理开始start_time = time.time()results = det_model(input_image, verbose=False)stop_time = time.time()# 保存日志if log_file:for result in results:for box in result.boxes:cls_id = int(box.cls)conf = float(box.conf)log_file.write(f"time: {stop_time:.3f}, class_id: {cls_id}, confidence: {conf:.2f}\n")# 绘制检测结果frame = results[0].plot()# 推理时间统计,用于计算平均推理时间和 FPSprocessing_times.append(stop_time - start_time)if len(processing_times) > 200:processing_times.popleft()avg_time = np.mean(processing_times) * 1000fps = 1000 / avg_time# 显示推理时间和 FPS_, f_width = frame.shape[:2]cv2.putText(frame,f"Inference: {avg_time:.1f}ms ({fps:.1f} FPS)",(20, 40),cv2.FONT_HERSHEY_COMPLEX,f_width / 1000,(0, 0, 255),1,cv2.LINE_AA)# 初始化 MP4 写入器if save_video and out_writer is None:height, width_out = frame.shape[:2]out_writer = cv2.VideoWriter(output_path, fourcc, 25.0, (width_out, height))if save_video and out_writer:out_writer.write(frame)cv2.imshow("YOLO OpenVINO Detection", frame)# ESC 键退出if cv2.waitKey(1) == 27:print("按下 ESC 键,退出。")breakexcept KeyboardInterrupt:print("用户中断。")except RuntimeError as e:print("运行错误:", e)finally:cap.release()cv2.destroyAllWindows()if out_writer:out_writer.release()if log_file:log_file.close()print(f"检测视频保存至: {output_path}")if save_log:print(f"检测日志保存至: {Path(output_dir) / 'detection_log.txt'}")

最后就是调用这个函数的部分了,下面是具体的示例代码:

    # 5. 初始化 predictorinitialize_predictor(det_model, compiled_int8_model)# 6. 执行视频推理run_video_inference(det_model=det_model,          # 模型对象source="./1.mp4",             # 视频路径或摄像头编号flip=False,                    # 是否镜像width=1280,                   # 画面宽度save_video=True,              # 是否保存 MP4 视频save_log=True,                # 是否保存检测日志output_dir="./results"        # 输出目录)

效果展示

video

完整代码

from pathlib import Path
from zipfile import ZipFile
from typing import Dictimport urllib.request
import tkinter as tk
from PIL import Image, ImageTkfrom ultralytics import YOLO
from ultralytics.utils import DEFAULT_CFG
from ultralytics.cfg import get_cfg
from ultralytics.data.converter import coco80_to_coco91_class
from ultralytics.data.utils import check_det_datasetimport openvino as ov
import nncf
import cv2
import numpy as np
import collections
import time# ----------------------------- #
# 全局配置和路径定义
# ----------------------------- #MODEL_VARIANTS = ["yolo11n", "yolo11s", "yolo11m", "yolo11l", "yolo11x"]
MODEL_NAME = MODEL_VARIANTS[0]  # 默认使用最轻量的 yolo11n 模型
PT_MODEL_PATH = f"{MODEL_NAME}.pt"
IR_MODEL_DIR = Path(f"{MODEL_NAME}_openvino_model")
IR_MODEL_PATH = IR_MODEL_DIR / f"{MODEL_NAME}.xml"
INT8_MODEL_PATH = Path(f"{MODEL_NAME}_openvino_int8_model/{MODEL_NAME}.xml")IMAGE_PATH = Path("./coco_bike.jpg")
OUT_DIR = Path("./")# COCO 数据集资源路径
DATA_URL = "http://images.cocodataset.org/zips/val2017.zip"
LABELS_URL = "https://github.com/ultralytics/yolov5/releases/download/v1.0/coco2017labels-segments.zip"
CFG_URL = "https://raw.githubusercontent.com/ultralytics/ultralytics/v8.1.0/ultralytics/cfg/datasets/coco.yaml"
DATA_PATH = OUT_DIR / "val2017.zip"
LABELS_PATH = OUT_DIR / "coco2017labels-segments.zip"
CFG_PATH = OUT_DIR / "coco.yaml"# ----------------------------- #
# 工具函数模块
# ----------------------------- #def download_file_if_needed(url: str, filename: str, dest_dir: Path) -> Path:"""下载文件(若文件已存在则跳过)"""dest_dir.mkdir(parents=True, exist_ok=True)file_path = dest_dir / filenameif not file_path.exists():print(f"Downloading: {filename}")urllib.request.urlretrieve(url, file_path)else:print(f"File already exists: {file_path}")return file_pathdef prepare_test_image():"""确保测试图片存在,如无则从官方地址下载"""if not IMAGE_PATH.exists():download_file_if_needed("https://storage.openvinotoolkit.org/repositories/openvino_notebooks/data/data/image/coco_bike.jpg",IMAGE_PATH.name, IMAGE_PATH.parent)def load_or_export_openvino_model() -> ov.CompiledModel:"""加载或导出 YOLOv11 OpenVINO IR 模型,并编译为 CPU 运行时模型"""model = YOLO(PT_MODEL_PATH).to("cpu")if not IR_MODEL_PATH.exists():model.export(format="openvino", dynamic=True, half=True)core = ov.Core()ir_model = core.read_model(IR_MODEL_PATH)return core.compile_model(ir_model, "CPU")def build_ultralytics_model() -> YOLO:"""创建 Ultralytics 的 YOLO 模型接口,用于调用预测器"""return YOLO(IR_MODEL_DIR, task="detect")def prepare_dataset() -> 'tuple[nncf.Dataset, object]':"""下载并解压 COCO 数据集,构造验证器和 NNCF 所需数据集格式"""if not (OUT_DIR / "coco/labels").exists():download_file_if_needed(DATA_URL, DATA_PATH.name, DATA_PATH.parent)download_file_if_needed(LABELS_URL, LABELS_PATH.name, LABELS_PATH.parent)download_file_if_needed(CFG_URL, CFG_PATH.name, CFG_PATH.parent)with ZipFile(LABELS_PATH, "r") as z:z.extractall(OUT_DIR)with ZipFile(DATA_PATH, "r") as z:z.extractall(OUT_DIR / "coco/images")args = get_cfg(cfg=DEFAULT_CFG)args.data = str(CFG_PATH)# 用 ultralytics 的 validator 构建 datasetdet_model = build_ultralytics_model();validator_cls = det_model.task_map[det_model.task]["validator"]validator = validator_cls(args=args)validator.data = check_det_dataset(args.data)validator.stride = 32dataloader = validator.get_dataloader(OUT_DIR / "coco", 1)validator.class_map = coco80_to_coco91_class()validator.names = YOLO(PT_MODEL_PATH).to("cpu").model.namesvalidator.nc = 80def transform_fn(data: Dict):return validator.preprocess(data)['img'].numpy()return nncf.Dataset(dataloader, transform_fn), validatordef quantize_model(original_model: ov.Model, quant_dataset: nncf.Dataset) -> ov.Model:"""使用 NNCF 对 OpenVINO 模型进行混合精度量化(混合 INT8/F32)"""ignored_scope = nncf.IgnoredScope(subgraphs=[nncf.Subgraph(inputs=[f"__module.model.{22 if 'v8' in MODEL_NAME else 23}/aten::cat/Concat",f"__module.model.{22 if 'v8' in MODEL_NAME else 23}/aten::cat/Concat_1",f"__module.model.{22 if 'v8' in MODEL_NAME else 23}/aten::cat/Concat_2"],outputs=[f"__module.model.{22 if 'v8' in MODEL_NAME else 23}/aten::cat/Concat_7"])])quant_model = nncf.quantize(original_model,quant_dataset,preset=nncf.QuantizationPreset.MIXED,ignored_scope=ignored_scope)ov.save_model(quant_model, str(INT8_MODEL_PATH))print(f"Quantized model saved to: {INT8_MODEL_PATH}")return quant_modeldef initialize_predictor(det_model: YOLO, compiled_model: ov.CompiledModel, conf=0.25, batch=1, save=False, mode="predict"):"""初始化 det_model 的 predictor,如果尚未初始化,并设置 OpenVINO 编译好的模型。参数:det_model: 模型对象,包含 predictor, model, overrides 等属性。compiled_model: OpenVINO 编译好的模型对象。conf: 置信度阈值,默认 0.25。batch: 批处理大小,默认 1。save: 是否保存结果,默认 False。mode: 推理模式,默认 "predict"。"""if det_model.predictor is None:config = {"conf": conf, "batch": batch, "save": save, "mode": mode}args = {**det_model.overrides, **config}det_model.predictor = det_model._smart_load("predictor")(overrides=args,_callbacks=det_model.callbacks)det_model.predictor.setup_model(model=det_model.model)det_model.predictor.model.ov_compiled_model = compiled_modeldef predict_and_show_image(det_model: YOLO, compiled_model: ov.CompiledModel):"""使用模型对图像进行目标检测,并通过 Tkinter GUI 显示检测结果"""results = det_model(IMAGE_PATH)result_img = Image.fromarray(results[0].plot()[:, :, ::-1])root = tk.Tk()root.title("YOLOv11 (OpenVINO INT8) Detection Result")tk_img = ImageTk.PhotoImage(result_img)label = tk.Label(root, image=tk_img)label.pack()root.mainloop()def run_video_inference(det_model, source=0, flip=True, width=None,save_video=True, save_log=True,output_dir="results"):"""使用 OpenVINO 和 YOLO 模型对视频进行目标检测推理并可视化。参数:det_model:YOLO 推理模型,支持 __call__(image) 方式调用source:视频源,可以是文件路径或摄像头索引, 0 表示默认摄像头flip:是否镜像翻转视频(镜像)width:设置画面宽度(自动等比例缩放), None 表示保持原尺寸save_video: 是否保存检测后的视频(MP4)save_log: 是否记录检测日志output_dir: 输出文件目录"""cap = cv2.VideoCapture(source)if not cap.isOpened():print(f"无法打开视频源: {source}")returnPath(output_dir).mkdir(parents=True, exist_ok=True)# 视频保存设置(保存为 MP4)out_writer = Noneoutput_path = str(Path(output_dir) / "output_yolo.mp4")fourcc = cv2.VideoWriter_fourcc(*"mp4v")# 日志文件准备log_file = open(Path(output_dir) / "detection_log.txt", "w") if save_log else Nonecv2.namedWindow("YOLO OpenVINO Detection", cv2.WINDOW_GUI_NORMAL | cv2.WINDOW_AUTOSIZE)processing_times = collections.deque()try:while True:ret, frame = cap.read()if not ret:print("视频读取失败或结束。")break# 检测窗口是否关闭if cv2.getWindowProperty("YOLO OpenVINO Detection", cv2.WND_PROP_VISIBLE) < 1:print("窗口已关闭,退出推理。")break# 镜像翻转(常用于摄像头)if flip:frame = cv2.flip(frame, 1)# 等比例缩放画面到指定宽度if width:scale = width / max(frame.shape)frame = cv2.resize(frame, None, fx=scale, fy=scale, interpolation=cv2.INTER_AREA)input_image = np.array(frame)# 计时推理开始start_time = time.time()results = det_model(input_image, verbose=False)stop_time = time.time()# 保存日志if log_file:for result in results:for box in result.boxes:cls_id = int(box.cls)conf = float(box.conf)log_file.write(f"time: {stop_time:.3f}, class_id: {cls_id}, confidence: {conf:.2f}\n")# 绘制检测结果frame = results[0].plot()# 推理时间统计,用于计算平均推理时间和 FPSprocessing_times.append(stop_time - start_time)if len(processing_times) > 200:processing_times.popleft()avg_time = np.mean(processing_times) * 1000fps = 1000 / avg_time# 显示推理时间和 FPS_, f_width = frame.shape[:2]cv2.putText(frame,f"Inference: {avg_time:.1f}ms ({fps:.1f} FPS)",(20, 40),cv2.FONT_HERSHEY_COMPLEX,f_width / 1000,(0, 0, 255),1,cv2.LINE_AA)# 初始化 MP4 写入器if save_video and out_writer is None:height, width_out = frame.shape[:2]out_writer = cv2.VideoWriter(output_path, fourcc, 25.0, (width_out, height))if save_video and out_writer:out_writer.write(frame)cv2.imshow("YOLO OpenVINO Detection", frame)# ESC 键退出if cv2.waitKey(1) == 27:print("按下 ESC 键,退出。")breakexcept KeyboardInterrupt:print("用户中断。")except RuntimeError as e:print("运行错误:", e)finally:cap.release()cv2.destroyAllWindows()if out_writer:out_writer.release()if log_file:log_file.close()print(f"检测视频保存至: {output_path}")if save_log:print(f"检测日志保存至: {Path(output_dir) / 'detection_log.txt'}")# ----------------------------- #
# 主执行流程
# ----------------------------- #
def main():# 1. 准备测试图像(如无则下载)prepare_test_image()# 2. 加载或导出 OpenVINO IR 模型,并编译运行(用于量化或预测)compiled_fp_model = load_or_export_openvino_model()# 3. 构造 Ultralytics YOLO 接口,用于推理/验证det_model = build_ultralytics_model()# 4. 若 INT8 模型已存在,则直接加载;否则进行量化生成core = ov.Core()if INT8_MODEL_PATH.exists():quantized_model = core.read_model(INT8_MODEL_PATH)compiled_int8_model = core.compile_model(quantized_model, "CPU")else:quant_dataset, _ = prepare_dataset()quantized_model = quantize_model(core.read_model(IR_MODEL_PATH), quant_dataset)compiled_int8_model = core.compile_model(quantized_model, "CPU")# 5. 初始化 predictorinitialize_predictor(det_model, compiled_int8_model)# 6. 执行视频推理run_video_inference(det_model=det_model,          # 模型对象source="./1.mp4",             # 视频路径或摄像头编号flip=False,                    # 是否镜像width=1280,                   # 画面宽度save_video=True,              # 是否保存 MP4 视频save_log=True,                # 是否保存检测日志output_dir="./results"        # 输出目录)if __name__ == "__main__":main()

相关文章:

OpenVINO教程(五):实现YOLOv11+OpenVINO实时视频目标检测

目录 实现讲解效果展示完整代码 本文作为上篇博客的延续&#xff0c;在之前实现了图片推理的基础上&#xff0c;进一步介绍如何进行视频推理。 实现讲解 首先&#xff0c;我们需要对之前的 predict_and_show_image 函数进行拆分&#xff0c;将图像显示与推理器&#xff08;pre…...

CentOS的安装以及网络配置

CentOS的下载 在学习docker之前&#xff0c;我们需要知道的就是docker是运行在Linux内核之上的&#xff0c;所以我们需要Linux环境的操作系统&#xff0c;当然了你也可以选择安装ubuntu等操作系统&#xff0c;如果你不想在本机安装的话还可以考虑买阿里或者华为的云服务器&…...

【初级】前端开发工程师面试100题(一)

本题库共计包含100题&#xff0c;考察html&#xff0c;css&#xff0c;js&#xff0c;以及react&#xff0c;vue&#xff0c;webpack等基础知识掌握情况。 HTML基础篇 说说你对HTML语义化的理解&#xff1f; 语义化就是用合适的标签表达合适的内容&#xff0c;比如<header&…...

eplan许可证与防火墙安全软件冲突

在使用EPLAN电气设计软件时&#xff0c;有时会遇到许可证与防火墙或安全软件之间的冲突。这种冲突可能导致许可证无法激活或软件无法正常运行&#xff0c;给用户带来诸多不便。本文将为您解析EPLAN许可证与防火墙/安全软件冲突的原因&#xff0c;并提供解决方案&#xff0c;帮助…...

「Java EE开发指南」用MyEclipse开发EJB 3无状态会话Bean(二)

本教程介绍在MyEclipse中开发EJB 3无状态会话bean&#xff0c;由于JPA实体和EJB 3实体非常相似&#xff0c;因此本教程不涉及EJB 3实体Bean的开发。在本教程中&#xff0c;您将学习如何&#xff1a; 创建EJB 3项目创建无状态会话bean部署并测试bean 在上文中&#xff08;点击…...

Stable Diffusion秋叶整合包V4独立版Python本地API连接指南

秋叶整合包V4独立版Python本地API连接指南 秋叶整合的Stable Diffusion V4独立版支持通过Python调用本地API实现自动化图像生成。以下是具体操作流程及注意事项&#xff1a; 一、启用API服务 启动器配置 • 在秋叶启动器的 高级选项 中添加以下参数&#xff1a; --api --liste…...

小程序 GET 接口两种传值方式

前言 一般 GET 接口只有两种URL 参数和路径参数 一&#xff1a;URL 参数&#xff08;推荐方式&#xff09; 你希望请求&#xff1a; https://serve.zimeinew.com/wx/products/info?id5124接口应该写成这样&#xff0c;用 req.query.id 取 ?id5124&#xff1a; app.get(&…...

深度学习在DOM解析中的应用:自动识别页面关键内容区块

摘要 本文介绍了如何在爬取东方财富吧&#xff08;https://www.eastmoney.com&#xff09;财经新闻时&#xff0c;利用深度学习模型对 DOM 树中的内容区块进行自动识别和过滤&#xff0c;并将新闻标题、时间、正文等关键信息分类存储。文章聚焦爬虫整体性能瓶颈&#xff0c;通…...

PyQt6实例_pyqtgraph多曲线显示工具_代码分享

目录 概述 效果 代码 返回结果对象 字符型横坐标 通用折线图工具 工具主界面 使用举例 概述 1 分析数据遇到需要一个股票多个指标对比或一个指标多个股票对比&#xff0c;涉及到同轴多条曲线的显示&#xff0c;所以开发了本工具。 2 多曲线显示部分可以当通用工具使…...

Linux网络编程 多线程Web服务器:HTTP协议与TCP并发实战

问题解答 TCP是如何防止SYN洪流攻击的&#xff1f; 方式有很多种&#xff0c;我仅举例部分&#xff1a; 1、调整内核参数 我们知道SYN洪流攻击的原理就是发送一系列无法完成三次握手的特殊信号&#xff0c;导致正常的能够完成三次握手的信号因为 连接队列空间不足&#xff…...

【Vulkan 入门系列】创建帧缓冲、命令池、命令缓存,和获取图片(六)

这一节主要介绍创建帧缓冲&#xff08;Framebuffer&#xff09;&#xff0c;创建命令池&#xff0c;创建命令缓存&#xff0c;和从文件加载 PNG 图像数据&#xff0c;解码为 RGBA 格式&#xff0c;并将像素数据暂存到 Vulkan 的 暂存缓冲区中。 一、创建帧缓冲 createFramebu…...

【Git】fork 和 branch 的区别

在 Git 中&#xff0c;“fork” 和 “branch” 是两个不同的概念&#xff0c;它们用于不同的场景并且服务于不同的目的。理解这两者的区别对于有效地使用 Git 进行版本控制非常重要。 1. Fork&#xff08;分叉&#xff09; 定义 Fork 是指在 GitHub、GitLab 等代码托管平台上…...

Qt 下载的地址集合

Qt 下载离线安装包 download.qt.io/archive/qt/5.14/5.14.2/ Qt 6 安装下载在线安装包 Index of /qt/official_releases/online_installers/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror...

java将pdf转换成word

1、jar包准备 在项目中新增lib目录&#xff0c;并将如下两个文件放入lib目录下 aspose-words-15.8.0-jdk16.jar aspose-pdf-22.9.jar 2、pom.xml配置 <dependency><groupId>com.aspose</groupId><artifactId>aspose-pdf</artifactId><versi…...

ubuntu下gcc/g++安装及不同版本切换

1. 查看当前gcc版本 $ gcc --version# 查看当前系统中已安装版本 $ ls /usr/bin/gcc*2. 安装新版本gcc $ sudo apt-get update# 这里以版本12为依据&#xff08;也可以通过源码方式安装&#xff0c;请自行Google&#xff01;&#xff09; $ sudo apt-get install -y gcc-12 g…...

缓存与内存;缺页中断;缓存映射:组相联

文章目录 内存&#xff08;RAM&#xff09;与缓存&#xff08;Cache&#xff09;Memory Management Unit缺页中断 多级缓存缓存替换策略缓存的映射方式 内存&#xff08;RAM&#xff09;与缓存&#xff08;Cache&#xff09; 缓存&#xff1a; CPU 内部或非常靠近的高速存储&a…...

FPGA入门学习Day1——设计一个DDS信号发生器

目录 一、DDS简介 &#xff08;一&#xff09;基本原理 &#xff08;二&#xff09;主要优势 &#xff08;三&#xff09;与传统技术的对比 二、FPGA存储器 &#xff08;一&#xff09;ROM波形存储器 &#xff08;二&#xff09;RAM随机存取存储器 &#xff08;三&…...

微信小程序拖拽排序有效果图

效果图 .wxml <view class"container" style"--w:{{w}}px;" wx:if"{{location.length}}"><view class"container-item" wx:for"{{list}}" wx:key"index" data-index"{{index}}"style"--…...

elasticsearch 查询检索

一、查询方式列举 1、多维度查询 关键词&#xff1a;bool must match {"query": {"bool": {"must": [{"match": {"server_name": "www.test.com"}},{"range": { //时间查询"createTime": …...

WT2000T专业录音芯片:破解普通录音设备信息留存、合规安全与远程协作三大难题

在快节奏的现代商业环境中&#xff0c;会议是企业决策、创意碰撞和战略部署的核心场景。然而&#xff0c;传统会议记录方式常面临效率低、信息遗漏、回溯困难等痛点。如何确保会议内容被精准记录并高效利用&#xff1f;会议室专用录音芯片应运而生&#xff0c;以智能化、高保真…...

【Python 学习笔记】 pip指令使用

系列文章目录 pip指令使用 文章目录 系列文章目录前言安装配置使用pip 管理Python包修改pip下载源 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 当前文章记录的是我在学习过程的一些笔记和思考&#xff0c;可能存在有误解的地方&#xff0c;仅供大家…...

与Ubuntu相关命令

windows将文件传输到Ubuntu 传输文件夹或文件 scp -r 本地文件夹或文件 ubuntu用户名IP地址:要传输到的文件夹路径 例如&#xff1a; scp -r .\04.py gao192.168.248.129:/home/gao 如果传输文件也可以去掉-r 安装软件 sudo apt-get update 更新软件包列表 sudo apt insta…...

C# 文件读取

文件读取是指使用 C# 程序从计算机文件系统中获取文件内容的过程。将存储在磁盘上的文件内容加载到内存中&#xff0c;供程序处理。主要类型有&#xff1a;文本文件读取&#xff08;如 .txt, .csv, .json, .xml&#xff09;&#xff1b;二进制文件读取&#xff08;如 .jpg, .pn…...

leetcode125.验证回文串

class Solution {public boolean isPalindrome(String s) {s s.replaceAll("[^a-zA-Z0-9]", "").toLowerCase();for(int i0,js.length()-1;i<j;i,j--){if(s.charAt(i)!s.charAt(j))return false;}return true;} }...

【Android面试八股文】Android系统架构【一】

Android系统架构图 1.1 安卓系统启动 1.设备加电后执行第一段代码&#xff1a;Bootloader 系统引导分三种模式&#xff1a;fastboot&#xff0c;recovery&#xff0c;normal&#xff1a; fastboot模式&#xff1a;用于工厂模式的刷机。在关机状态下&#xff0c;按返回开机 键进…...

NLP高频面试题(五十二)——BERT 变体详解

在现代自然语言处理领域,BERT 系列模型不断演进,衍生出多种变体,它们通过改进预训练任务、模型结构和训练策略,在不同应用场景下取得了更优表现。本文首先概览主要 BERT 变体(如 ALBERT、RoBERTa、ELECTRA、SpanBERT、Transformer-XL 等),随后针对以下几个关键问题逐一展…...

【数据可视化-21】水质安全数据可视化:探索化学物质与水质安全的关联

&#x1f9d1; 博主简介&#xff1a;曾任某智慧城市类企业算法总监&#xff0c;目前在美国市场的物流公司从事高级算法工程师一职&#xff0c;深耕人工智能领域&#xff0c;精通python数据挖掘、可视化、机器学习等&#xff0c;发表过AI相关的专利并多次在AI类比赛中获奖。CSDN…...

CSS 选择器介绍

CSS 选择器介绍 1. 基本概念 CSS&#xff08;层叠样式表&#xff09;是一种用于描述 HTML 或 XML 文档外观的语言。通过 CSS&#xff0c;可以控制网页中元素的布局、颜色、字体等视觉效果。而 CSS 选择器则是用来指定哪些 HTML 元素应该应用这些样式的工具。 2. 基本选择器 …...

【prometheus+Grafana篇】从零开始:Linux 7.6 上二进制安装 Prometheus、Grafana 和 Node Exporter

&#x1f4ab;《博主主页》&#xff1a;奈斯DB-CSDN博客 &#x1f525;《擅长领域》&#xff1a;擅长阿里云AnalyticDB for MySQL(分布式数据仓库)、Oracle、MySQL、Linux、prometheus监控&#xff1b;并对SQLserver、NoSQL(MongoDB)有了解 &#x1f496;如果觉得文章对你有所帮…...

STM32(M4)入门:GPIO与位带操作(价值 3w + 的嵌入式开发指南)

一&#xff1a;GPIO 1.1 了解时钟树&#xff08;必懂的硬件基础&#xff09; 在 STM32 开发中&#xff0c;时钟系统是一切外设工作的 “心脏”。理解时钟树的工作原理&#xff0c;是正确配置 GPIO、UART 等外设的核心前提。 1.1.1 为什么必须开启外设时钟&#xff1f; 1. 计…...