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

3D点云目标检测——KITTI数据集读取与处理

一、 数据基本情况

KITTI数据集是由德国卡尔斯鲁厄理工学院和丰田美国技术研究院联合创建的一个大规模自动驾驶场景下的计算机视觉算法评测数据集。以下是关于它的详细介绍:

  1. 数据集背景:为评估自动驾驶中计算机视觉算法的性能而设计。自动驾驶汽车需在复杂道路环境中准确识别、跟踪和预测其他车辆、行人等交通参与者的行为,KITTI数据集就是为提供这样一个基准测试平台而产生的。
  2. 数据采集:使用安装在改装丰田普锐斯车上的两台彩色相机、两台灰度相机、一个3D激光扫描仪和一个高精度GPS/IMU系统,在德国卡尔斯鲁厄的市区、乡村和高速公路等不同环境下行驶6小时采集数据。
  3. 数据内容:包含大量图像序列及对应的3D物体标注信息,标注信息有物体的位置、大小、方向及类别等,还提供了激光雷达扫描得到的点云数据。
  4. 数据标注:每个物体都被仔细标注,标注信息包括边界框、3D尺寸、方向角、截断程度以及遮挡程度等。
  5. 应用场景:主要用于评估自动驾驶中的目标检测、目标跟踪、3D重建、场景理解等算法的性能,也可用于研究计算机视觉、机器学习、模式识别等领域的其他问题。
  6. 评估指标:提供了准确率、召回率、F1分数等一套评估指标,帮助研究人员了解算法表现并进行比较。
  7. 数据集影响:自发布以来,已成为自动驾驶和计算机视觉领域的重要基准测试平台,推动了相关算法发展,促进了学术界和工业界的合作与交流,为自动驾驶技术的实际应用奠定了基础。

KITTI 数据集采集自德国卡尔斯鲁厄市,涵盖了市区、郊区、高速公路等多种交通场景。数据采集时间为 2011 年 09 月 26 日、28 日、29 日、30 日及 10 月 03 日的白天。

KITTI 数据采集平台如下图所示:

该平台包含以下设备:

  • 2 个 140 万像素的黑白相机
  • 2 个 140 万像素的彩色相机
  • 4 个爱特蒙特光学镜头
  • 1 个 64 线 Velodyne 3D 激光扫描仪
  • 1 个 OXTS RT3003 惯导系统

从上图可以看出:

  • 相机的坐标系中,Z 轴朝前,Y 轴朝下,整个坐标系为右手坐标系。
  • 激光雷达的 X 轴朝向正前方,Z 轴竖直向上,Y 轴根据右手定则确定。
  • IMU/GPS 系统的坐标系朝向与激光雷达一致。

总结来说,KITTI 数据集由 4 个相机、1 个激光雷达、1 个 IMU/GPS 惯导系统共同组成。我们需要厘清这 6 个传感器之间的坐标系关系和时间同步信息。

关于传感器的尺寸参数可以参考下图:

[date]-drive-sync-[sequence] 目录下存放了 6 个传感器对应的采集数据文件夹,分别为:

- image_00
- image_01
- image_02
- image_03
- oxts
- velodyne-points
  • 时间戳:在 velodyne-points 文件夹下有三个时间戳文件:
    • timestamps_start.txt:激光扫描仪一周开始扫描的时间。
    • timestamps_end.txt:激光扫描仪一周扫描结束的时间。
    • timestamps.txt:激光扫描到正前方触发相机拍照的时间。
  • 图像数据
    • 图像是裁剪掉了引擎盖和天空之后的图像。
    • 图像是去畸变之后的数据。
  • OXTS 数据:每一帧存储了包括经纬度、速度、加速度等 30 个不同的字段值。
  • 雷达数据
    • 浮点数的二进制文件,每个点由 4 个浮点数组成,分别为雷达坐标系下的 x,y,z 坐标和激光的反射强度 r
    • 每扫描一次,大约得到 120000 个 3D 点。
    • 激光雷达绕垂直轴逆时针转动。

传感器标定及时间同步

整个系统以激光雷达旋转一周为 1 帧。激光雷达旋转到某个特定位置时,通过一个弹簧片的物理接触触发相机拍照。IMU 无法通过这种触发方式采集数据,但 IMU 数据采集的频率达到了 100Hz,通过对 IMU 采集的数据记录时间戳,选择与相机采集时间最接近的作为当前帧的数据,最大时间误差为 5ms。

相机标定:相机内外参标定使用的方法是 A toolbox for automatic calibration of range and camera sensors using a single shot。所有相机的中心都已对齐,即它们都在相同的 XY 平面上,这便于图像的校正(去除天空和引擎盖)。

每天开始采集数据前,都会对整个数据采集系统进行标定,以避免传感器间位置的偏移。

在每天的 date_calib.zip 文件夹下,有 3 个文本文件,用于记录传感器之间的坐标转换关系等信息。

二、 用于 3D 目标检测

