YOLOv3实践教程:使用预训练模型进行目标检测
目录
- 简介
- 环境准备
- 获取预训练模型
- 图像目标检测
- 视频目标检测
- 模型性能优化
- 常见问题解答
- 进阶学习路径
简介
YOLOv3(You Only Look Once version 3)是一种高效的实时目标检测算法,由Joseph Redmon和Ali Farhadi于2018年提出。与传统的目标检测方法相比,YOLO将目标检测视为单一的回归问题,直接从完整图像预测边界框及其类别概率,使其成为速度和准确性之间平衡的优秀选择。
本教程适合以下人群:
- 对计算机视觉和深度学习感兴趣的初学者
- 想要快速实现目标检测功能的开发者
- 需要在项目中集成目标检测功能的学生或研究人员
环境准备
系统要求
- Python 3.6+
- CPU或GPU(推荐NVIDIA GPU以提高性能)
- 至少4GB内存(推荐8GB以上)
安装必要的库
首先,我们需要创建一个虚拟环境(可选但推荐):
bash
# 创建虚拟环境
python -m venv yolov3_env# 激活虚拟环境
# Windows:
yolov3_env\Scripts\activate
# Linux/Mac:
source yolov3_env/bin/activate
安装必要的库:
bash
# 安装基本库
pip install numpy opencv-python-headless matplotlib pillow# 使用CPU版PyTorch
pip install torch torchvision# 或使用GPU版PyTorch (根据你的CUDA版本选择适当的命令)
# 请访问 https://pytorch.org/get-started/locally/ 获取适用于你系统的安装命令
如果你想使用官方的darknet实现,你需要克隆并编译darknet库:
bash
git clone https://github.com/AlexeyAB/darknet.git
cd darknet# 编辑Makefile,设置GPU=1、CUDNN=1(如果有GPU)
# 在Windows上,使用Makefile.win文件# Linux/Mac编译:
make
或者,我们可以使用更简单的Python实现,如Ultralytics的YOLOv3:
bash
pip install ultralytics
获取预训练模型
YOLOv3提供了多种预训练模型,最常用的是在COCO数据集上训练的模型。
使用Ultralytics YOLOv3
bash
# 下载预训练权重
wget https://github.com/ultralytics/yolov3/releases/download/v9.0/yolov3.pt -O yolov3.pt
如果使用原始的darknet实现:
bash
# 下载配置文件和权重
wget https://raw.githubusercontent.com/AlexeyAB/darknet/master/cfg/yolov3.cfg
wget https://pjreddie.com/media/files/yolov3.weights
COCO数据集类别
YOLOv3预训练模型可以检测80种不同的物体,包括人、车辆、动物和日常物品。完整的类别列表如下:
python
COCO_CLASSES = ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat','traffic light', 'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat','dog', 'horse', 'sheep', 'cow', 'elephant', 'bear', 'zebra', 'giraffe', 'backpack','umbrella', 'handbag', 'tie', 'suitcase', 'frisbee', 'skis', 'snowboard', 'sports ball','kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard', 'tennis racket','bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple','sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair','couch', 'potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop', 'mouse','remote', 'keyboard', 'cell phone', 'microwave', 'oven', 'toaster', 'sink', 'refrigerator','book', 'clock', 'vase', 'scissors', 'teddy bear', 'hair drier', 'toothbrush'
]
图像目标检测
现在我们开始实际操作,使用YOLOv3模型检测图像中的目标。
方法1:使用Ultralytics YOLOv3(推荐新手使用)
创建一个Python脚本 detect_image.py
:
python
from ultralytics import YOLO
import cv2
import numpy as np
import timedef detect_objects(image_path, conf_threshold=0.25):# 加载模型model = YOLO('yolov3.pt')# 读取图像img = cv2.imread(image_path)if img is None:print(f"无法读取图像: {image_path}")return# 记录开始时间start_time = time.time()# 执行推理results = model(img)# 计算推理时间inference_time = time.time() - start_timeprint(f"推理时间: {inference_time:.2f}秒")# 获取检测结果result = results[0]# 在图像上绘制检测结果for box in result.boxes:x1, y1, x2, y2 = map(int, box.xyxy[0])conf = float(box.conf[0])cls_id = int(box.cls[0])if conf >= conf_threshold:label = f"{result.names[cls_id]} {conf:.2f}"cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2)cv2.putText(img, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)# 保存和显示结果output_path = "output_" + image_path.split("/")[-1]cv2.imwrite(output_path, img)print(f"已保存结果到: {output_path}")# 显示结果 (可选,如果在有图形界面的环境下)cv2.imshow("Detection Result", img)cv2.waitKey(0)cv2.destroyAllWindows()if __name__ == "__main__":# 替换为你自己的图像路径image_path = "test_image.jpg"detect_objects(image_path)
方法2:使用OpenCV的DNN模块
如果你想使用OpenCV的DNN模块直接加载darknet模型,可以使用以下代码:
python
import cv2
import numpy as np
import time
import argparsedef detect_objects_opencv(image_path, config_path, weights_path, conf_threshold=0.5, nms_threshold=0.4):# 加载类别名称with open('coco.names', 'rt') as f:classes = f.read().rstrip('\n').split('\n')# 设置随机颜色np.random.seed(42)colors = np.random.randint(0, 255, size=(len(classes), 3), dtype=np.uint8)# 加载网络net = cv2.dnn.readNetFromDarknet(config_path, weights_path)# 检查可用的计算后端backend = cv2.dnn.DNN_BACKEND_OPENCVtarget = cv2.dnn.DNN_TARGET_CPU# 如果有CUDA支持,可以启用GPUif cv2.cuda.getCudaEnabledDeviceCount() > 0:backend = cv2.dnn.DNN_BACKEND_CUDAtarget = cv2.dnn.DNN_TARGET_CUDAnet.setPreferableBackend(backend)net.setPreferableTarget(target)# 获取输出层名称layer_names = net.getLayerNames()output_layers = [layer_names[i - 1] for i in net.getUnconnectedOutLayers()]# 读取图像img = cv2.imread(image_path)if img is None:print(f"无法读取图像: {image_path}")returnheight, width = img.shape[:2]# 图像预处理: 创建blobblob = cv2.dnn.blobFromImage(img, 1/255.0, (416, 416), swapRB=True, crop=False)net.setInput(blob)# 记录开始时间start_time = time.time()# 前向传播,获取检测结果outputs = net.forward(output_layers)# 计算推理时间inference_time = time.time() - start_timeprint(f"推理时间: {inference_time:.2f}秒")# 处理检测结果class_ids = []confidences = []boxes = []for output in outputs:for detection in output:scores = detection[5:]class_id = np.argmax(scores)confidence = scores[class_id]if confidence > conf_threshold:# 目标位置center_x = int(detection[0] * width)center_y = int(detection[1] * height)w = int(detection[2] * width)h = int(detection[3] * height)# 计算左上角坐标x = int(center_x - w / 2)y = int(center_y - h / 2)boxes.append([x, y, w, h])confidences.append(float(confidence))class_ids.append(class_id)# 非最大抑制,移除重叠框indices = cv2.dnn.NMSBoxes(boxes, confidences, conf_threshold, nms_threshold)# 绘制检测结果for i in indices:i = i if isinstance(i, int) else i[0] # 处理不同OpenCV版本的兼容性box = boxes[i]x, y, w, h = boxlabel = f"{classes[class_ids[i]]}: {confidences[i]:.2f}"color = [int(c) for c in colors[class_ids[i]]]# 绘制边界框和标签cv2.rectangle(img, (x, y), (x + w, y + h), color, 2)cv2.putText(img, label, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)# 保存结果output_path = "output_" + image_path.split("/")[-1]cv2.imwrite(output_path, img)print(f"已保存结果到: {output_path}")# 显示结果 (可选)cv2.imshow("Detection Result", img)cv2.waitKey(0)cv2.destroyAllWindows()if __name__ == "__main__":parser = argparse.ArgumentParser(description='YOLOv3目标检测')parser.add_argument('--image', type=str, default='test_image.jpg', help='输入图像路径')parser.add_argument('--config', type=str, default='yolov3.cfg', help='模型配置文件路径')parser.add_argument('--weights', type=str, default='yolov3.weights', help='模型权重文件路径')parser.add_argument('--conf', type=float, default=0.5, help='置信度阈值')args = parser.parse_args()# 在运行前确保你有coco.names文件# 可以从这里下载: https://github.com/AlexeyAB/darknet/blob/master/data/coco.namesdetect_objects_opencv(args.image, args.config, args.weights, args.conf)
确保你在同一目录下有一个coco.names
文件,包含所有COCO类别:
bash
# 下载coco.names文件
wget https://raw.githubusercontent.com/AlexeyAB/darknet/master/data/coco.names
视频目标检测
现在让我们扩展到视频目标检测,这对于监控、行为分析等应用非常有用。
使用Ultralytics YOLOv3处理视频
创建一个脚本detect_video.py
:
python
from ultralytics import YOLO
import cv2
import time
import argparsedef detect_video(video_path, conf_threshold=0.25, output_path=None):# 加载模型model = YOLO('yolov3.pt')# 打开视频文件或摄像头if video_path.isdigit():cap = cv2.VideoCapture(int(video_path)) # 摄像头else:cap = cv2.VideoCapture(video_path) # 视频文件if not cap.isOpened():print(f"无法打开视频源: {video_path}")return# 获取视频参数width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))fps = cap.get(cv2.CAP_PROP_FPS)# 准备输出视频if output_path:fourcc = cv2.VideoWriter_fourcc(*'XVID')out = cv2.VideoWriter(output_path, fourcc, fps, (width, height))else:out = None# 处理视频帧frame_count = 0start_time = time.time()while True:ret, frame = cap.read()if not ret:breakframe_count += 1# 执行检测results = model(frame)result = results[0]# 在帧上绘制检测结果for box in result.boxes:x1, y1, x2, y2 = map(int, box.xyxy[0])conf = float(box.conf[0])cls_id = int(box.cls[0])if conf >= conf_threshold:label = f"{result.names[cls_id]} {conf:.2f}"cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)cv2.putText(frame, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)# 显示实时FPScurrent_time = time.time()elapsed_time = current_time - start_timefps_text = f"FPS: {frame_count / elapsed_time:.2f}"cv2.putText(frame, fps_text, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)# 保存输出帧if out:out.write(frame)# 显示结果cv2.imshow("Video Detection", frame)# 按'q'键退出if cv2.waitKey(1) & 0xFF == ord('q'):break# 清理资源cap.release()if out:out.release()cv2.destroyAllWindows()print(f"处理了 {frame_count} 帧,平均 FPS: {frame_count / elapsed_time:.2f}")if __name__ == "__main__":parser = argparse.ArgumentParser(description='YOLOv3视频目标检测')parser.add_argument('--video', type=str, default='0', help='输入视频路径或摄像头索引 (默认为0,表示默认摄像头)')parser.add_argument('--conf', type=float, default=0.25, help='置信度阈值')parser.add_argument('--output', type=str, default=None, help='输出视频路径 (可选)')args = parser.parse_args()detect_video(args.video, args.conf, args.output)
使用OpenCV DNN处理视频
如果你想使用OpenCV DNN模块处理视频:
python
import cv2
import numpy as np
import time
import argparsedef detect_video_opencv(video_path, config_path, weights_path, conf_threshold=0.5, nms_threshold=0.4, output_path=None):# 加载类别名称with open('coco.names', 'rt') as f:classes = f.read().rstrip('\n').split('\n')# 设置随机颜色np.random.seed(42)colors = np.random.randint(0, 255, size=(len(classes), 3), dtype=np.uint8)# 加载网络net = cv2.dnn.readNetFromDarknet(config_path, weights_path)# 检查可用的计算后端backend = cv2.dnn.DNN_BACKEND_OPENCVtarget = cv2.dnn.DNN_TARGET_CPU# 如果有CUDA支持,可以启用GPUif cv2.cuda.getCudaEnabledDeviceCount() > 0:backend = cv2.dnn.DNN_BACKEND_CUDAtarget = cv2.dnn.DNN_TARGET_CUDAnet.setPreferableBackend(backend)net.setPreferableTarget(target)# 获取输出层名称layer_names = net.getLayerNames()output_layers = [layer_names[i - 1] for i in net.getUnconnectedOutLayers()]# 打开视频文件或摄像头if video_path.isdigit():cap = cv2.VideoCapture(int(video_path)) # 摄像头else:cap = cv2.VideoCapture(video_path) # 视频文件if not cap.isOpened():print(f"无法打开视频源: {video_path}")return# 获取视频参数width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))fps = cap.get(cv2.CAP_PROP_FPS)# 准备输出视频if output_path:fourcc = cv2.VideoWriter_fourcc(*'XVID')out = cv2.VideoWriter(output_path, fourcc, fps, (width, height))else:out = None# 处理视频帧frame_count = 0start_time = time.time()processing_times = []while True:ret, frame = cap.read()if not ret:breakframe_count += 1frame_start_time = time.time()# 图像预处理blob = cv2.dnn.blobFromImage(frame, 1/255.0, (416, 416), swapRB=True, crop=False)net.setInput(blob)# 前向传播outputs = net.forward(output_layers)# 处理检测结果class_ids = []confidences = []boxes = []for output in outputs:for detection in output:scores = detection[5:]class_id = np.argmax(scores)confidence = scores[class_id]if confidence > conf_threshold:# 目标位置center_x = int(detection[0] * width)center_y = int(detection[1] * height)w = int(detection[2] * width)h = int(detection[3] * height)# 计算左上角坐标x = int(center_x - w / 2)y = int(center_y - h / 2)boxes.append([x, y, w, h])confidences.append(float(confidence))class_ids.append(class_id)# 非最大抑制indices = cv2.dnn.NMSBoxes(boxes, confidences, conf_threshold, nms_threshold)# 绘制检测结果for i in indices:i = i if isinstance(i, int) else i[0] # 处理不同OpenCV版本的兼容性box = boxes[i]x, y, w, h = boxlabel = f"{classes[class_ids[i]]}: {confidences[i]:.2f}"color = [int(c) for c in colors[class_ids[i]]]# 绘制边界框和标签cv2.rectangle(frame, (x, y), (x + w, y + h), color, 2)cv2.putText(frame, label, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)# 计算处理时间frame_time = time.time() - frame_start_timeprocessing_times.append(frame_time)# 显示实时FPScurrent_time = time.time()elapsed_time = current_time - start_timefps_text = f"FPS: {frame_count / elapsed_time:.2f}"cv2.putText(frame, fps_text, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)# 保存输出帧if out:out.write(frame)# 显示结果cv2.imshow("Video Detection", frame)# 按'q'键退出if cv2.waitKey(1) & 0xFF == ord('q'):break# 清理资源cap.release()if out:out.release()cv2.destroyAllWindows()# 打印统计信息avg_time = sum(processing_times) / len(processing_times) if processing_times else 0print(f"处理了 {frame_count} 帧")print(f"平均处理时间: {avg_time:.4f} 秒/帧")print(f"平均 FPS: {1 / avg_time:.2f}" if avg_time > 0 else "无法计算 FPS")if __name__ == "__main__":parser = argparse.ArgumentParser(description='YOLOv3视频目标检测')parser.add_argument('--video', type=str, default='0', help='输入视频路径或摄像头索引 (默认为0,表示默认摄像头)')parser.add_argument('--config', type=str, default='yolov3.cfg', help='模型配置文件路径')parser.add_argument('--weights', type=str, default='yolov3.weights', help='模型权重文件路径')parser.add_argument('--conf', type=float, default=0.5, help='置信度阈值')parser.add_argument('--output', type=str, default=None, help='输出视频路径 (可选)')args = parser.parse_args()detect_video_opencv(args.video, args.config, args.weights, args.conf, 0.4, args.output)
模型性能优化
YOLOv3是一个功能强大的模型,但在资源有限的环境中,可能需要进行一些优化。以下是一些实用的优化技巧:
1. 降低输入图像分辨率
默认情况下,YOLOv3使用416×416的输入分辨率,但你可以降低它以提高速度:
python
# 例如,将分辨率降低到320×320
blob = cv2.dnn.blobFromImage(img, 1/255.0, (320, 320), swapRB=True, crop=False)
2. 使用YOLOv3-tiny
YOLOv3-tiny是YOLOv3的轻量级版本,速度更快但准确性略低:
bash
# 下载YOLOv3-tiny的配置和权重
wget https://raw.githubusercontent.com/AlexeyAB/darknet/master/cfg/yolov3-tiny.cfg
wget https://pjreddie.com/media/files/yolov3-tiny.weights
然后修改代码,使用这些文件。
3. 利用GPU加速(如果可用)
对于OpenCV DNN实现:
python
net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA)
net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA)
对于Ultralytics实现,它会自动利用可用的GPU。
4. 批处理
如果你需要处理多个图像,可以考虑批处理来提高吞吐量:
python
# 使用Ultralytics YOLOv3的批处理
results = model(batch_of_images, batch_size=4)
5. 量化和优化
对于更高级的优化,可以考虑模型量化和TensorRT优化(需要NVIDIA GPU):
bash
# 使用ONNX和TensorRT(需要额外步骤)
pip install onnx onnxruntime-gpu
# 转换模型到ONNX格式,然后使用TensorRT优化
常见问题解答
1. 检测结果不准确怎么办?
- 尝试调整置信度阈值(conf_threshold)和NMS阈值(nms_threshold)
- 检查图像预处理步骤是否正确
- 确保模型权重和配置文件匹配
2. 为什么我的检测速度很慢?
- 如果没有GPU,速度会受限
- 尝试使用YOLOv3-tiny版本
- 减小输入分辨率
- 确保你的OpenCV是带CUDA支持编译的(用于GPU加速)
3. 如何处理大型图像?
- 将大图像分割成较小的块进行处理
- 降低图像分辨率,但这可能导致小目标检测性能下降
4. 为什么某些物体没有被检测到?
- 小目标往往更难检测,尝试增加输入分辨率
- 某些物体可能不在COCO数据集的80个类别中
- 物体可能被遮挡或光照条件不佳
5. 模型文件太大,有更小的替代方案吗?
- 使用YOLOv3-tiny(约34MB)代替完整的YOLOv3(约240MB)
- 对模型进行量化可以进一步减小体积
相关文章:
YOLOv3实践教程:使用预训练模型进行目标检测
目录 简介环境准备获取预训练模型图像目标检测视频目标检测模型性能优化常见问题解答进阶学习路径 简介 YOLOv3(You Only Look Once version 3)是一种高效的实时目标检测算法,由Joseph Redmon和Ali Farhadi于2018年提出。与传统的目标检测…...
confluent-kafka入门教程
文章目录 官方文档与kafka-python的对比配置文档配置项 Producer代码示例Consumer代码示例 官方文档 confluent_kafka API — confluent-kafka 2.8.0 documentation Quick Start for Confluent Cloud | Confluent Documentation 与kafka-python的对比 对比维度confluent-ka…...
网络安全-Http\Https协议和Bp抓包
1. http协议,有请求必有相应, 请求协议, 响应协议; 2. 密码学加密机制及常用算法和常用名称说明: 算法 密钥 明文数据 密文; 加密算法分类和常用算法: 加密算法可以归结为三大类ÿ…...
TDengine 语言连接器(C#)
简介 TDengine.Connector 是 TDengine 提供的 C# 语言连接器。C# 开发人员可以通过它开发存取 TDengine 集群数据的 C# 应用软件。 .NET 版本兼容性 .NET Framework 4.6 及以上版本。.NET 5.0 及以上版本。 支持的平台 原生连接支持的平台和 TDengine 客户端驱动支持的平台…...
AI对百度搜索与抖音社区的影响差异?
在AIGC(生成式人工智能)快速发展的背景下,用户获取内容的方式确实变得更加直接和便捷。抖音、小红书等视频内容社区的流量下降速度可能比百度搜索更慢,这一现象可以从以下几个角度分析: 1. 内容形式的差异:…...
《ADVANCING MATHEMATICAL REASONING IN LAN- GUAGE MODELS》全文阅读
《ADVANCING MATHEMATICAL REASONING IN LAN- GUAGE MODELS: THE IMPACT OF PROBLEM-SOLVING DATA, DATA SYNTHESIS METHODS, AND TRAINING STAGES》全文阅读 提升语言模型中的数学推理能力:问题求解数据、数据合成方法及训练阶段的影响 \begin{abstract} 数学推…...
是德科技KEYSIGHT Agilent U2004A功率传感器
是德科技KEYSIGHT Agilent U2004A功率传感器 Keysight U2004A USB功率传感器的特性和规格包括: 频率范围为 9 kHz 至 6 GHz -60 至 20 dBm 的宽动态范围 内部调零功能消除了外部校准 测量速度高达 250 个读数/秒 在 PC 或其他 Agilent 仪器上显示功率测量值 频率…...
Kubernetes(K8S)内部功能总结
Kubernetes(K8S)是云技术的最核心的部分,也是构建是云原生的基石 K8S K8S,是Kubernetes的缩写,是Google开发的容器编排平台,现在由云原生计算基金会(CNCF)进行维护。 K8Sÿ…...
智谱最新模型GLM4是如何练成的
写在前面 这篇博客将基于《ChatGLM: A Family of Large Language Models from GLM-130B to GLM-4 All Tools》,深入剖析 GLM-4 系列在**模型架构设计、预训练、后训练(对齐)、以及关键技术创新(如长上下文处理、Agent 能力构建)**等环节的实现逻辑与设计考量,带你全面了…...
类头文件相互包含的问题
1.预编译指令: #ifndef CLASS_A_ #define CLASS_A_#include CLASS_B.h#endif 2.#pragma once 3.将类A中声明类B,并类中声明类B的指针,在类中的实现文件中包含类B的头文件。在类B中包含类A的头文件 a.h:class Bclass A {public:private:B*…...
云原生周刊:K8s 中的 GPU 共享
开源项目推荐 A2A Google 的 Agent2Agent(A2A)协议是一个开源标准,旨在促进不同框架和供应商构建的 AI 代理之间的互操作性。它允许代理通过统一的协议安全地交换信息、协同执行任务,并在多种企业平台和云环境中无缝协作。 A2A…...
(五)机器学习---决策树和随机森林
在分类问题中还有一个常用算法:就是决策树。本文将会对决策树和随机森林进行介绍。 目录 一.决策树的基本原理 (1)决策树 (2)决策树的构建过程 (3)决策树特征选择 (4࿰…...
DeepReaserch写的文献综述示例分享
目录 DeepReaserch提供的文献综述: 人工智能在医疗影像诊断中的研究进展综述(2015–2025) 引言 1 近十年研究进展回顾 1.1 深度学习崛起阶段(2015–2017年) 1.2 方法完善与临床初探(2018–2020年&…...
Token安全存储的几种方式
文章目录 1. EncryptedSharedPreferences示例代码 2. SQLCipher示例代码 3.使用 Android Keystore加密后存储示例代码1. 生成密钥对2. 使用 KeystoreManager 代码说明安全性建议加密后的几种存储方式1. 加密后采用 SharedPreferences存储2. 加密后采用SQLite数据库存储1. Token…...
阶段性使用总结-通义灵码
序言 前段时间用通义灵码,参加了下数字中国闽江流域的比赛。https://www.dcic-china.com/competitions/10173 最后成绩一般般,106名,大概有2000多人参加这题目,估计有一堆小号。 按照下面这个思路建模的,迭代了大概15…...
SpringBoot 与 Vue3 实现前后端互联全解析
在当前的互联网时代,前后端分离架构已经成为构建高效、可维护且易于扩展应用系统的主流方式。本文将详细介绍如何利用 SpringBoot 与 Vue3 构建一个前后端分离的项目,展示两者如何通过 RESTful API 实现无缝通信,让读者了解从环境搭建、代码实…...
Flutter 图标和按钮组件
引言 在 Flutter 应用开发中,图标和按钮是构建用户界面不可或缺的元素。图标能够以直观的图形方式传达信息,增强应用的视觉吸引力;而按钮则是用户与应用进行交互的重要途径。本文将详细介绍 Flutter 中图标和按钮组件的使用,涵盖…...
大模型平台Dify工作流高效调用Ragflow知识库,解决其原生知识库解析和检索能力不足的问题
Dify调用Ragflow知识库的详细步骤,安装详细部署在我之前文章 多图超详细:Docker安装知识库AI客服RAGFlow的详细步骤、使用教程及注意事项:。超详细:Dify大语言模型工作流开发平台的安装与使用,deepseek知识库客服等。…...
数据库的基本原则
数据库的核心原则 原子性与持久性:原子性(Atomicity)确保一个事务中的所有操作要么全部完成,要么完全不执行,不会出现部分完成的情况。持久性(Durability)则保证一旦事务提交成功,即…...
项目集管理汇报报告 (范本)
该文档适用于企业管理层、项目经理、项目团队成员以及对项目集管理感兴趣的人员。它对企业项目管理至关重要,通过全面分析 揭示了如目标达成率低、数据缺失严重、成本进度管控有风险等关键问题,为管理层提供决策依据,助力其了解项目整体状况&…...
阿里云 MSE Nacos 发布全新“安全防护”模块,简化安全配置,提升数据保护
作者:张文浩 阿里云在其微服务引擎(MSE)注册配置中心 Nacos 上正式推出全新“安全防护”功能模块,旨在帮助企业用户有效管理安全状态和降低开启安全相关功能的学习成本,提升微服务架构的安全性。首期推出的“安全防护…...
Pydantic v2 的使用
一、前言 Pydantic 是一个 Python 数据验证 和 设置管理 库,使用 Python 类型 注解。具有以下特点: 1.1 核心功能 数据验证:自动验证数据类型和约束条件类型转换:自动将输入数据转换为声明类型Schema 生成:自动生成…...
从零开始学A2A二 : A2A 协议的技术架构与实现
A2A 协议的技术架构与实现 学习目标 技术架构掌握 深入理解 A2A 协议的分层架构设计掌握各层次的功能和职责理解协议的工作原理和数据流 实现能力培养 能够搭建基本的 A2A 服务端掌握客户端开发方法实现智能体间的有效通信 架构设计理解 理解与 MCP 的本质区别掌握多智能体协…...
设计模式每日硬核训练 Day 12:装饰器模式(Decorator Pattern)完整讲解与实战应用
🔄 回顾 Day 11:适配器模式小结 在 Day 11 中,我们学习了适配器模式(Adapter Pattern): 用于将“不兼容”的接口适配为目标接口,解决新旧系统之间的桥接问题。强调“接口兼容、外部桥接”&…...
[CMake] CMakePresets.json简单使用
解决的问题 CMakePresets.json是为了解决在使用命令行编译使用CMake的项目时,可能会十分麻烦。如类似的参数-DCMAKE_BUILD_TYPEDebug所以有了CMakePresets.json来配置configure和build时的命令,然后在使用时 cmake --preset<configure-preset-name&…...
智能办公如何创建e10流程
智能办公如何创建e10流程 配置e10流程前,您要做的事情: 1、进入e10管理后台,创建应用,开放接口权限;2、进入e10管理后台,配置千里聆套件,配置同步人员;3、进入千里聆系统ÿ…...
Mac关闭sip方法
Mac关闭sip方法 导航 文章目录 Mac关闭sip方法导航完整操作流程图详细步骤 完整操作流程图 这东西是我在网上搬运下来的,但是我在为业务实操过程中,根据实操情况还是有新的注意点的 详细步骤 1.在「关于本机」-「系统报告」-「软件」;查看SIP是否开启…...
Flutter 播放利器:`media_kit` 的详细介绍与使用指南
在 Flutter 项目中实现音视频播放,开发者过去主要依赖如 video_player、just_audio 等第三方库,但这些库或多或少存在一些局限性,比如平台兼容性差、定制能力不足、播放格式有限等问题。 而 media_kit 是近年崛起的一款全平台音视频播放解决…...
GEO优化中的关键底座:知识图谱如何提升生成式AI的准确性与实时性?
今天,我将与大家分享如何通过GEO优化(生成式人工智能优化)和动态知识图谱,帮助企业提升智能化水平并实现高效的业务运营。首先,GEO优化利用生成式AI为企业提供内容生成、客服自动化和智能销售等服务,而知识…...
案例 - 登录认证:保障系统安全访问的实现
摘要:本文介绍了为Tlias智能学习辅助系统添加登录认证功能的过程,涵盖从需求分析、接口文档设计,到思路分析、功能开发以及最后的测试等多个关键环节,旨在实现只有通过登录认证的用户才能安全访问后台系统功能的目标。 关键词&am…...
Node.js Session 原理简单介绍 + 示例代码
目录 ✅ Session 原理简要说明 🧩 示例项目 - 使用 Node.js Express 实现简单 Session 登录 📁 文件结构 🔹 server.js (JavaScript) 🔸 index.html (HTML) ▶️ 程序运行步骤 ✅ 程序运行效果 🎯 总结 在 We…...
C# 类型、存储和变量(C#程序是一组类型声明)
本章内容 C#程序是一组类型声明 类型是一种模板 实例化类型 数据成员和函数成员 预定义类型 用户定义类型 栈和堆 值类型和引用类型 变量 静态类型和dynamic关键字 可空类型 C#程序是一组类型声明 如果广泛地描述C和C程序源代码的特征,可以说C程序是一组函数和数据…...
复变函数摘记3
复变函数摘记3 5. 留数5.1 可去奇点、极点、本性奇点5.2 零点与极点的关系5.3 在无穷远点处的情形5.4 留数 5. 留数 \quad 如果函数 f ( z ) f(z) f(z) 在 z 0 z_0 z0 及 z 0 z_0 z0 的邻域内处处可导,那么称 f ( z ) f(z) f(z) 在点 z 0 z_0 z0 处解析。…...
深入定制 QSlider——实现精准点击跳转与拖拽区分
在使用 Qt 编写界面应用时,QSlider 是一个常用的滑动控件。但你可能会注意到,默认情况下点击滑轨(groove)区域时,滑块并不会直接跳到鼠标点击的位置,而是按照内部的分页步进(page step)行为响应。此外,垂直 Slider 在点击最底部时还存在 releaseEvent(或 sliderRelea…...
Summary
一、数据结构 1.1 哈希 主要是HashMap和HashSet;其中HashSet底层是一个HashMap属性。 // 获取HashMap元素,HashSet均不支持 map.keySet (); // Set<k> map.values (; // Collection<V> map.entrySet();//Set<Map.Entry<K,V>> for (Map.E…...
MCP Server 开发实战 | 大模型无缝对接 Grafana
前言 随着大模型的飞速发展,越来越多的 AI 创新颠覆了过往很多产品的使用体验。但你是否曾想过,在向大型语言模型提问时,它能否根据你的需求精准返回系统中的对应数据?例如,当用户查询 Grafana 服务时,模型…...
【ROS2】行为树 BehaviorTree(六):各种各样的节点
1、装饰器节点 Decorators 1)否操作 Inverter 如果子项失败则返回 SUCCESS,如果子项成功则返回 FAILURE。 如果子节点返回 RUNNING,则该节点也返回 RUNNING。 2)强制成功 ForceSuccess 如果子节点返回 RUNNING,则该节点也返回 RUNNING。 否则,它总是返回 SUCCESS。 3)…...
Docker Swarm 集群使用指南概述
概述 对于简单轻量级集群管理,利用 Docker Swarm 就够用了,适合中小型应用程序的容器编排。如果是比较重的中心化集群管理方案或需要更复杂的功能,可以考虑使用 Kubernetes Helm Consul 等更强大的容器编排工具。 Docker Swarm 1. Docke…...
【行业树选择器组件:基于Vue3与Element Plus的高性能树形选择组件优化与重构】
行业树选择器组件:基于Vue3与Element Plus的高性能树形选择组件优化与重构 组件概述与背景 行业树选择器是一个基于Element Plus的ElTreeSelect封装的业务组件,主要应用于能源管理系统中,用于展示和选择国标行业分类体系的四级层级结构。该…...
PasteForm框架开发之Entity多级嵌套的表单的实现
你相信么,使用PasteForm框架开发,管理端居然不要写代码!!! 一起来看看PasteForm是否支持多级表模式(外表) 需求假设 假如有这么一个需求,就是订单表,包含了多级的信息,比如这个订单包含了哪些…...
Anaconda笔记
下载Anaconda 清华源 官方源 本文下载:Anaconda3-2024.10-1-Windows-x86_64.exe 建议不要安装到C盘,我的安装到D:Anaconda目录 设置环境变量 WinR cmd命令行输入: conda --version:可以查看到版本信息安装成功c…...
Linux——共享内存
目录 一、共享内存概念 二、共享内存的一些函数 2.1 shmget 创建共享内存 2.2 shmat 访问共享内存 2.3 shmdt 解除共享内存的映射 2.4 shnctl 删除共享内存段 三、共享内存 3.1 创建测试进程 3.2 使用循环测试 编辑 3.3 共享内存写入程序 3.4 带有信号量的共享内…...
计算机系统---烤机(性能测评)
计算机烤机 一、烤机的定义与核心目的 烤机(Burn-in Test) 是通过对计算机硬件施加持续高负载,模拟极端运行环境,以验证硬件稳定性、性能极限、散热能力及潜在缺陷的测试方法。核心目标包括: 硬件稳定性验证&#x…...
Linux命令+Git命令
Linux命令Git命令 linux查看两个操作系统cd命令的区别操作文件和文件夹vim不同模式保存和退出 Git linux Linux操作系统中,几乎所有的东西都以文件夹或文件形式存在,这些文件夹/文件有一个共同的根目录/。如果我们在某块磁盘A上(无其他分区&…...
【前端】Nuxt打包部署的几种方式
一、总结知识点 Nuxt 是基于 Vue 的服务端渲染框架,部署方式主要取决于你使用的 Nuxt 模式:Universal (SSR)、SPA 或 Static Site Generation (SSG)。不同模式下的打包部署流程略有不同。以下将分别介绍 Nuxt 应用的打包和部署方式。 二、详细说明 1. …...
DP 16bit位宽数据扰码实现和仿真
DisplayPort 1.4协议中数据需进行扰码,扰码用到了16-bit LFSR,表达式如下。 LFSR每移位8个bit后,用最高有效 8 位以相反的位顺序与一个字节数据进行异或从而实现数据加扰/解扰。 我们已利用这个框图进行8个时钟周期迭代,得到了和…...
力扣每日打卡 1534. 统计好三元组 (简单)
力扣 1534. 统计好三元组 简单 前言一、题目内容二、解题方法1. 暴力解法2.官方题解2.1 方法一:枚举2.2 方法二:枚举优化 前言 这是刷算法题的第十二天,用到的语言是JS 题目:力扣 1534. 统计好三元组 (简单) 一、题目内容 给你一…...
CExercise_13_1排序算法_1插入排序
题目: 请自己手动实现插入排序算法: // 插入排序 void insertion_sort(int arr[], int len); 然后给定一个int数组,实现将它从小到大进行排序。 关键点 分析: 在插入排序中,稳定性指的是排序算法能够保持相等元素的原始…...
图论--DFS搜索图/树
目录 一、图的存储结构 二、题目练习 846. 树的重心 - AcWing题 dfs,之前学习的回溯算法好多都是用dfs实现搜索的(把题目抽象成树形结构来搜索),其实 回溯算法就是 深搜,只不过针对某一搜索场景 我们给他一个更细分…...
blender 超逼真角色daz 纹理材质 humanpro插件
https://www.youtube.com/KhanhVo-zp9lh/featured https://superhivemarket.com/products/humanpro https://superhivemarket.com/products/humanpro HUMANPRO 插件 - BLENDER HumanPro 是一款专为帮助用户轻松快速地创建高度精细逼真的人体皮肤纹理和复杂皱纹而设计的插件…...