YOLO11 目标检测 | 导出ONNX模型 | ONNX模型推理
本文分享YOLO11中,从xxx.pt权重文件转为.onnx文件,然后使用.onnx文件,进行目标检测任务的模型推理。
用ONNX模型推理,便于算法到开发板或芯片的部署。
备注:本文是使用Python,编写ONNX模型推理代码的
目录
1、导出ONNX模型
2、目标检测——ONNX模型推理
2.1、ONNX模型推理-整体流程
2.2、预处理函数
2.3、后处理函数
2.4、检测效果可视化函数
2.5、YOLO11目标检测——ONNX模型推理完整代码
1、导出ONNX模型
首先我们训练好的模型,生成xxx.pt权重文件;
然后用下面代码,导出ONNX模型(简洁版)
from ultralytics import YOLO# 加载一个模型,路径为 YOLO 模型的 .pt 文件
model = YOLO("runs/detect/train/weights/best.pt")# 导出模型,格式为 ONNX
model.export(format="onnx")
运行代码后,会在上面路径中生成best.onnx文件的
- 比如,填写的路径是:"runs/detect/train/weights/best.pt"
- 那么在runs/detect/train/weights/目录中,会生成与best.pt同名的onnx文件,即best.onnx
上面代码示例是简单版,如果需要更专业设置ONNX,用下面版本的
YOLO11导出ONNX模型(专业版)
from ultralytics import YOLO# 加载一个模型,路径为 YOLO 模型的 .pt 文件
model = YOLO("runs/detect/train/weights/best.pt")# 导出模型,设置多种参数
model.export(format="onnx", # 导出格式为 ONNXimgsz=(640, 640), # 设置输入图像的尺寸keras=False, # 不导出为 Keras 格式optimize=False, # 不进行优化half=False, # 不启用 FP16 量化int8=False, # 不启用 INT8 量化dynamic=False, # 不启用动态输入尺寸simplify=True, # 简化 ONNX 模型opset=None, # 使用最新的 opset 版本workspace=4.0, # 为 TensorRT 优化设置最大工作区大小(GiB)nms=False, # 不添加 NMS(非极大值抑制)batch=1 # 指定批处理大小
)
对于model.export( )函数中,各种参数说明:
format="onnx"
:指定导出模型的格式为 onnx。imgsz=(640, 640)
:输入图像的尺寸设为 640x640。如果需要其他尺寸可以修改这个值。keras=False
:不导出为 Keras 格式的模型。optimize=False
:不应用 TorchScript 移动设备优化。half=False
:不启用 FP16(半精度)量化。int8=False
:不启用 INT8 量化。dynamic=False
:不启用动态输入尺寸。simplify=True
:简化模型以提升 ONNX 模型的性能。opset=None
:使用默认的 ONNX opset 版本,如果需要可以手动指定。workspace=4.0
:为 TensorRT 优化指定最大工作空间大小为 4 GiB。nms=False
:不为 CoreML 导出添加非极大值抑制(NMS)。batch=1
:设置批处理大小为 1。
参考官网文档:https://docs.ultralytics.com/modes/export/#arguments
当然了,YOLO11中不仅支持ONNX模型,还支持下面表格中格式
支持的导出格式 | format 参数值 | 生成的模型示例 | model.export( )函数的参数 |
---|---|---|---|
PyTorch | - | yolo11n.pt | - |
TorchScript | torchscript | yolo11n.torchscript | imgsz , optimize , batch |
ONNX | onnx | yolo11n.onnx | imgsz , half , dynamic , simplify , opset , batch |
OpenVINO | openvino | yolo11n_openvino_model/ | imgsz , half , int8 , batch |
TensorRT | engine | yolo11n.engine | imgsz , half , dynamic , simplify , workspace , int8 , batch |
CoreML | coreml | yolo11n.mlpackage | imgsz , half , int8 , nms , batch |
TF SavedModel | saved_model | yolo11n_saved_model/ | imgsz , keras , int8 , batch |
TF GraphDef | pb | yolo11n.pb | imgsz , batch |
TF Lite | tflite | yolo11n.tflite | imgsz , half , int8 , batch |
TF Edge TPU | edgetpu | yolo11n_edgetpu.tflite | imgsz |
TF.js | tfjs | yolo11n_web_model/ | imgsz , half , int8 , batch |
PaddlePaddle | paddle | yolo11n_paddle_model/ | imgsz , batch |
NCNN | ncnn | yolo11n_ncnn_model/ | imgsz , half , batch |
2、目标检测——ONNX模型推理
我们需要编写代码实现了一个使用 ONNXRuntime 执行 YOLOv11 检测模型推理的完整流程,包含图像预处理、推理、后处理和可视化 。
需要编写的代码功能包括:
-
预处理: 读取输入图像,通过 letterbox 填充图像,自动调整图像尺寸,使其符合模型的输入尺寸要求,并归一化并转换为模型输入的格式 。
-
模型推理: 使用 ONNXRuntime 加载YOLO11 模型,并根据系统环境自动选择 CPU 或 GPU 执行推理。预处理后的图像输入到模型中,模型返回预测的边界框、类别和分数等输出结果。
-
后处理: 对模型输出的边界框、类别和分数进行处理,首先根据置信度阈值过滤低置信度的检测结果。然后根据缩放比例将边界框映射回原图的尺寸,应用非极大值抑制(NMS)去除重叠的边界框,最终提取有效的检测结果。
-
可视化: 在输入图像上绘制检测到的边界框、类别名称和置信度,使用不同颜色区分不同类别的对象。可选择将带有检测结果的图像保存到文件中,最终输出检测结果保存的路径。
2.1、ONNX模型推理-整体流程
首先编写一个用于运行YOLO11检测模型的推理类:YOLO11
ONNX推理流程:预处理 -> 推理 -> 后处理
class YOLO11:"""YOLO11 目标检测模型类,用于处理推理和可视化。"""def __init__(self, onnx_model, input_image, confidence_thres, iou_thres):"""初始化 YOLO11 类的实例。参数:onnx_model: ONNX 模型的路径。input_image: 输入图像的路径。confidence_thres: 用于过滤检测结果的置信度阈值。iou_thres: 非极大值抑制(NMS)的 IoU(交并比)阈值。"""self.onnx_model = onnx_modelself.input_image = input_imageself.confidence_thres = confidence_thresself.iou_thres = iou_thres# 加载类别名称self.classes = CLASS_NAMES# 为每个类别生成一个颜色调色板self.color_palette = np.random.uniform(0, 255, size=(len(self.classes), 3))def main(self):# 使用 ONNX 模型创建推理会话,自动选择CPU或GPUsession = ort.InferenceSession(self.onnx_model, providers=["CUDAExecutionProvider", "CPUExecutionProvider"] if ort.get_device() == "GPU" else ["CPUExecutionProvider"],)# 打印模型的输入尺寸print("YOLO11 🚀 目标检测 ONNXRuntime")print("模型名称:", self.onnx_model)# 获取模型的输入形状model_inputs = session.get_inputs()input_shape = model_inputs[0].shape self.input_width = input_shape[2]self.input_height = input_shape[3]print(f"模型输入尺寸:宽度 = {self.input_width}, 高度 = {self.input_height}")# 预处理图像数据,确保使用模型要求的尺寸 (640x640)img_data = self.preprocess()# 使用预处理后的图像数据运行推理outputs = session.run(None, {model_inputs[0].name: img_data})# 对输出进行后处理以获取输出图像return self.postprocess(self.img, outputs) # 输出图像
2.2、预处理函数
然后编写输入图像预处理函数:preprocess
主要功能:对输入的图像进行读取、颜色空间转换、尺寸调整、归一化等预处理操作,并返回适合模型输入的图像数据。
- 使用 OpenCV 读取图像。
- 将图像从 BGR 格式转换为 RGB 格式。
- 使用
letterbox
函数保持图像的宽高比并填充图像,使其符合模型要求的输入尺寸。 - 归一化图像数据(像素值除以 255.0)。
- 转换图像通道的维度,符合 PyTorch 模型的输入格式(通道优先)。
- 扩展图像维度以匹配模型输入的 batch 大小。
def preprocess(self):"""对输入图像进行预处理,以便进行推理。返回:image_data: 经过预处理的图像数据,准备进行推理。"""# 使用 OpenCV 读取输入图像self.img = cv2.imread(self.input_image)# 获取输入图像的高度和宽度self.img_height, self.img_width = self.img.shape[:2]# 将图像颜色空间从 BGR 转换为 RGBimg = cv2.cvtColor(self.img, cv2.COLOR_BGR2RGB)# 保持宽高比,进行 letterbox 填充, 使用模型要求的输入尺寸img, self.ratio, (self.dw, self.dh) = self.letterbox(img, new_shape=(self.input_width, self.input_height))# 通过除以 255.0 来归一化图像数据image_data = np.array(img) / 255.0# 将图像的通道维度移到第一维image_data = np.transpose(image_data, (2, 0, 1)) # 通道优先# 扩展图像数据的维度,以匹配模型输入的形状image_data = np.expand_dims(image_data, axis=0).astype(np.float32)# 返回预处理后的图像数据return image_data
预处理函数preprocess,会依赖letterbox函数。
letterbox函数功能:将图像缩放并进行填充,以保持宽高比,最终将图像调整到指定的输入尺寸。
- 计算图像的缩放比例,保证宽高比不变。
- 根据缩放后的图像尺寸,计算需要的填充量(上下左右)。
- 对图像进行缩放和添加边框(填充),确保最终图像尺寸符合目标输入尺寸。
- 返回调整后的图像、缩放比例及填充尺寸。
def letterbox(self, img, new_shape=(640, 640), color=(114, 114, 114), auto=False, scaleFill=False, scaleup=True):"""将图像进行 letterbox 填充,保持纵横比不变,并缩放到指定尺寸。"""shape = img.shape[:2] # 当前图像的宽高print(f"Original image shape: {shape}")if isinstance(new_shape, int):new_shape = (new_shape, new_shape)# 计算缩放比例r = min(new_shape[0] / shape[0], new_shape[1] / shape[1]) # 选择宽高中最小的缩放比if not scaleup: # 仅缩小,不放大r = min(r, 1.0)# 缩放后的未填充尺寸new_unpad = (int(round(shape[1] * r)), int(round(shape[0] * r)))# 计算需要的填充dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1] # 计算填充的尺寸dw /= 2 # padding 均分dh /= 2# 缩放图像if shape[::-1] != new_unpad: # 如果当前图像尺寸不等于 new_unpad,则缩放img = cv2.resize(img, new_unpad, interpolation=cv2.INTER_LINEAR)# 为图像添加边框以达到目标尺寸top, bottom = int(round(dh)), int(round(dh))left, right = int(round(dw)), int(round(dw))img = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color)print(f"Final letterboxed image shape: {img.shape}")return img, (r, r), (dw, dh)
2.3、后处理函数
再编写后处理函数:postprocess
该代码的功能是对模型的输出结果进行后处理,主要用于从目标检测模型的输出中提取边界框(bounding boxes)、置信度分数和类别ID,并将这些检测结果绘制在输入图像上。
A、模型输出后处理
- 将模型的输出数据进行转置和压缩,使其符合处理的预期格式。
- 遍历模型的每一个检测结果,提取检测框的坐标(x, y, w, h)、类别得分,并通过阈值过滤掉低置信度的检测结果。
- 计算检测框在原始图像上的实际位置,考虑缩放和填充的影响。
B、缩放和填充调整
- 根据图像的缩放比例和填充量,将检测框的坐标从网络输入尺寸(如640x640)调整回原始图像尺寸。
C、非极大值抑制(NMS)
- 使用非极大值抑制(NMS)算法对检测结果进行过滤,删除重叠的检测框,仅保留最高置信度的框。
D、绘制检测结果
- 使用
draw_detections
方法在输入图像上绘制边界框,并标注检测类别和置信度。 - 最终返回包含检测结果的图像,图像上绘制了所有有效的检测框和对应的标签。
def postprocess(self, input_image, output):"""对模型输出进行后处理,以提取边界框、分数和类别 ID。参数:input_image (numpy.ndarray): 输入图像。output (numpy.ndarray): 模型的输出。返回:numpy.ndarray: 包含检测结果的输入图像。"""# 转置并压缩输出,以匹配预期形状outputs = np.transpose(np.squeeze(output[0]))rows = outputs.shape[0]boxes, scores, class_ids = [], [], []# 计算缩放比例和填充ratio = self.img_width / self.input_width, self.img_height / self.input_heightfor i in range(rows):classes_scores = outputs[i][4:]max_score = np.amax(classes_scores)if max_score >= self.confidence_thres:class_id = np.argmax(classes_scores)x, y, w, h = outputs[i][0], outputs[i][1], outputs[i][2], outputs[i][3]# 将框调整到原始图像尺寸,考虑缩放和填充x -= self.dw # 移除填充y -= self.dhx /= self.ratio[0] # 缩放回原图y /= self.ratio[1]w /= self.ratio[0]h /= self.ratio[1]left = int(x - w / 2)top = int(y - h / 2)width = int(w)height = int(h)boxes.append([left, top, width, height])scores.append(max_score)class_ids.append(class_id)indices = cv2.dnn.NMSBoxes(boxes, scores, self.confidence_thres, self.iou_thres)for i in indices:box = boxes[i]score = scores[i]class_id = class_ids[i]self.draw_detections(input_image, box, score, class_id)return input_image
2.4、检测效果可视化函数
该代码的功能是根据检测结果在输入图像上绘制边界框和标签,以可视化目标检测的结果。
def draw_detections(self, img, box, score, class_id):"""在输入图像上绘制检测到的边界框和标签。参数:img: 用于绘制检测结果的输入图像。box: 检测到的边界框。score: 对应的检测分数。class_id: 检测到的目标类别 ID。返回:None"""# 提取边界框的坐标x1, y1, w, h = box# 获取类别对应的颜色color = self.color_palette[class_id]# 在图像上绘制边界框cv2.rectangle(img, (int(x1), int(y1)), (int(x1 + w), int(y1 + h)), color, 2)# 创建包含类别名和分数的标签文本label = f"{self.classes[class_id]}: {score:.2f}"# 计算标签文本的尺寸(label_width, label_height), _ = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.5, 1)# 计算标签文本的位置label_x = x1label_y = y1 - 10 if y1 - 10 > label_height else y1 + 10# 绘制填充的矩形作为标签文本的背景cv2.rectangle(img, (label_x, label_y - label_height), (label_x + label_width, label_y + label_height), color, cv2.FILLED)# 在图像上绘制标签文本cv2.putText(img, label, (label_x, label_y), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 1, cv2.LINE_AA)
2.5、YOLO11目标检测——ONNX模型推理完整代码
完整代码,如下所示:
# Ultralytics YOLO 🚀, AGPL-3.0 licenseimport argparse
import cv2
import numpy as np
import onnxruntime as ort# 类外定义类别映射关系,使用字典格式
CLASS_NAMES = {0: 'class_name1', # 类别 0 名称1: 'class_name2', # 类别 1 名称2: 'class_name3' # 类别 1 名称# 可以添加更多类别...
}class YOLO11:"""YOLO11 目标检测模型类,用于处理推理和可视化。"""def __init__(self, onnx_model, input_image, confidence_thres, iou_thres):"""初始化 YOLO11 类的实例。参数:onnx_model: ONNX 模型的路径。input_image: 输入图像的路径。confidence_thres: 用于过滤检测结果的置信度阈值。iou_thres: 非极大值抑制(NMS)的 IoU(交并比)阈值。"""self.onnx_model = onnx_modelself.input_image = input_imageself.confidence_thres = confidence_thresself.iou_thres = iou_thres# 加载类别名称self.classes = CLASS_NAMES# 为每个类别生成一个颜色调色板self.color_palette = np.random.uniform(0, 255, size=(len(self.classes), 3))def preprocess(self):"""对输入图像进行预处理,以便进行推理。返回:image_data: 经过预处理的图像数据,准备进行推理。"""# 使用 OpenCV 读取输入图像self.img = cv2.imread(self.input_image)# 获取输入图像的高度和宽度self.img_height, self.img_width = self.img.shape[:2]# 将图像颜色空间从 BGR 转换为 RGBimg = cv2.cvtColor(self.img, cv2.COLOR_BGR2RGB)# 保持宽高比,进行 letterbox 填充, 使用模型要求的输入尺寸img, self.ratio, (self.dw, self.dh) = self.letterbox(img, new_shape=(self.input_width, self.input_height))# 通过除以 255.0 来归一化图像数据image_data = np.array(img) / 255.0# 将图像的通道维度移到第一维image_data = np.transpose(image_data, (2, 0, 1)) # 通道优先# 扩展图像数据的维度,以匹配模型输入的形状image_data = np.expand_dims(image_data, axis=0).astype(np.float32)# 返回预处理后的图像数据return image_datadef letterbox(self, img, new_shape=(640, 640), color=(114, 114, 114), auto=False, scaleFill=False, scaleup=True):"""将图像进行 letterbox 填充,保持纵横比不变,并缩放到指定尺寸。"""shape = img.shape[:2] # 当前图像的宽高print(f"Original image shape: {shape}")if isinstance(new_shape, int):new_shape = (new_shape, new_shape)# 计算缩放比例r = min(new_shape[0] / shape[0], new_shape[1] / shape[1]) # 选择宽高中最小的缩放比if not scaleup: # 仅缩小,不放大r = min(r, 1.0)# 缩放后的未填充尺寸new_unpad = (int(round(shape[1] * r)), int(round(shape[0] * r)))# 计算需要的填充dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1] # 计算填充的尺寸dw /= 2 # padding 均分dh /= 2# 缩放图像if shape[::-1] != new_unpad: # 如果当前图像尺寸不等于 new_unpad,则缩放img = cv2.resize(img, new_unpad, interpolation=cv2.INTER_LINEAR)# 为图像添加边框以达到目标尺寸top, bottom = int(round(dh)), int(round(dh))left, right = int(round(dw)), int(round(dw))img = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color)print(f"Final letterboxed image shape: {img.shape}")return img, (r, r), (dw, dh)def postprocess(self, input_image, output):"""对模型输出进行后处理,以提取边界框、分数和类别 ID。参数:input_image (numpy.ndarray): 输入图像。output (numpy.ndarray): 模型的输出。返回:numpy.ndarray: 包含检测结果的输入图像。"""# 转置并压缩输出,以匹配预期形状outputs = np.transpose(np.squeeze(output[0]))rows = outputs.shape[0]boxes, scores, class_ids = [], [], []# 计算缩放比例和填充ratio = self.img_width / self.input_width, self.img_height / self.input_heightfor i in range(rows):classes_scores = outputs[i][4:]max_score = np.amax(classes_scores)if max_score >= self.confidence_thres:class_id = np.argmax(classes_scores)x, y, w, h = outputs[i][0], outputs[i][1], outputs[i][2], outputs[i][3]# 将框调整到原始图像尺寸,考虑缩放和填充x -= self.dw # 移除填充y -= self.dhx /= self.ratio[0] # 缩放回原图y /= self.ratio[1]w /= self.ratio[0]h /= self.ratio[1]left = int(x - w / 2)top = int(y - h / 2)width = int(w)height = int(h)boxes.append([left, top, width, height])scores.append(max_score)class_ids.append(class_id)indices = cv2.dnn.NMSBoxes(boxes, scores, self.confidence_thres, self.iou_thres)for i in indices:box = boxes[i]score = scores[i]class_id = class_ids[i]self.draw_detections(input_image, box, score, class_id)return input_imagedef draw_detections(self, img, box, score, class_id):"""在输入图像上绘制检测到的边界框和标签。参数:img: 用于绘制检测结果的输入图像。box: 检测到的边界框。score: 对应的检测分数。class_id: 检测到的目标类别 ID。返回:None"""# 提取边界框的坐标x1, y1, w, h = box# 获取类别对应的颜色color = self.color_palette[class_id]# 在图像上绘制边界框cv2.rectangle(img, (int(x1), int(y1)), (int(x1 + w), int(y1 + h)), color, 2)# 创建包含类别名和分数的标签文本label = f"{self.classes[class_id]}: {score:.2f}"# 计算标签文本的尺寸(label_width, label_height), _ = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.5, 1)# 计算标签文本的位置label_x = x1label_y = y1 - 10 if y1 - 10 > label_height else y1 + 10# 绘制填充的矩形作为标签文本的背景cv2.rectangle(img, (label_x, label_y - label_height), (label_x + label_width, label_y + label_height), color, cv2.FILLED)# 在图像上绘制标签文本cv2.putText(img, label, (label_x, label_y), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 1, cv2.LINE_AA)def main(self):# 使用 ONNX 模型创建推理会话,自动选择CPU或GPUsession = ort.InferenceSession(self.onnx_model, providers=["CUDAExecutionProvider", "CPUExecutionProvider"] if ort.get_device() == "GPU" else ["CPUExecutionProvider"],)# 打印模型的输入尺寸print("YOLO11 🚀 目标检测 ONNXRuntime")print("模型名称:", self.onnx_model)# 获取模型的输入形状model_inputs = session.get_inputs()input_shape = model_inputs[0].shape self.input_width = input_shape[2]self.input_height = input_shape[3]print(f"模型输入尺寸:宽度 = {self.input_width}, 高度 = {self.input_height}")# 预处理图像数据,确保使用模型要求的尺寸 (640x640)img_data = self.preprocess()# 使用预处理后的图像数据运行推理outputs = session.run(None, {model_inputs[0].name: img_data})# 对输出进行后处理以获取输出图像return self.postprocess(self.img, outputs) # 输出图像if __name__ == "__main__":# 创建参数解析器以处理命令行参数parser = argparse.ArgumentParser()parser.add_argument("--model", type=str, default="runs/detect/train/weights/best.onnx", help="输入你的 ONNX 模型路径。")parser.add_argument("--img", type=str, default=r"datasets/test.jpg", help="输入图像的路径。")parser.add_argument("--conf-thres", type=float, default=0.5, help="置信度阈值")parser.add_argument("--iou-thres", type=float, default=0.45, help="NMS IoU 阈值")args = parser.parse_args()# 使用指定的参数创建 YOLO11 类的实例detection = YOLO11(args.model, args.img, args.conf_thres, args.iou_thres)# 执行目标检测并获取输出图像output_image = detection.main()# 保存输出图像到文件cv2.imwrite("det_result_picture.jpg", output_image)print("图像已保存为 det_result_picture.jpg")
需要修改类别映射关系,以及类别对应的颜色
比如,定义两个类别(car、person), 示例代码:
# 类外定义类别映射关系,使用字典格式
CLASS_NAMES = {0: 'car', # 类别 0 名称1: 'person' # 类别 1 名称# 可以添加更多类别...
}
运行代码,打印信息:
YOLO11 🚀 目标检测 ONNXRuntime
模型名称: runs/detect/train/weights/best.onnx
模型输入尺寸:宽度 = 640, 高度 = 640
Original image shape: (398, 700)
Final letterboxed image shape: (640, 640, 3)
图像已保存为 det_result_picture.jpg
可视化看一下分割效果,保存名称是:det_result_picture.jpg
YOLO11相关文章推荐:
一篇文章快速认识YOLO11 | 关键改进点 | 安装使用 | 模型训练和推理-CSDN博客
一篇文章快速认识 YOLO11 | 实例分割 | 模型训练 | 自定义数据集-CSDN博客
YOLO11模型推理 | 目标检测与跟踪 | 实例分割 | 关键点估计 | OBB旋转目标检测-CSDN博客
YOLO11模型训练 | 目标检测与跟踪 | 实例分割 | 关键点姿态估计-CSDN博客
YOLO11 实例分割 | 自动标注 | 预标注 | 标签格式转换 | 手动校正标签-CSDN博客
YOLO11 实例分割 | 导出ONNX模型 | ONNX模型推理-CSDN博客
分享完成,欢迎大家多多点赞和收藏,谢谢~
相关文章:

YOLO11 目标检测 | 导出ONNX模型 | ONNX模型推理
本文分享YOLO11中,从xxx.pt权重文件转为.onnx文件,然后使用.onnx文件,进行目标检测任务的模型推理。 用ONNX模型推理,便于算法到开发板或芯片的部署。 备注:本文是使用Python,编写ONNX模型推理代码的 目…...
PostgreSQL DBA月度检查列表
为了确保数据库系统能够稳定高效运行,DBA 需要定期对数据库进行检查和维护,这是一项非常具有挑战性的工作。 本文给大家推荐一个 PostgreSQL DBA 月度性能检查列表,遵循以下指导原则可以帮助我们实现一个高可用、高性能、低成本、可扩展的数…...
驱动开发系列12 - Linux 编译内核模块的Makefile解释
一:内核模块Makefile #这一行定义了要编译的内核模块目标文件。obj-m表示目标模块对象文件(.o文件), #并指定了两个模块源文件:helloworld-params.c 和 helloworld.c。最终会生成这 #这两个.c文件的.o对象文件。 obj-m := helloworld-params.o helloworld.o#这行定义了内核…...

用js+css实现圆环型的进度条——js+css基础积累
如果用jscss实现圆环型的进度条: 直接上代码: <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta http-equiv"X-UA-Compatible" content"IEedge" /><met…...
TDengine 与北微传感达成合作,解决传统数据库性能瓶颈
在当今物联网(IoT)快速发展的背景下,传感器技术已成为各个行业数字化转型的关键组成部分。随着设备数量的激增和数据生成速度的加快,如何高效地管理和分析这些数据,成为企业实现智能化运营的重要挑战。尤其是在惯性传感…...