最初,KITTI 数据集支持的任务包括双目、光流和里程计。后来,陆续支持了深度估计、2D 目标检测、3D 目标检测、BEV 目标检测、语义分割、实例分割、多目标追踪等任务。

在目标检测中,定义的类别有 8 种:Car/Van/Truck/Pedestrian/Person_sitting/Cyclist/Tram/Misc(其他)

对 3D 对象的标注是在激光雷达坐标系下进行的。需要注意的是,目前 3D 目标检测只由检测框中心点坐标 xyz、检测框的长宽高 length/width/height 和检测框的偏航角 yaw 这 7 个自由度组成。

在这里插入图片描述

不过这里有一个容易引起歧义的问题:length/width/height 分别对应 xyz 的哪个轴呢?从下图可以看出,length 对应 dxwidth 对应 dyheight 对应 dz。整个 3D 框的标注在激光雷达坐标系下。

KITTI 3D 目标检测数据集包括 7481 张训练数据和 7518 张测试数据。尽管 KITTI 数据集中包含了标注了 8 种对象,但只有 Car/Pedestrian 标注得比较充分,KITTI 官方用来评估算法。在 KITTI BenchMark 中使用的 3D 检测框类别有 3 个,分别是 Car/Pedestrian/Cyclist

下载的 3D 目标检测数据集包含以下文件夹:

  • image_02:左目彩色 png 格式的图像。
  • label_02:左目彩色图像中标注的对象标签。
  • calib:传感器之间的坐标转换关系。
  • velodyne:激光点云数据。
  • plane:在激光坐标系下,路面的平面方程。

标签文件中每一行内容如下:

Pedestrian 0.00 0 -0.20 712.40 143.00 810.73 307.92 1.89 0.48 1.20 1.84 1.47 8.41 0.01

包含的字段有:

  • type:目标的类型,如 Car/Van 等,1 个字段。
  • truncated:浮点数 0-1,目标对象离开相机视野的比例,1 个字段。
  • occluded:整数 0,1,2,30 表示全部可见,1 表示部分遮挡,2 表示大部分未遮挡,3 表示未知,1 个字段。
  • alpha:对象的观测角,1 个字段。
  • bbox:2D 检测框像素坐标,x1,y1,x2,y2,4 个字段。
  • dimensions:3D 对象的尺寸,height,width,length,单位是米,3 个字段。
  • location:3D 对象在相机坐标系下的中心坐标 xyz,单位是米。
  • rotation_yyaw 角,偏航角。
  • score:目标对象的评分,用来计算 ROC 曲线或 MAP。

相机坐标系中的点可以通过 calib 中的变换矩阵变换到图像像素坐标中。

rotation_yalpha 的区别在于:alpha 度量的是相机中心到对象中心的角度。rotation_y 度量的是对象绕相机坐标系 y 轴的转角 yaw。以汽车为例,当一辆车在相机坐标系下位于 x 轴方向时,其 rotation_y 角为零,无论这辆车在 x,z 平面的哪个位置。而对于 alpha 角来说,仅当汽车在相机坐标系下 z 轴上时,alpha 角为零,偏离 z 轴时,alpha 角都不为零。

将激光点云投影到左目彩色图像中可以使用的公式为:X = P2 * R0_rect * Tr_vel_to_cam * Y

其中,R0_rect 是 3x3 的校正矩阵,Tr_vel_to_cam 是 3x4 的雷达变换到相机坐标系下的变换矩阵。

三、代码实战

使用 open3d 读取点云

import numpy as np
import struct
import open3d as o3ddef convert_kitti_bin_to_pcd(binFilePath):size_float = 4list_pcd = []with open(binFilePath, "rb") as f:byte = f.read(size_float * 4)print(byte)while byte:x, y, z, intensity = struct.unpack("ffff", byte)list_pcd.append([x, y, z])byte = f.read(size_float * 4)np_pcd = np.asarray(list_pcd)pcd = o3d.geometry.PointCloud()pcd.points = o3d.utility.Vector3dVector(np_pcd)return pcdbs = "/xx/xx/data/code/mmdetection3d/demo/data/kitti/000008.bin"
pcds = convert_kitti_bin_to_pcd(bs)
o3d.visualization.draw_geometries([pcds])# save
o3d.io.write_point_cloud('000008.pcd', pcds, write_ascii=False, compressed=False, print_progress=False)

通过 numpy 读取:

def load_bin(bin_file):data = np.fromfile(bin_file, np.float32).reshape((-1, 4))data = data[:, :-1]pcd = o3d.geometry.PointCloud()pcd.points = o3d.utility.Vector3dVector(data)return pcd

上述代码可以读取并可视化点云数据,并将其保存为 pcd 格式的点云。

选取的 3D 目标检测任务数据集中的 training/image_02/000008.png,对应的标签文件为 000008.txt,内容如下:

Car 0.88 3 -0.69 0.00 192.37 402.31 374.00 1.60 1.57 3.23 -2.70 1.74 3.68 -1.29
Car 0.00 1 2.04 334.85 178.94 624.50 372.04 1.57 1.50 3.68 -1.17 1.65 7.86 1.90
Car 0.34 3 -1.84 937.29 197.39 1241.00 374.00 1.39 1.44 3.08 3.81 1.64 6.15 -1.31
Car 0.00 1 -1.33 597.59 176.18 720.90 261.14 1.47 1.60 3.66 1.07 1.55 14.44 -1.25
Car 0.00 0 1.74 741.18 168.83 792.25 208.43 1.70 1.63 4.08 7.24 1.55 33.20 1.95
Car 0.00 0 -1.65 884.52 178.31 956.41 240.18 1.59 1.59 2.47 8.48 1.75 19.96 -1.25

将其画在 000008.png 上的代码如下:

import cv2
img = cv2.imread(img_s)
with open(label_s) as f:lines = f.read().split("n")[:-1]
for item in lines:boxes = item.split()[4:8]boxes = [float(x) for x in boxes]bb = np.array(boxes, dtype=np.int32)cv2.rectangle(img, bb[:2], bb[-2:], (0,0,255), 1)
cv2.imwrite("/xx/xx/data/code/mmdetection3d/demo/data/kitti/08_res.png", img)

从图中可以看出,左下角两个检测框的边缘部分标注得并不理想。

对应的点云数据如下:

KITTI 3D 目标检测的数据标签给出的 3D 中心点的坐标是在左目彩色相机坐标系中。

使用 Open3D 可视化检测框的代码可以参考以下内容:

"""
from https://github.com/dtczhl/dtc-KITTI-For-
Beginners.git
"""
import matplotlib.pyplot as plt
import matplotlib.image as mping
import numpy as np
import os
import open3d as o3d
import open3d.visualization as o3d_vis
from shapely.geometry import Point
from shapely.geometry.polygon import PolygonMARKER_COLOR = {'Car': [1, 0, 0],               # red'DontCare': [0, 0, 0],          # black'Pedestrian': [0, 0, 1],        # blue'Van': [1, 1, 0],               # yellow'Cyclist': [1, 0, 1],           # magenta'Truck': [0, 1, 1],             # cyan'Misc': [0.5, 0, 0],            # maroon'Tram': [0, 0.5, 0],            # green'Person_sitting': [0, 0, 0.5]}  # navy# image border width
BOX_BORDER_WIDTH = 5# point size
POINT_SIZE = 0.005def show_object_in_image(img_filename, label_filename):img = mping.imread(img_filename)with open(label_filename) as f_label:lines = f_label.readlines()for line in lines:line = line.strip('n').split()left_pixel, top_pixel, right_pixel, bottom_pixel = [int(float(line[i])) for i in range(4, 8)]box_border_color = MARKER_COLOR[line[0]]for i in range(BOX_BORDER_WIDTH):img[top_pixel+i, left_pixel:right_pixel, :] = box_border_colorimg[bottom_pixel-i, left_pixel:right_pixel, :] = box_border_colorimg[top_pixel:bottom_pixel, left_pixel+i, :] = box_border_colorimg[top_pixel:bottom_pixel, right_pixel-i, :] = box_border_colorplt.imshow(img)plt.show()def show_object_in_point_cloud(point_cloud_filename, label_filename, calib_filename):pc_data = np.fromfile(point_cloud_filename, '<f4')  # little-endian float32pc_data = np.reshape(pc_data, (-1, 4))cloud = o3d.geometry.PointCloud()cloud.points = o3d.utility.Vector3dVector(pc_data[:,:-1])pc_color = np.ones((len(pc_data), 3))calib = load_kitti_calib(calib_filename)rot_axis = 2with open(label_filename) as f_label:lines = f_label.readlines()bboxes_3d = []for line in lines:line = line.strip('n').split()point_color = MARKER_COLOR[line[0]]veloc, dims, rz, box3d_corner = camera_coordinate_to_point_cloud(line[8:15], calib['Tr_velo_to_cam'])bboxes_3d.append(np.concatenate((veloc, dims, np.array([rz]))))bboxes_3d = np.array(bboxes_3d)print(bboxes_3d.shape)lines = []for i in range(len(bboxes_3d)):center = bboxes_3d[i, 0:3]dim = bboxes_3d[i, 3:6]yaw = np.zeros(3)yaw[rot_axis] = bboxes_3d[i, 6]rot_mat = o3d.geometry.get_rotation_matrix_from_xyz(yaw)# bottom center to gravity centercenter[rot_axis] += dim[rot_axis] / 2box3d = o3d.geometry.OrientedBoundingBox(center, rot_mat, dim)line_set = o3d.geometry.LineSet.create_from_oriented_bounding_box(box3d)line_set.paint_uniform_color(np.array(point_color) / 255.)lines.append(line_set)for i, v in enumerate(pc_data):if point_in_cube(v[:3], box3d_corner) is True:pc_color[i, :] = point_colorcloud.colors = o3d.utility.Vector3dVector(pc_color)o3d_vis.draw([*lines, cloud])def point_in_cube(point, cube):z_min = np.amin(cube[:, 2], 0)z_max = np.amax(cube[:, 2], 0)if point[2] > z_max or point[2] < z_min:return Falsepoint = Point(point[:2])polygon = Polygon(cube[:4, :2])return polygon.contains(point)def load_kitti_calib(calib_file):"""This script is copied from https://github.com/AI-liu/Complex-YOLO"""with open(calib_file) as f_calib:lines = f_calib.readlines()P0 = np.array(lines[0].strip('n').split()[1:], dtype=np.float32)P1 = np.array(lines[1].strip('n').split()[1:], dtype=np.float32)P2 = np.array(lines[2].strip('n').split()[1:], dtype=np.float32)P3 = np.array(lines[3].strip('n').split()[1:], dtype=np.float32)R0_rect = np.array(lines[4].strip('n').split()[1:], dtype=np.float32)Tr_velo_to_cam = np.array(lines[5].strip('n').split()[1:], dtype=np.float32)Tr_imu_to_velo = np.array(lines[6].strip('n').split()[1:], dtype=np.float32)return {'P0': P0, 'P1': P1, 'P2': P2, 'P3': P3, 'R0_rect': R0_rect,'Tr_velo_to_cam': Tr_velo_to_cam.reshape(3, 4),'Tr_imu_to_velo': Tr_imu_to_velo}def camera_coordinate_to_point_cloud(box3d, Tr):"""This script is copied from https://github.com/AI-liu/Complex-YOLO"""def project_cam2velo(cam, Tr):T = np.zeros([4, 4], dtype=np.float32)T[:3, :] = TrT[3, 3] = 1T_inv = np.linalg.inv(T)lidar_loc_ = np.dot(T_inv, cam)lidar_loc = lidar_loc_[:3]return lidar_loc.reshape(1, 3)def ry_to_rz(ry):angle = -ry - np.pi / 2if angle >= np.pi:angle -= np.piif angle < -np.pi:angle = 2 * np.pi + anglereturn angleh, w, l, tx, ty, tz, ry = [float(i) for i in box3d]cam = np.ones([4, 1])cam[0] = txcam[1] = tycam[2] = tzt_lidar = project_cam2velo(cam, Tr)Box = np.array([[-l / 2, -l / 2, l / 2, l / 2, -l / 2, -l / 2, l / 2, l / 2],[w / 2, -w / 2, -w / 2, w / 2, w / 2, -w / 2, -w / 2, w / 2],[0, 0, 0, 0, h, h, h, h]])rz = ry_to_rz(ry)rotMat = np.array([[np.cos(rz), -np.sin(rz), 0.0],[np.sin(rz), np.cos(rz), 0.0],[0.0, 0.0, 1.0]])velo_box = np.dot(rotMat, Box)cornerPosInVelo = velo_box + np.tile(t_lidar, (8, 1)).Tbox3d_corner = cornerPosInVelo.transpose()dims = np.array([l, w, h])# t_lidar: the x, y coordinator of the center of the object# box3d_corner: the 8 cornersprint(t_lidar.shape)return t_lidar.reshape(-1), dims, rz, box3d_corner.astype(np.float32)if __name__ == '__main__':# updatesROOT = "/media/lx/data/code/mmdetection3d/demo/data/kitti"IMG_DIR = f'{ROOT}/image_2'LABEL_DIR = f'{ROOT}/label_2'POINT_CLOUD_DIR = f'{ROOT}/velo'CALIB_DIR = f'{ROOT}/calib'# id for viewingfile_id = 8img_filename = os.path.join(IMG_DIR, '{0:06d}.png'.format(file_id))label_filename = os.path.join(LABEL_DIR, '{0:06d}.txt'.format(file_id))pc_filename = os.path.join(POINT_CLOUD_DIR, '{0:06d}.bin'.format(file_id))calib_filename = os.path.join(CALIB_DIR, '{0:06d}.txt'.format(file_id))# show object in imageshow_object_in_image(img_filename, label_filename)# show object in point cloudshow_object_in_point_cloud(pc_filename, label_filename, calib_filename)

可视化的结果如下:

以上内容对 KITTI 数据集用于 3D 目标检测任务的情况进行了基本介绍。后续在涉及多模态时,将补充如何结合 2D 检测框来完成目标的识别和定位。

相关文章:

3D点云目标检测——KITTI数据集读取与处理

一、 数据基本情况 KITTI数据集是由德国卡尔斯鲁厄理工学院和丰田美国技术研究院联合创建的一个大规模自动驾驶场景下的计算机视觉算法评测数据集。以下是关于它的详细介绍&#xff1a; 数据集背景&#xff1a;为评估自动驾驶中计算机视觉算法的性能而设计。自动驾驶汽车需在…...

【鸿蒙开发】Hi3861学习笔记- 外部中断

00. 目录 文章目录 00. 目录01. 概述02. EXTI相关API03. 硬件设计04. 软件设计05. 实验现象06. 附录 01. 概述 我们在做按键控制实验时&#xff0c;虽然能实现 IO 口输入功能&#xff0c;但代码是一直在检测 IO 输入口的变化&#xff0c;因此效率不高&#xff0c;特别是在一些…...

技术与情感交织的一生 (一)

目录 一条朋友圈 静默 至暗时刻 选择 成人高考 歇一下 一条朋友圈 大年初一是我合作伙伴的生日&#xff0c;我称呼他为老高&#xff0c;他发的朋友圈写到&#xff1a;“50岁了&#xff0c;留下的皆是珍贵回忆。” &#xff0c;看到留言的瞬间&#xff0c;只有一个感觉&a…...

30天学习Java第六天——Object类

Object类 java.lang.Object时所有类的超类。Java中所有类都实现了这个类中的方法。 toString方法 将Java对象转换成字符串的表示形式。 public String toString() {return getClass().getName() "" Integer.toHexString(hashCode()); }默认实现是&#xff1a;完…...

基于WebRTC与P2P技术,嵌入式视频通话EasyRTC实现智能硬件音视频交互,适配Linux、ARM、RTOS、LiteOS

EasyRTC不仅仅是一个连接工具&#xff0c;更是一个经过深度优化的通信桥梁。它在嵌入式设备上进行了特殊优化&#xff0c;通过轻量级SDK设计、内存和存储优化以及硬件加速支持&#xff0c;解决了传统WebRTC在嵌入式设备上的适配难题&#xff0c;显著节省了嵌入式设备的资源。 1…...

向量库集成指南

文章目录 向量库集成指南Chroma集成Pinecone集成MiLvus集成向量库集成指南 向量库是一种索引和存储向量嵌入以实现高效管理和快速检索的数据库。与单独的向量索引不同,像Pinecone这样的向量数据库提供了额外的功能,例如,索引管理、数据管理、元数据存储和过滤,以及水平扩展…...

深度研究deep-research优秀开源项目

原文链接:https://i68.ltd/notes/posts/20250305-deep-research2/ 港大开源AI科研神器AI-Researcher 项目仓库:GitHub - HKUDS/AI-Researcher: "AI-Researcher: Fully-Automated Scientific Discovery with LLM Agents" & "Open-Sourced Alternative to G…...

芯谷D8563TS:低功耗CMOS实时时钟/日历电路的优选方案

在电子设备中&#xff0c;实时时钟&#xff08;RTC&#xff09;电路对于提供准确的时间和日历信息至关重要。芯谷D8563TS作为一款低功耗的CMOS实时时钟/日历电路&#xff0c;以其丰富的功能、高精度和灵活的可编程性&#xff0c;成为众多嵌入式系统和电池供电设备中的理想选择。…...

FPGA中级项目1——IP核(ROM 与 RAM)

FPGA中级项目1——IP核&#xff08;ROM 与 RAM&#xff09; IP核简介 在 FPGA&#xff08;现场可编程门阵列&#xff09;设计中&#xff0c;IP 核&#xff08;Intellectual Property Core&#xff0c;知识产权核&#xff09;是预先设计好的、可重用的电路模块&#xff0c;用于实…...

Redis的持久化-AOF

1.AOF AOF&#xff08;Append Only File&#xff09;持久化&#xff1a;以独立日志的方式记录每次写命令&#xff0c;重启时在重新执行AOF文件中的命令达到恢复数据的目的。AOF的主要作用是解决了数据持久化的实时性&#xff0c;目前已经是Redis持久化的主流方式。理解掌握好A…...

jmeter-sample

jmeter-sample http request:接口测试常用请求参数ParametersBody DataFiles Upload jdbc request配置JDBC Connection Configuration创建JDBC Requst请求 http request:接口测试常用 请求参数 Parameters 常见于get请求&#xff0c;与拼在接口后面是一样的效果&#xff1a;如…...

2025-03-15 学习记录--C/C++-PTA 练习3-4 统计字符

合抱之木&#xff0c;生于毫末&#xff1b;九层之台&#xff0c;起于累土&#xff1b;千里之行&#xff0c;始于足下。&#x1f4aa;&#x1f3fb; 一、题目描述 ⭐️ 练习3-4 统计字符 本题要求编写程序&#xff0c;输入10个字符&#xff0c;统计其中英文字母、空格或回车、…...

编程自学指南:java程序设计开发,网络编程基础,TCP编程,UDP编程,HTTP客户端开发

编程自学指南&#xff1a;java程序设计开发&#xff0c;网络编程基础 学习目标&#xff1a; 理解网络协议&#xff08;TCP/IP、UDP&#xff09;的核心概念 掌握Socket编程实现客户端与服务端通信 能够通过多线程处理并发网络请求 开发简单的网络应用&#xff08;如聊天程序…...

C++ primer plus 类和对象

目录​​​​​​​ 前言 一 接口的设计 二 方法的设计和使用 三 构造函数 四 析构函数 五 析构函数和构造函数小结 总结 前言 前面已经描述了很多有关于类和对象的知识了&#xff0c;所以我们直接开始上手操作 一 接口的设计 首先我们要知道什么是接口 接口是一个…...

k8s 修改节点驱逐阈值

编辑 /var/lib/kubelet/config.yaml 文件 kind: KubeletConfiguration evictionHard:nodefs.available: "5%" # 降低磁盘压力触发阈值imagefs.available: "10%" # 调整容器镜像存储触发阈值nodefs.inodesFree: "3%...

HiPixel开源AI驱动的图像超分辨率的原生macOS 应用程序,使用 SwiftUI 构建并利用 Upscayl 强大的 AI 模型

一、软件介绍 文末提供程序和源码下载 HiPixel是一个开源程序基于SwiftUI构建的macOS原生应用程序&#xff0c;用于AI驱动的图像超分辨率&#xff0c;并利用Upscayl的强大AI模型。 二、软件特征 具有 SwiftUI 界面的原生 macOS 应用程序使用 AI 模型进行高质量图像放大通过 G…...

使用 .NET Core 实现 RabbitMQ 消息队列的详细教程

RabbitMQ 是一个流行的消息队列中间件&#xff0c;它允许应用程序通过异步消息的方式进行通信。RabbitMQ 支持 AMQP 协议&#xff0c;可以通过多种方式与应用程序交互。在本教程中&#xff0c;我们将深入探讨如何在 .NET Core 环境中使用 RabbitMQ 来实现消息队列。我们将学习如…...

深度学习——同一台电脑使用ssh配置多个github账号

如果一台电脑只有一个github账号&#xff0c;那么进行默认的ssh配置&#xff0c;通过git拉取和提交代码即可&#xff0c;但在实际的工作中&#xff0c;有时候需要在一台电脑登录多个github账号&#xff0c;将不同的项目代码提交到不同的github账号&#xff0c;这个时候如果仅仅…...

windows常用cmd命令

Windows 命令提示符&#xff08;CMD&#xff09;提供了许多实用的命令&#xff0c;用于管理文件、目录、网络、系统配置等。以下是一些常用的 CMD 命令及其用途&#xff1a; 文件和目录操作 dir: 列出当前目录下的文件和子目录。 dircd: 切换当前目录。 cd C:\Users cd .. # 返…...

C语言中的流程控制语句

一.流程控制语句的分类&#xff1a; 1.顺序结构 概念&#xff1a;从上往下依次执行&#xff0c;也是程序默认的执行顺序 2.分支结构 概念&#xff1a;程序在执行的过程中出现了岔路&#xff08;我们只能选择一条支线进行执行&#xff09; &#xff08;1&#xff09;.if语句…...

C语言【数据结构】:理解什么是数据结构和算法(启航)

引言 启航篇&#xff0c;理解什么是数据结构和算法 在 C 语言编程领域&#xff0c;数据结构和算法是两个核心且紧密相关的概念 一、数据结构 定义 数据结构是指相互之间存在一种或多种特定关系的数据元素的集合&#xff08;比如数组&#xff09;&#xff0c;它是组织和存储数…...

WebLogic XMLDecoder反序列化漏洞(CVE-2017-10271)深度解析与实战复现

0x00 漏洞概述 CVE-2017-10271 是Oracle WebLogic Server WLS Security组件中的远程代码执行漏洞。攻击者通过构造恶意XML请求&#xff0c;利用XMLDecoder反序列化机制绕过安全验证&#xff0c;最终实现服务器权限接管。 影响版本 WebLogic 10.3.6.0WebLogic 12.1.3.0WebLog…...

【动态规划篇】746.使用最小花费爬楼梯

746.使用最小花费爬楼梯 题目链接&#xff1a; 746.使用最小花费爬楼梯 题目叙述&#xff1a; 给你一个整数数组 cost &#xff0c;其中 cost[i] 是从楼梯第i个台阶向上爬需要支付的费用。一旦你支付此费用&#xff0c;即可选择向上爬一个或者两个台阶。 你可以选择从下标为 …...

类和对象:

1. const运算符重载&#xff1a; 1. const成员函数&#xff1a; 我们来看我们的下面的代码&#xff1a; 我们来看这个&#xff0c;我们的对象使用const进行修饰&#xff0c;然后我们对象d1调用我们的成员函数&#xff0c;然后我们取d1的地址然后传过去&#xff0c;这时候我们的…...

研究整除的性质——最大公约数(GCD)和最小公倍数(LCM)

最大公约数&#xff08;GCD&#xff09;和最小公倍数&#xff08;Least Common Multiple&#xff0c;LCM&#xff09;研究整除的性质&#xff0c;非常古老&#xff0c;在2000多年前就得到了很好的研究。由于简单易懂&#xff0c;有较广泛的应用&#xff0c;它们是竞赛中频繁出现…...

jenkins 配置邮件问题整理

版本&#xff1a;Jenkins 2.492.1 插件&#xff1a; A.jenkins自带的&#xff0c; B.安装功能强大的插件 配置流程&#xff1a; 1. jenkins->系统配置->Jenkins Location 此处的”系统管理员邮件地址“&#xff0c;是配置之后发件人的email。 2.配置系统自带的邮件A…...

FastAPI复杂查询终极指南:告别if-else的现代化过滤架构

title: FastAPI复杂查询终极指南:告别if-else的现代化过滤架构 date: 2025/3/14 updated: 2025/3/14 author: cmdragon excerpt: 本文系统讲解FastAPI中复杂查询条件的构建方法,涵盖参数验证、动态过滤、安全防护等18个核心技术点。通过引入策略模式、声明式编程等技术,彻…...

MySQL行列转化

初始化表结构&#xff1a; CREATE TABLE student_scores (student_id int NOT NULL,student_name varchar(50) DEFAULT NULL,math_score int DEFAULT NULL,english_score int DEFAULT NULL,science_score int DEFAULT NULL,PRIMARY KEY (student_id) ) ENGINEInnoDB DEFAULT C…...

施磊老师c++(六)

继承与多态-多重继承 文章目录 继承与多态-多重继承1.虚基类和虚继承本节内容 2.菱形继承---怎么解决?本节内容**面试问题: 怎么理解多重继承的?**---重点 3.c提供的四种类型转换本节内容 1.虚基类和虚继承 本节内容 多重继承? 代码复用, 一个派生类 有多个基类 抽象类—有…...

c++:AVL树

1.概念 由于二叉搜索树不能确保为近似完全二叉树的结构&#xff0c;节点相同的情况下&#xff0c;高度可能会很高&#xff0c;高度有可能会很低&#xff0c;所以搜索次数不能稳定维持在logn级别。我们在二叉搜索树的基础上进行平衡调整就可以控制搜索次数稳定在logn级别。 而AV…...

HTML编辑MP4保存名称

上图是HTML的界面&#xff0c;需要点击EDIT_MP4的选项&#xff0c;然后就出现文本框输入MP4名称。输入对应的MP4文件名称后&#xff0c;则点击Add_MP4按钮就可以把MP4的名称修改到json文件里面&#xff0c;json文件是network_detail.json文件。 HTML和CGI程序的交互 上图是htm…...

以太坊AI代理与PoS升级点燃3月市场热情,2025年能否再创新高?

币热网深度报道&#xff1a;以太坊AI代理与PoS升级引爆3月热潮&#xff0c;2025年能否再攀历史新高&#xff1f; 原文来源&#xff1a;币热网 - 区块链信息资讯平台 以太坊升级&#xff0c;市场热情高涨 近期&#xff0c;以太坊市场犹如被一股神秘力量点燃&#xff0c;掀起了…...

IDEA2024又一坑:连接Docker服务连不上,提示:Cannot run program “docker“: CreateProcess error=2

为新电脑安装了IDEA2024版&#xff0c;因为局域网中安装有Docker,所以这台电脑上没有安装&#xff0c;当运行时发现死活连不上Docker报&#xff1a;Cannot run program “docker“: CreateProcess error2 分析&#xff1a; Docker服务有问题 其它电脑都能连&#xff0c;排除 网…...

css基本功

为什么 ::first-letter 是伪元素&#xff1f; ::first-letter 的作用是选择并样式化元素的第一个字母&#xff0c;它创建了一个虚拟的元素来包裹这个字母&#xff0c;因此属于伪元素。 grid布局 案例一 <!DOCTYPE html> <html lang"zh-CN"><head&…...

ALSA vs OSS:Linux 音频架构的演变与核心区别

在 Linux 音频系统的发展过程中&#xff0c;OSS&#xff08;Open Sound System&#xff09; 和 ALSA&#xff08;Advanced Linux Sound Architecture&#xff09; 曾分别在不同阶段承担着音频管理的角色。OSS 是 Linux 早期的音频架构&#xff0c;而 ALSA 作为其继任者&#xf…...

双指针算法介绍+算法练习(2025)

一、介绍双指针算法 双指针&#xff08;或称为双索引&#xff09;算法是一种高效的算法技巧&#xff0c;常用于处理数组或链表等线性数据结构。它通过使用两个指针来遍历数据&#xff0c;从而减少时间复杂度&#xff0c;避免使用嵌套循环。双指针算法在解决诸如查找、排序、去重…...

第八节:红黑树(初阶)

【本节要点】 红黑树概念红黑树性质红黑树结点定义红黑树结构红黑树插入操作的分析 一、红黑树的概念与性质 1.1 红黑树的概念 红黑树 &#xff0c;是一种 二叉搜索树 &#xff0c;但 在每个结点上增加一个存储位表示结点的颜色&#xff0c;可以是 Red和 Black 。 通过对 任何…...

【C++标准库类型】深入理解C++中的using声明:从基础到实践

目录 一、using声明基础 1.1 基本语法形式 1.2 典型应用场景 1.3 作用域规则 二、关键注意事项 2.1 命名冲突处理 2.2 头文件使用规范 2.3 与typedef的对比 三、面向对象中的应用 3.1. 解除派生类名称隐藏&#xff08;核心应用&#xff09; 3.2. 构造函数继承&#…...

蓝桥杯2024年第十五届省赛真题-回文数组

题目描述 小蓝在无聊时随机生成了一个长度为 n 的整数数组&#xff0c;数组中的第 i 个数为ai&#xff0c;他觉得随机生成的数组不太美观&#xff0c;想把它变成回文数组&#xff0c;也是就对于任意i ∈ [1, n] 满足 ai an−i1 。小蓝一次操作可以指定相邻的两个数&#xff0c…...

多数元素——面试经典150题(力扣)

题目 给定一个大小为 n 的数组 nums &#xff0c;返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的&#xff0c;并且给定的数组总是存在多数元素。 示例 1&#xff1a; 输入&#xff1a;nums [3,2,3] 输出&#xff1a;3 …...

QT中委托QStyledItemDelegate的使用

目录 一、子类化委托 二、委托方法实现 1)createEditor 2)setEditorData 3)setModelData 4)updateEditorGeometry 三、委托使用 四、总结 Qt的数据容器控件采用模型/视图(model/view)架构设计。模型用于存放控件的数据,视图则用于显示编辑数据,而委托则是…...

