日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

AVOD:点云数据与BEV图的处理及可视化

發布時間:2024/8/1 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 AVOD:点云数据与BEV图的处理及可视化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • 前言
    • 1. 點云數據可視化
    • 2. 點云數據校準
    • 3. 轉為BEV圖
    • 結束語

前言

??本篇主要記錄對AVOD代碼的學習與理解,主要是KITTI數據集中3D Object Detection任務中的點云數據和BEV圖的處理,為方面理解其中的操作,博主在這里加入了可視化的操作。

??本篇博客使用的樣本編號為000274,RGB圖像如下:

1. 點云數據可視化

??點云數據保存在velodyne文件夾內,數據文件的格式是.bin,保存了x, y, z三軸坐標以及反射值r信息,數據格式為float32,通過numpy可以讀取文件,具體如下:

import numpy as npif __name__ == '__main__':bin_file = r'F:\DataSet\Kitti\object\velodyne\000274.bin'pointcloud = np.fromfile(bin_file, dtype=np.float32, count=-1).reshape([-1, 4])print('pointcloud shape: ', pointcloud.shape)# pointcloud shape: (120438, 4)

??為了更加直觀的看點云圖像,這里不再使用matplotlib,而是更專業的三維可視化工具包mayavi,具體操作如下:

import numpy as np from mayavi import mlabif __name__ == '__main__':bin_file = r'F:\DataSet\Kitti\object\velodyne\000274.bin'pointcloud = np.fromfile(bin_file, dtype=np.float32, count=-1).reshape([-1, 4])x = pointcloud[:, 0] # x position of pointy = pointcloud[:, 1] # y position of pointz = pointcloud[:, 2] # z position of pointr = pointcloud[:, 3] # reflectance value of pointd = np.sqrt(x ** 2 + y ** 2) # Map Distance from sensorvals = 'height'if vals == "height":col = zelse:col = dfig = mlab.figure(bgcolor=(1, 1, 1), size=(700, 500))mlab.points3d(x, y, z,d, # Values used for Colormode="point",colormap='spectral', # 'bone', 'copper', 'gnuplot', 'spectral', 'summer'# color=(0, 1, 0), # Used a fixed (r,g,b) insteadfigure=fig)mlab.show()

??可視化結果如下:


??調整一下視角與RGB圖保持一致:

2. 點云數據校準

??RGB圖片使用的是左側第二個彩色攝像機,即image_2,因此需要將雷達數據進行坐標變化,將其映射到攝像機坐標系中,計算公式為:

y = P2 * R0_rect * Tr_velo_to_cam * x

??大致計算流程:

# Read calibration info frame_calib = calib_utils.read_calibration(calib_dir, img_idx) x, y, z, i = calib_utils.read_lidar(velo_dir=velo_dir, img_idx=img_idx)# Calculate the point cloud pts = np.vstack((x, y, z)).T pts = calib_utils.lidar_to_cam_frame(pts, frame_calib)# Only keep points in front of camera (positive z) pts = pts[pts[:, 2] > 0] point_cloud = pts.T# Project to image frame point_in_im = calib_utils.project_to_image(point_cloud, p=frame_calib.p2).T

??具體實現:

# 為了方便可視化數據,這里封裝了對點云進行可視化的函數 def visu_point_cloud(x, y, z):d = np.sqrt(x ** 2 + y ** 2) # Map Distance from sensorvals = 'distance'if vals == "distance":col = delse:col = zfig = mlab.figure(bgcolor=(1, 1, 1), size=(700, 500))mlab.points3d(x, y, z,col, # Values used for Colormode="point",colormap='spectral', # 'bone', 'copper', 'gnuplot', 'spectral', 'summer'# color=(0, 1, 0), # Used a fixed (r,g,b) insteadfigure=fig)mlab.show()def get_lidar_point_cloud(calib_dir, velo_dir, img_idx, im_size=None, min_intensity=None):""" Calculates the lidar point cloud, and optionally returns only thepoints that are projected to the image.:param calib_dir: directory with calibration files:param velo_dir: directory with velodyne files:param img_idx: image index:param im_size: (optional) 2 x 1 list containing the size of the imageto filter the point cloud [w, h]:param min_intensity: (optional) minimum intensity required to keep a point:return: (3, N) point_cloud in the form [[x,...][y,...][z,...]]"""# Read calibration infoframe_calib = read_calibration(calib_dir, img_idx)x, y, z, i = read_lidar(velo_dir=velo_dir, img_idx=img_idx)# Calculate the point cloudpts = np.vstack((x, y, z)).Tpts = lidar_to_cam_frame(pts, frame_calib)# The given image is assumed to be a 2D imageif not im_size:point_cloud = pts.Treturn point_cloudelse:# Only keep points in front of camera (positive z)pts = pts[pts[:, 2] > 0]point_cloud = pts.T# Project to image framepoint_in_im = project_to_image(point_cloud, p=frame_calib['p2']).T# Filter based on the given image sizeimage_filter = (point_in_im[:, 0] > 0) & \(point_in_im[:, 0] < im_size[0]) & \(point_in_im[:, 1] > 0) & \(point_in_im[:, 1] < im_size[1])if not min_intensity:return pts[image_filter].Telse:intensity_filter = i > min_intensitypoint_filter = np.logical_and(image_filter, intensity_filter)return pts[point_filter].Timg_path = r'F:\DataSet\Kitti\object\image_2' lidar_path = r'F:\DataSet\Kitti\object\velodyne' calib_path = r'F:\DataSet\Kitti\object\calib' planes_path = r'F:\DataSet\Kitti\object\planes' label_path = r'F:\DataSet\Kitti\object\label_2' img_idx = 274if __name__ == '__main__':point_cloud = get_lidar_point_cloud(calib_path, lidar_path, img_idx, im_size)visu_point_cloud(point_cloud[0], point_cloud[1], point_cloud[2])

??可視化結果如下:


??調整視角為俯視圖:

3. 轉為BEV圖

??BEV,即bird's eye view,鳥瞰圖

??鳥瞰圖的計算需要用到地面數據,即空間上的點投影到某個平面,需要知道該平面的平面方程,平面方程的表達式為:ax+by+cz+d=0ax+by+cz+d=0ax+by+cz+d=0??空間上的點P(x0,y0,z0)P(x_0,y_0,z_0)P(x0?,y0?,z0?)到平面上的距離為:distance=∣ax0+by0+cz0+d∣a2+b2+c2distance=\frac {|ax_0+by_0+cz_0+d|} {\sqrt {a^2+b^2+c^2}}distance=a2+b2+c2?ax0?+by0?+cz0?+d???讀取KITTI數據集中的地面數據:

# 000274.txt # Plane Width 4 Height 1 -2.143976e-03 -9.997554e-01 2.201096e-02 1.707479e+00 # 分別表示a, b, c, d四個參數值

??點云數據轉BEV時高度分辨率為0.5,根據點云數據可以得到x,y和z軸上的數據,即x_col,y_col,z_col,然后使用np.lexsort()對x軸進行排序:

sorted_order = np.lexsort((y_col, z_col, x_col)) # 對 x_col 進行排序 # 如果 x_col 中的數值一樣,則比較 z_col 中相應索引下的值的大小 # 如果還相同,再比較 y_col 中的元素

??將 y_col 中的元素置為0,即只保留x和z軸上的數據,然后使用np.view()對數值類型進行變換:

# 定義12字節的數據類型 dt = np.dtype((np.void, 12))# 先使用np.ascontiguousarray將一個內存不連續存儲的數組轉換為內存連續存儲的數組,使得運行速度更快 # 再使用np.view按指定方式對內存區域進行切割,來完成數據類型的轉換 # discrete_pts(n, 3) --> contiguous_array(n, 1) # itemsize輸出array元素的字節數 contiguous_array = np.ascontiguousarray(discrete_pts).view(dtype=dt)

??離散點云數據discrete_pts的shape為(n,3),其數值類型為np.int32,4字節,總字節為n34Byte,現將其轉為12Byte的數據,即保持總字節數不變:n112,轉換完成后的shape為(n,1)。

??對上述的數據進行去重:

# 去除數組中的重復數字,并進行排序 _, unique_indices = np.unique(contiguous_array, return_index=True) unique_indices.sort() # 得到不重復的數據 # voxel 體素(三維) # pixel 像素(二維) voxel_coords = discrete_pts[unique_indices] # 將索引值映射到原點 voxel_coords -= -400

