位置: IT常识 - 正文

自动驾驶数据集(一):KITTI数据集介绍(自动驾驶数据集 mev)

发布时间:2024-01-17
自动驾驶数据集(一):KITTI数据集介绍

推荐整理分享自动驾驶数据集(一):KITTI数据集介绍(自动驾驶数据集 mev),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:自动驾驶数据集对比,自动驾驶数据集标注,自动驾驶数据集测试,自动驾驶数据集谷歌,自动驾驶数据集如何收集,自动驾驶数据集如何收集,自动驾驶数据集 yolo,自动驾驶数据集如何收集,内容如对您有帮助,希望把文章链接给更多的朋友!

如有错误,恳请指出。

文章目录0. 数据集下载1. 标注数据label_22. 校准数据calib3. 点云数据velodyne4. 图像数据image_20. 数据集下载

KITTI数据集的下载地址:https://www.cvlibs.net/datasets/kitti/eval_object.php?obj_benchmark=3d,下载以下四个部分即可: 上图红色框标记的为我们需要的数据,分别是彩色图像数据image_2(12GB)、点云数据velodyne(29GB)、相机矫正数据calib(16MB)、标签数据label_2(5MB)。其中彩色图像数据、点云数据、相机矫正数据均包含training(7481)和testing(7518)两个部分,标签数据只有training数据。

KITTI数据下载完成后的目录结构如下所示:测试集没有label_2数据

└── KITTI ├── training <-- training data | ├── image_2 | ├── label_2 | ├── velodyne | └── calib └── testing <--- testing data | ├── image_2 | ├── velodyne | └── calib1. 标注数据label_2

KITTI数据集中的标注文件以txt格式保存,每个标注文件中包含16个属性,即16列。但我们只能够看到前15列数据,因为第16列是针对测试场景下目标的置信度得分,也可以认为训练场景中得分全部为1但是没有专门标注出来。

下面以KITTI中的"000100.txt"文件为例,包含内容如下所示:

Van 0.63 0 -0.90 0.00 58.65 320.90 374.00 2.46 2.03 5.35 -5.18 1.69 7.24 -1.51Cyclist 0.00 0 -1.58 684.31 165.66 710.23 242.31 1.82 0.59 1.89 2.13 1.66 18.06 -1.47Pedestrian 0.00 0 0.84 359.32 182.26 400.32 285.85 1.57 0.52 0.62 -3.63 1.72 11.35 0.54Car 0.00 2 -2.46 19.88 179.87 206.64 238.00 1.44 1.62 3.91 -13.04 1.64 18.98 -3.05DontCare -1 -1 -10 650.19 158.35 666.90 192.77 -1 -1 -1 -1000 -1000 -1000 -10

每一行代表一个object,每一行都有16列分别表示不同的含义,具体如下:

第1列(字符串):代表物体类别(type) 目标类比别(type),共有8种类别,分别是Car、Van、Truck、Pedestrian、Person_sitting、Cyclist、Tram、Misc或’DontCare。DontCare表示某些区域是有目标的,但是由于一些原因没有做标注,比如距离激光雷达过远。但实际算法可能会检测到该目标,但没有标注,这样会被当作false positive (FP)。这是不合理的。用DontCare标注后,评估时将会自动忽略这个区域的预测结果,相当于没有检测到目标,这样就不会增加FP的数量了。此外,在 2D 与 3D Detection Benchmark 中只针对 Car、Pedestrain、Cyclist 这三类。第2列(浮点数):代表物体是否被截断(truncated) 数值在0(非截断)到1(截断)之间浮动,数字表示指离开图像边界对象的程度。第3列(整数):代表物体是否被遮挡(occluded) 整数0、1、2、3分别表示被遮挡的程度。第4列(弧度数):物体的观察角度(alpha) 取值范围为:-pi ~ pi(单位:rad),是在相机坐标系下,以相机原点为中心,相机原点到物体中心的连线为半径,将物体绕相机y轴旋转至相机z轴,此时物体方向与相机x轴的夹角。这相当于将物体中心旋转到正前方后,计算其与车身方向的夹角。第5~8列(浮点数):物体的2D边界框大小(bbox) 四个数分别是xmin、ymin、xmax、ymax(单位:pixel),表示2维边界框的左上角和右下角的坐标。第9~11列(浮点数):3D物体的尺寸(dimensions)分别是高、宽、长(单位:米)第12-14列(整数):3D物体的位置(location)分别是x、y、z(单位:米),特别注意的是,这里的xyz是在相机坐标系下3D物体的中心点位置。第15列(弧度数):旋转角(rotation_y),取值范围为(-pi, pi)。表示车体朝向,绕相机坐标系y轴的弧度值,即物体前进方向与相机坐标系x轴的夹角。rolation_y与alpha的关系为:alpha=rotation_y - theta,theta为物体中心与车体前进方向上的夹角。alpha的效果是从正前方看目标行驶方向与车身方向的夹角,如果物体不在正前方,那么旋转物体或者坐标系使得能从正前方看到目标,旋转的角度为theta。如下图所示:

关于label文件的理解还可以参考如下代码:

class Object3d(object): """ 3d object label """ def __init__(self, label_file_line): data = label_file_line.split(" ") data[1:] = [float(x) for x in data[1:]] # extract label, truncation, occlusion self.type = data[0] # 'Car', 'Pedestrian', ... self.truncation = data[1] # truncated pixel ratio [0..1] self.occlusion = int(data[2]) # 0=visible, 1=partly occluded, 2=fully occluded, 3=unknown self.alpha = data[3] # object observation angle [-pi..pi] # extract 2d bounding box in 0-based coordinates self.xmin = data[4] # left self.ymin = data[5] # top self.xmax = data[6] # right self.ymax = data[7] # bottom self.box2d = np.array([self.xmin, self.ymin, self.xmax, self.ymax]) # extract 3d bounding box information self.h = data[8] # box height self.w = data[9] # box width self.l = data[10] # box length (in meters) self.t = (data[11], data[12], data[13]) # location (x,y,z) in camera coord. self.ry = data[14] # yaw angle (around Y-axis in camera coordinates) [-pi..pi] # 估算困难等级 def estimate_diffculty(self): """ Function that estimate difficulty to detect the object as defined in kitti website""" # height of the bounding box bb_height = np.abs(self.xmax - self.xmin) if bb_height >= 40 and self.occlusion == 0 and self.truncation <= 0.15: return "Easy" elif bb_height >= 25 and self.occlusion in [0, 1] and self.truncation <= 0.30: return "Moderate" elif bb_height >= 25 and self.occlusion in [0, 1, 2] and self.truncation <= 0.50: return "Hard" else: return "Unknown" # 打印当前标注对象的相关信息 def print_object(self): print('Type, truncation, occlusion, alpha: %s, %d, %d, %f' % \ (self.type, self.truncation, self.occlusion, self.alpha)) print('2d bbox (x0,y0,x1,y1): %f, %f, %f, %f' % \ (self.xmin, self.ymin, self.xmax, self.ymax)) print('3d bbox h,w,l: %f, %f, %f' % \ (self.h, self.w, self.l)) print('3d bbox location, ry: (%f, %f, %f), %f' % \ (self.t[0],self.t[1],self.t[2],self.ry))2. 校准数据calib

以训练文件中的000000.txt标定校准文件为例,其内容如下图所示。

P0: 7.070493000000e+02 0.000000000000e+00 6.040814000000e+02 0.000000000000e+00 0.000000000000e+00 7.070493000000e+02 1.805066000000e+02 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 1.000000000000e+00 0.000000000000e+00P1: 7.070493000000e+02 0.000000000000e+00 6.040814000000e+02 -3.797842000000e+02 0.000000000000e+00 7.070493000000e+02 1.805066000000e+02 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 1.000000000000e+00 0.000000000000e+00P2: 7.070493000000e+02 0.000000000000e+00 6.040814000000e+02 4.575831000000e+01 0.000000000000e+00 7.070493000000e+02 1.805066000000e+02 -3.454157000000e-01 0.000000000000e+00 0.000000000000e+00 1.000000000000e+00 4.981016000000e-03P3: 7.070493000000e+02 0.000000000000e+00 6.040814000000e+02 -3.341081000000e+02 0.000000000000e+00 7.070493000000e+02 1.805066000000e+02 2.330660000000e+00 0.000000000000e+00 0.000000000000e+00 1.000000000000e+00 3.201153000000e-03R0_rect: 9.999128000000e-01 1.009263000000e-02 -8.511932000000e-03 -1.012729000000e-02 9.999406000000e-01 -4.037671000000e-03 8.470675000000e-03 4.123522000000e-03 9.999556000000e-01Tr_velo_to_cam: 6.927964000000e-03 -9.999722000000e-01 -2.757829000000e-03 -2.457729000000e-02 -1.162982000000e-03 2.749836000000e-03 -9.999955000000e-01 -6.127237000000e-02 9.999753000000e-01 6.931141000000e-03 -1.143899000000e-03 -3.321029000000e-01Tr_imu_to_velo: 9.999976000000e-01 7.553071000000e-04 -2.035826000000e-03 -8.086759000000e-01 -7.854027000000e-04 9.998898000000e-01 -1.482298000000e-02 3.195559000000e-01 2.024406000000e-03 1.482454000000e-02 9.998881000000e-01 -7.997231000000e-01