android 调用wps打开文档并感知保存事件

需求场景 在项目开发中会碰到需要调用WPS打开Word,Excel,Ppt等Office系列文档的情况&#xff0c;网上目前少有正式介绍如何调用相关API打开文档&#xff0c;并实现文档编辑后回传给三方应用&#xff0c;本人在逛WPS社区时发现 解锁WPS二次开发新世界&#xff1a;Android开发用…...

前端 Webpack 面试题

1、什么是 Webpack?它有什么作用? Webpack 是一个前端资源打包工具,用于将 JavaScript、CSS、图片等项目资源进行模块化管理和打包。它能够将复杂的项目结构转化为浏览器友好的代码,提高前端项目的开发效率和性能。 模块打包:Webpack 将项目中的各个模块及依赖打包成一个…...

05延迟任务精准发布文章(redis实现延迟任务、分布式锁)

上架不代表发布(需要发布app端才会显示文章&#xff09; 1)文章定时发布 2)延迟任务概述 2.1)什么是延迟任务 定时任务&#xff1a;有固定周期的&#xff0c;有明确的触发时间 延迟队列&#xff1a;没有固定的开始时间&#xff0c;它常常是由一个事件触发的&#xff0c;而在…...

十六、从零搭建一个 Vue 3 后台管理系统:完整实战教程

Vue 3 作为当下最为流行的前端框架之一&#xff0c;凭借其简洁的 API 以及强大的性能&#xff0c;已然成为构建后台管理系统的首选工具。本文将一步一步地引导你从零开始搭建一个 Vue 3 后台管理系统&#xff0c;内容涵盖路由、权限管理、状态管理等核心功能&#xff0c;并且会…...

never_give_up

一个很有意思的题&#xff1a; never_give_up - Bugku CTF平台 注意到注释里面有1p.html&#xff0c;我们直接在源代码界面看&#xff0c;这样就不会跳转到它那个链接的&#xff1a; 然后解码可得&#xff1a; ";if(!$_GET[id]) {header(Location: hello.php?id1);exi…...

DeepSeek结合Mermaid绘图(流程图、时序图、类图、状态图、甘特图、饼图)转载

思维速览&#xff1a; 本文将详细介绍如何利用DeepSeek结合Mermaid语法绘制各类专业图表&#xff0c;帮助你提高工作效率和文档质量。 ▍DeepSeek入门使用请看&#xff1a;deepseek保姆级入门教程&#xff08;网页端使用 本地客户端部署 使用技巧&#xff09; DeepSeek官网…...

「基于大模型的智能客服系统」语义理解、上下文记忆与反馈机制设计

网罗开发 &#xff08;小红书、快手、视频号同名&#xff09; 大家好&#xff0c;我是 展菲&#xff0c;目前在上市企业从事人工智能项目研发管理工作&#xff0c;平时热衷于分享各种编程领域的软硬技能知识以及前沿技术&#xff0c;包括iOS、前端、Harmony OS、Java、Python等…...

【后端】【django】导出 API 文档的几种方法

在 Django 项目里&#xff0c;导出 API 文档是很常见的需求&#xff0c;一般可以借助第三方库来实现。 使用 drf-yasg 导出 Swagger/OpenAPI 格式文档 drf-yasg 是一个用于 Django REST framework 的工具&#xff0c;能够自动生成 Swagger 和 OpenAPI 格式的 API 文档。 步骤…...

【HarmonyOS Next之旅】DevEco Studio使用指南(二)

目录 1 -> 工程模板介绍 2 -> 创建一个新的工程 2.1 -> 创建和配置新工程 2.1.1 -> 创建HarmonyOS工程 2.2.2 -> 创建OpenHarmony工程 1 -> 工程模板介绍 DevEco Studio支持多种品类的应用/元服务开发&#xff0c;预置丰富的工程模板&#xff0c;可以根…...