??計算每個體素中數據點的數量,即后一個索引值減去當前索引值:

num_points_in_voxel = np.diff(unique_indices) num_points_in_voxel = np.append(num_points_in_voxel,discrete_pts_2d.shape[0] -unique_indices[-1])

??計算每個體素中數據點的高度,通過計算點到平面方程的距離:

# voxel (x, y, z) # 平面方程: ax + by + cz + d = 0 height_in_voxel = (a*x + b*y + c*z + d) / np.sqrt(a**2 + b**2 + c**2)

??對高度信息進行縮放,height_in_voxel = height_in_voxel / 0.5,根據二維索引值voxel_coords(去除y軸)與高度信息即可得到BEV數據,密度信息的計算:

# N is num points in voxel # x = 16 density_map = min(1.0, log(N+1)/log(x))

??最終的BEV是由5個高度信息和1個密度信息組成,其shape為(700, 800, 6)。
??三維可視化結果如下:


??RGB可視化如下:

結束語

??后續繼續更新^_^

總結

以上是生活随笔為你收集整理的AVOD:点云数据与BEV图的处理及可视化的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 精品午夜久久久 | 美女大bxxxxn内射 | 青青在线 | 国内一区二区视频 | 国产精品伦理一区二区 | 国产亚洲高清视频 | 日本精品久久久久 | 精品成人av一区二区三区 | 亚洲永久精品ww.7491进入 | 欧美性日韩 | 日韩欧美国产高清91 | 北条麻妃一区二区三区四区五区 | 一二三av| 亚洲理论片在线观看 | 福利毛片 | 丰满少妇影院 | 999av| 粉嫩aⅴ一区二区三区 | 成人欧美一区二区三区黑人一 | 精品视频网 | 国产自偷自拍视频 | 天天操夜夜添 | 超碰超碰超碰超碰超碰 | 日日干日日摸 | 最新激情网 | 视频一区在线免费观看 | 欧美午夜精品一区二区 | 激情视频免费在线观看 | 欧美五月婷婷 | 亚洲欧美一二三 | 国产污视频 | 日韩一区免费 | 在线视频观看一区二区 | 91亚洲精品视频 | 亚洲视频一二三 | 久久久精选 | 一区二区在线 | 久久xxxx | 国产成人综合网 | 中文字字幕在线中文 | 久久精品色欲国产AV一区二区 | 亚洲精品高清在线观看 | av这里只有精品 | 欧美一区二区三区久久精品 | 韩国毛片一区二区三区 | 国产一区二区三区久久久 | 色偷偷中文字幕 | 熟女视频一区 | 最新久久久 | 性视频播放免费视频 | 国产aaa毛片 | 婷婷丁香色| 国产丝袜一区二区三区 | 色欲人妻综合网 | 免费观看亚洲视频 | 欧美日韩一二区 | 色哟哟在线 | 女女h百合无遮涩涩漫画软件 | 美女扒开内裤让男人桶 | 国产一区二区小视频 | 豆花在线观看 | 青青草国产成人99久久 | 在线看亚洲 | 国模精品一区二区三区 | 精品字幕 | 姐姐的朋友2在线 | 日韩av在线播放一区 | 日本少妇激情舌吻 | 精品人妻一区二区三区久久夜夜嗨 | 懂色av一区二区三区在线播放 | 欧美激情一级 | 五月天激情影院 | 黄色网免费观看 | 精品国产一区二区三区四区阿崩 | 亚洲 小说区 图片区 | 伊人久久伊人 | 日日夜夜精品视频免费 | 欧美激情一二三区 | 亚洲乱码国产乱码精品精大量 | 免费无码国产v片在线观看 三级全黄做爰在线观看 | 国产精品伦子伦 | 丁香花五月天 | 日本黄色www | 奇米在线 | 国产亚洲欧美日韩高清 | 免费日韩一区 | 亚洲欧美色视频 | 久久免费视频精品 | 日韩有码一区 | 蜜臀av粉嫩av懂色av | 久青草国产在线 | 女人裸体又黄 | wwwjizzzcom | 91玉足脚交白嫩脚丫 | 麻豆极品 | 国产精品第3页 | 性高湖久久久久久久久aaaaa | 九九九九九热 | jizz亚洲女人高潮大叫 |