其中,P0、1、2、3分别代表左边灰度相机、右边灰度相机、左边彩色相机和右边彩色相机。

1)内参矩阵 P0-P3分别表示4个相机的内参矩阵,或投影矩阵, 大小为 3x4。相机内参矩阵是为了计算点云空间位置坐标在相机坐标系下的坐标,即把点云坐标投影到相机坐标系。将相机的内参矩阵乘以点云在世界坐标系中的坐标即可得到点云在相机坐标系中的坐标。

如果需要进一步将点云在相机坐标系下的坐标投影到像平面,还需要除以Z值,以及内参矩阵的推导请参考:处理点云数据(五):坐标系的转换

2)外参矩阵 根据上述介绍,我们知道存在三种坐标系世界坐标系、相机坐标系、激光雷达坐标系。世界坐标系反映了物体的真实位置坐标,也是作为相机坐标系和激光雷达坐标系之间相互变换的过渡坐标系。

点云位置坐标投影到相机坐标系前,需要转换到世界坐标系下,对应的矩阵为外参矩阵。外参矩阵为Tr_velo_to_cam ,大小为3x4,包含了旋转矩阵 R 和 平移向量 T。将相机的外参矩阵乘以点云坐标即可得到点云在世界坐标系中的坐标。

自动驾驶数据集(一):KITTI数据集介绍(自动驾驶数据集 mev)

3)R0校准矩阵 R0_rect 为0号相机的修正矩阵,大小为3x3,目的是为了使4个相机成像达到共面的效果,保证4个相机光心在同一个xoy平面上。在进行外参矩阵变化之后,需要于R0_rect相乘得到相机坐标系下的坐标。

4)点云坐标到相机坐标 综上所述,点云坐标在相机坐标系中的坐标等于:内参矩阵 * R0校准矩阵 * 外参矩阵 * 点云坐标 即:P * R0_rect *Tr_velo_to_cam * x

例如,要将Velodyne激光雷达坐标系中的点x投影到左侧的彩色图像中y,使用公式: y = P2 * R0_rect *Tr_velo_to_cam * x

当计算出z<0的时候表明该点在相机的后面 。按照上述过程得到的结果是点云在相机坐标系中的坐标,如果需要将点云坐标投影到像平面还需要除以Z。

因为最后的转换结果如下,详细见参考资料3.

坐标系之间的转换代码:

class Calibration(object): def __init__(self, calib_filepath, from_video=False): if from_video: calibs = self.read_calib_from_video(calib_filepath) else: calibs = self.read_calib_file(calib_filepath) # Projection matrix from rect camera coord to image2 coord self.P = calibs["P2"] self.P = np.reshape(self.P, [3, 4]) # Rigid transform from Velodyne coord to reference camera coord self.V2C = calibs["Tr_velo_to_cam"] self.V2C = np.reshape(self.V2C, [3, 4]) self.C2V = inverse_rigid_trans(self.V2C) # Rotation from reference camera coord to rect camera coord self.R0 = calibs["R0_rect"] self.R0 = np.reshape(self.R0, [3, 3]) # Camera intrinsics and extrinsics self.c_u = self.P[0, 2] self.c_v = self.P[1, 2] self.f_u = self.P[0, 0] self.f_v = self.P[1, 1] self.b_x = self.P[0, 3] / (-self.f_u) # relative self.b_y = self.P[1, 3] / (-self.f_v) ...... def cart2hom(self, pts_3d): """ Input: nx3 points in Cartesian Oupput: nx4 points in Homogeneous by pending 1 """ n = pts_3d.shape[0] pts_3d_hom = np.hstack((pts_3d, np.ones((n, 1)))) return pts_3d_hom # =========================== # ------- 3d to 3d ---------- # =========================== def project_velo_to_ref(self, pts_3d_velo): pts_3d_velo = self.cart2hom(pts_3d_velo) # nx4 return np.dot(pts_3d_velo, np.transpose(self.V2C)) def project_ref_to_velo(self, pts_3d_ref): pts_3d_ref = self.cart2hom(pts_3d_ref) # nx4 return np.dot(pts_3d_ref, np.transpose(self.C2V)) def project_rect_to_ref(self, pts_3d_rect): """ Input and Output are nx3 points """ return np.transpose(np.dot(np.linalg.inv(self.R0), np.transpose(pts_3d_rect))) def project_ref_to_rect(self, pts_3d_ref): """ Input and Output are nx3 points """ return np.transpose(np.dot(self.R0, np.transpose(pts_3d_ref))) def project_rect_to_velo(self, pts_3d_rect): """ Input: nx3 points in rect camera coord. Output: nx3 points in velodyne coord. """ pts_3d_ref = self.project_rect_to_ref(pts_3d_rect) return self.project_ref_to_velo(pts_3d_ref) def project_velo_to_rect(self, pts_3d_velo): pts_3d_ref = self.project_velo_to_ref(pts_3d_velo) return self.project_ref_to_rect(pts_3d_ref) # =========================== # ------- 3d to 2d ---------- # =========================== def project_rect_to_image(self, pts_3d_rect): """ Input: nx3 points in rect camera coord. Output: nx2 points in image2 coord. """ pts_3d_rect = self.cart2hom(pts_3d_rect) # 增加第四列(全为1) pts_2d = np.dot(pts_3d_rect, np.transpose(self.P)) # nx3 pts_2d[:, 0] /= pts_2d[:, 2] # 如果需要将点云坐标投影到像平面还需要除以Z pts_2d[:, 1] /= pts_2d[:, 2] return pts_2d[:, 0:2] def project_velo_to_image(self, pts_3d_velo): """ Input: nx3 points in velodyne coord. Output: nx2 points in image2 coord. """ pts_3d_rect = self.project_velo_to_rect(pts_3d_velo) return self.project_rect_to_image(pts_3d_rect) # =========================== # ------- 2d to 3d ---------- # =========================== def project_image_to_rect(self, uv_depth): """ Input: nx3 first two channels are uv, 3rd channel is depth in rect camera coord. Output: nx3 points in rect camera coord. """ n = uv_depth.shape[0] x = ((uv_depth[:, 0] - self.c_u) * uv_depth[:, 2]) / self.f_u + self.b_x y = ((uv_depth[:, 1] - self.c_v) * uv_depth[:, 2]) / self.f_v + self.b_y pts_3d_rect = np.zeros((n, 3)) pts_3d_rect[:, 0] = x pts_3d_rect[:, 1] = y pts_3d_rect[:, 2] = uv_depth[:, 2] return pts_3d_rect def project_image_to_velo(self, uv_depth): pts_3d_rect = self.project_image_to_rect(uv_depth) return self.project_rect_to_velo(pts_3d_rect) ......3. 点云数据velodyne

这里KITTI的点云数据是bin文件格式的,在之前的笔记介绍到bin点云文件可以进行如下进行读取:

kitti_file = r'E:\Study\Machine Learning\Dataset3d\kitti\training\velodyne\000100.bin'points = np.fromfile(file=kitti_file, dtype=np.float32, count=-1).reshape([-1, 4])

bin文件的存储方式是以二进制形式存储,这带来的好处是读写的速度快,精度不丢失。与txt文件相同,其没有文件的描述信息,只包含点云数据,没有文件的说明部分。但是,txt文件按行存储点的信息,而bin则是将全部数据合并为一个序列,也可以理解为一行。也就是说,读取一个bin文件的输出是一个长串的序列信息,一般需要将其reshape一下,每4个数据为一个点云数据,所以需要reshape成N行4列。

