日韩性视频-久久久蜜桃-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图的处理及可视化的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 亲子乱aⅴ一区二区三区 | 91国在线视频 | 男人的天堂久久 | 日韩乱码一区二区三区 | 国产二页 | 黄色aaa毛片 | 999免费视频 | 日韩你懂的| 日韩精品在线观看网站 | 成人涩涩网站 | 一级片一区二区三区 | 又色又爽又黄gif动态图 | 天天综合天天 | 黄色网页免费看 | 国产日产欧洲无码视频 | 日本久久久久久 | 中国女人做爰视频 | 永久福利视频 | 欧美11一13sex性hd | 国产免费叼嘿网站免费 | 日韩精品一区在线 | 成 年 人 黄 色 大 片大 全 | 他揉捏她两乳不停呻吟动态图 | 亚洲欧美一区二区三区久久 | 天天操导航 | 直接看的毛片 | 强伦人妻一区二区三区视频18 | av黄色网 | 日韩高清在线一区 | 欧美性生活网站 | 中文字幕日韩专区 | 老外一级片 | 看全色黄大色黄女片18 | 成人网在线视频 | 五月婷色 | 亚洲第一欧美 | 一区二区三区av夏目彩春 | 亚洲av男人的天堂在线观看 | 欧美日本日韩 | 男人和女人日批视频 | 翔田千里一区二区三区av | 青苹果av| 欧美性大战久久久久久 | 黄视频免费在线看 | 国产一区二区视频免费观看 | 快播视频在线观看 | 日韩精品免费一区二区三区 | 日韩大胆视频 | 七月婷婷综合 | 视频在线不卡 | 国产做受91 | 欧美视频免费看欧美视频 | 黄色片免费网站 | 91精品啪在线观看国产线免费 | 日韩视频在线免费播放 | 粉嫩av网| 一区二区福利电影 | 久久国产精品久久久久久电车 | 在线免费看mv的网站入口 | 另类专区欧美 | 国产视频在线观看视频 | 一起草av在线 | 色噜噜狠狠一区二区 | 中文字幕av日韩 | 日本成人三级电影 | 亚洲一线在线观看 | 午夜剧场欧美 | 91激情视频在线观看 | 美女裸体跪姿扒开屁股无内裤 | 亚洲天堂少妇 | 免费无码一区二区三区 | 校园春色综合网 | 国产91网址 | 亚洲精品1 | 日本一级片在线播放 | 久久亚洲免费视频 | 88久久精品无码一区二区毛片 | 99成人国产精品视频 | 久久婷婷国产麻豆91天堂 | 黄页免费视频 | 免费黄网站在线看 | 亚洲成人久久久 | 波多野结衣av在线观看 | 女人一级一片30分 | 国产精选久久久 | 欧美做受xxxxxⅹ性视频 | 三级性生活视频 | 亚洲一级无毛 | 性生活av| 亚洲天堂中文字幕在线 | 奇米在线播放 | 亚洲精品国产suv | 国产欧美一区二区三区在线老狼 | 在线免费观看的av | 亚洲欧美一区二区三区久久 | 成人首页 | 亚洲视频中文字幕 | a级片在线免费观看 | 日本网站在线播放 |