通过Python爬虫获取商品销量数据,轻松掌握市场动态
为什么选择Python爬虫? 简洁易用:Python语言具有简洁的语法和丰富的库,使得编写爬虫变得简单高效。强大的库支持:Python拥有强大的爬虫框架(如Scrapy、BeautifulSoup、Requests等),可以快速实现…...

学习虚幻C++开发日志——TSet
TSet 官方文档:虚幻引擎中的Set容器 | 虚幻引擎 5.5 文档 | Epic Developer Community (epicgames.com) TSet 是通过对元素求值的可覆盖函数,使用数据值本身作为键,而不是将数据值与独立的键相关联。 默认情况下,TSet 不支持重…...
面向对象进阶(下)(JAVA笔记第二十二期)
p.s.这是萌新自己自学总结的笔记,如果想学习得更透彻的话还是请去看大佬的讲解 目录 抽象方法和抽象类抽象方法定义格式抽象类定义格式抽象方法和抽象类注意事项 接口接口的定义接口中成员变量的特点接口中没有构造方法接口中成员方法的特点在接口中定义具有方法体…...

通信协议——UART
目录 基础概念串行&并行串行的优缺点 单工&双工 UART基本概念时序图思考:接收方如何确定01和0011 基础概念 串行&并行 串行为8车道,并行为1车道 串行的优缺点 通行速度快浪费资源布线复杂线与线之间存在干扰 单工&双工 单工…...
最优阵列处理技术(七)-谱加权
阵列的加权技术等价于时间序列谱分析中的加窗或锐化技术。在加权过程中,需要考虑的是如何降低旁瓣并使主波束宽度的增长最小。 首先需要明确的是,在 u u u空间下的波束方向图为 B u ( u ) =...