简单的,可以通过一下代码对点云进行可视化:

def viz_mayavi(points, vals="distance"): x = points[:, 0] # x position of point y = points[:, 1] # y position of point z = points[:, 2] # z position of point fig = mlab.figure(bgcolor=(0, 0, 0), size=(640, 360)) mlab.points3d(x, y, z, z, # Values used for Color mode="point", colormap='spectral', # 'bone', 'copper', 'gnuplot' # color=(0, 1, 0), # Used a fixed (r,g,b) instead figure=fig, )4. 图像数据image_2

对于这部分数据就没啥可以介绍的,就是存放图像的,可以更具标注文件在图像上对标注框进行展现。

参考资料:

1. 【KITTI】KITTI数据集简介(二) — 标注数据label_2

2. KITTI】KITTI数据集简介(四) — 标定校准数据calib

3. 处理点云数据(五):坐标系的转换

4. kitti可视化github项目:kitti_object_vis

5. kitti数据集在3D目标检测中的入门

6. Open3d系列 | 1. Open3d实现点云数据读写、点云配准、点云法向量计算

本文链接地址:https://www.jiuchutong.com/zhishi/299568.html 转载请保留说明!

上一篇:for of 和 for in 的区别(for of 与for in)

下一篇:线性判别分析(LDA)详解(线性判别分析LDA医学)

  • APP快速运营推广,绝不可放过新媒体渠道运营(app运营推广计划方案)

    APP快速运营推广,绝不可放过新媒体渠道运营(app运营推广计划方案)

  • vivox70pro+怎么设置语音助手(vivox70pro怎么设置门禁卡)

    vivox70pro+怎么设置语音助手(vivox70pro怎么设置门禁卡)

  • 搜索历史已关闭怎样打开(搜索历史关闭了之后开启能看到吗?)

    搜索历史已关闭怎样打开(搜索历史关闭了之后开启能看到吗?)

  • 联想哪一年拿下中国个人电脑市场第一(联想哪一年成立)

    联想哪一年拿下中国个人电脑市场第一(联想哪一年成立)

  • gra-ul10是什么型号(华为gra-cl10)

    gra-ul10是什么型号(华为gra-cl10)

  • 电脑屏坏了能修吗(电脑屏坏了修一下多少钱)

    电脑屏坏了能修吗(电脑屏坏了修一下多少钱)

  • 网易云拉黑对方还能关注吗(网易云拉黑对方能看到主页吗)

    网易云拉黑对方还能关注吗(网易云拉黑对方能看到主页吗)

  • 小米ac2100频繁断网(小米ac2100突然断线怎么回事)

    小米ac2100频繁断网(小米ac2100突然断线怎么回事)

  • 微信昵称最多可以设置多少字(微信昵称最多可以改几次)

    微信昵称最多可以设置多少字(微信昵称最多可以改几次)

  • oppo手机安全事件怎么删除(OPPO手机安全事件查看下载)

    oppo手机安全事件怎么删除(OPPO手机安全事件查看下载)

  • 华为art-aloox是什么型号

    华为art-aloox是什么型号

  • 快手昵称后面的数字代表什么(快手昵称后面的数字名)

    快手昵称后面的数字代表什么(快手昵称后面的数字名)

  • ps怎么做透明磨砂质感(ps怎样做透明效果)

    ps怎么做透明磨砂质感(ps怎样做透明效果)

  • 电脑enter是什么意思(电脑enter键有什么用)

    电脑enter是什么意思(电脑enter键有什么用)

  • microsoft visual是啥

    microsoft visual是啥

  • 怎么设置文档16开纸(怎么设置文档自动保存)

    怎么设置文档16开纸(怎么设置文档自动保存)

  • oppo一个电话标志加hd(oppo手机来电显示一个号码)

    oppo一个电话标志加hd(oppo手机来电显示一个号码)

  • oppo桌面时钟怎么添加(oppo桌面时钟怎么设置悬浮)

    oppo桌面时钟怎么添加(oppo桌面时钟怎么设置悬浮)

  • 卡点视频怎么做教程(照片卡点视频怎么做)

    卡点视频怎么做教程(照片卡点视频怎么做)

  • smg9650ds是什么型号

    smg9650ds是什么型号

  • 从快手上买的东西怎么查物流(快手里买的东西)

    从快手上买的东西怎么查物流(快手里买的东西)

  • 修改工作组(电脑更改工作组后进不了系统)

    修改工作组(电脑更改工作组后进不了系统)

  • 详解Linux中将应用程序打包为Snap软件包格式的方法(linux中的应用程序主要保存在哪些目录中)

    详解Linux中将应用程序打包为Snap软件包格式的方法(linux中的应用程序主要保存在哪些目录中)

  • 人脸清晰化神器codeFormer图形界面包GUI(人脸清晰化神器软件)

    人脸清晰化神器codeFormer图形界面包GUI(人脸清晰化神器软件)

  • 【云原生 | 23】Docker运行Web服务实战之Tomcat(云原生是什么)

    【云原生 | 23】Docker运行Web服务实战之Tomcat(云原生是什么)

  • ps中钢笔工具的主要用途(ps里的钢笔工具)

    ps中钢笔工具的主要用途(ps里的钢笔工具)

  • 房产税一律按房产价值计征
  • 解除劳动一次性补偿金怎么记账
  • 工资与社保的关系怎么写
  • 预期报酬率和期望报酬率一样吗
  • 员工工资计入管理费用吗
  • 应付账款暂估余额
  • 个税申报系统中累计减除费用可以手动修改吗
  • 用携税宝怎么申报增值税
  • 租赁费进项税可以抵扣吗
  • 公益性捐赠的税收优惠政策
  • 行政事业单位国有资产处置管理办法
  • 代开运输发票是否预征企业所得税?
  • 应收账款融资的优缺点
  • 增值税转售行为怎么做会计处理?
  • 长期股权变更
  • 个人去税务局开居间费发票
  • 一般纳税人当月只有进项没有销项怎么做账
  • 个税申报所属期和所得期
  • 出口货物免征增值税的有哪些
  • 受委托研发企业可以享受研发支出吗
  • 仓库的账怎么做
  • 开发票没有银行回单可以入帐吗?
  • 360压缩怎么压缩到指定大小
  • 暂估成本能挂账多久
  • php的认识
  • PHP:Memcached::getServerList()的用法_Memcached类
  • 汽车报废残值收入怎么做账
  • php单例模式demo
  • 购买低值易耗品现金流量计入
  • 应付债券的应付利息怎么计算
  • 现金流量表补充资料怎么理解
  • 营业外收入合理避税
  • 企业预缴所得税怎么算
  • 微信小程序图片大小如何设置
  • xi:xtreg命令
  • 包装物押金会计科目
  • 租赁发票的租赁日期怎么写
  • 预收账款多好还是少好
  • 房产税从何时计算缴纳
  • 开一般户需要开户许可证吗
  • 企业没收入也要交税吗
  • 履约保证金打到个人账户合法吗
  • 营业总收入同比增长怎么分析
  • 增量留抵税额退税的计算公式为
  • 销售货物提供运输服务分录
  • 自产产品对外捐赠确认收入吗
  • 怎么做好流水账
  • 计提工会经费如何做账
  • 确认收入时,也必须确认资产或债务
  • 二手车交易增值税发票
  • 小微企业免征增值税优惠
  • centos6yum源
  • solaris安装软件包
  • win10系统如何关闭窗口特效
  • linux修改ssh端口号启动失败
  • Windows命令行复制粘贴命令
  • mac系统怎么把文件移到文件夹
  • fpt.exe
  • 深入了解linux内核
  • backtracker
  • 在bootstrap中,有哪几种导航
  • 初学excel零基础教学视频
  • jquery prototype
  • cluster into
  • angular子组件调用父组件的方法
  • jquery监听页面刷新
  • Python 中urls.py:URL dispatcher(路由配置文件)详解
  • nodejs quic
  • socketio视频教程
  • jquery中如何获取元素?
  • javastudio
  • python计算字符串长度的程序
  • 延安市地方税务局电话
  • 电子专票红字信息表
  • 国家税务局河北省税务局
  • 煤炭资源税税率表
  • 广东共青团如何解绑微信
  • 即征即退的留抵税额是否可以抵一般计税的税额
  • 纳税人分类分级管理办法
  • 国税能级管理(国税局等级制度)
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号