Java | Leetcode Java题解之第486题预测赢家
题目: 题解: class Solution {public boolean PredictTheWinner(int[] nums) {int length nums.length;int[] dp new int[length];for (int i 0; i < length; i) {dp[i] nums[i];}for (int i length - 2; i > 0; i--) {for (int j i 1; j …...
leetcode动态规划(十五)-完全背包
题目 leetcode上没有纯完全背包题目,可以看卡码网上的题目 完全背包 思路 有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品都有无限个(也就是可以放入背包多次)ÿ…...

AI视听新体验!浙大阿里提出视频到音乐生成模型MuVi:可解决语义对齐和节奏同步问题
MuVi旨在解决视频到音乐生成(V2M)中的语义对齐和节奏同步问题。 MuVi通过专门设计的视觉适配器分析视频内容,以提取上下文 和时间相关的特征,这些特征用于生成与视频的情感、主题及其节奏和节拍相匹配的音乐。MuVi在音频质量和时间同步方面表现优于现有基线方法,并展示了其在风…...

对比两个el-table,差异数据突显标记
前言 在数据分析和数据处理的过程中,经常需要对比两个数据集,以便发现其中的差异和变化。本文将介绍如何使用 el-table 组件来对比两个数据集,并通过差异数据的突显标记,帮助用户更直观地理解数据的变化。 cell-style 属性 其实利…...
调研funasr时间戳返回时间坐标效果可用性
# 背景 : 分析funasr识别结果中每个中文字的时间戳偏差情况 1.评价指标: ①偏差公式: A=标注字的时间戳(帧长区间) B=识别字的时间戳(帧长区间) 偏差=(AB的区间并集-AB的区间交际) 偏差百分比=(AB的区间并集-AB的区间交际)/(A的帧长) def calculate_bias(la…...
Tomcat默认配置整理
Connector: 处理请求的具体配置 Tomcat的连接等待队列长度,默认是100 Tomcat的最大连接数,默认是8192 Tomcat的最小工作线程数,默认是10 Tomcat的最大线程数,默认是200 Tomcat的连接超时时间,默认是20s Server port…...
深入理解Rust中的指针:裸指针 智能指针
Rust是一种注重安全性的系统编程语言,它通过所有权、借用和生命周期等机制来保证内存安全。在Rust中,指针的使用是小心翼翼的,因为指针操作是导致内存错误的主要原因之一。然而,指针在处理底层数据和性能优化时又是必不可少的。本…...

物联网实训项目:绿色家居套件
1、基本介绍 绿色家居通过物联网技术将家中的各种设备连接到一起,提供家电控制、照明控制、电话远程控制、室内外遥控、防盗报警、环境监测、暖通控制、红外转发以及可编程定时控制等多种功能和手段。绿色家居提供全方位的信息交互功能,甚至为各种能源费…...
缓存雪崩是什么
背景 Redis的缓存雪崩是指在某一时间段内,大量缓存数据同时失效,导致大量请求直接打到数据库上,造成数据库压力激增,甚至可能导致数据库宕机。这种情况类似于雪崩效应,突然的大量请求涌入数据库,系统无法承…...

【格物刊】龙信刊物已上新
文章关键词:电子数据取证、电子物证、手机取证、介质取证 深藏注册表的秘密:一次揭开金融阴谋的成功取证 一场看似无懈可击的金融操作,背后是否隐藏着阴谋?执法部门接到举报,指控几名金融机构的高层管理人员涉嫌利用…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...

Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)
前言: 最近在做行为检测相关的模型,用的是时空图卷积网络(STGCN),但原有kinetic-400数据集数据质量较低,需要进行细粒度的标注,同时粗略搜了下已有开源工具基本都集中于图像分割这块,…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...