当前位置:   article > 正文

(15)点云数据处理学习——单目深度估计获得RGBD图再重建点云_深度图像和rgb图像生成点云数据

深度图像和rgb图像生成点云数据

1、主要参考

(1)大佬视频

Create Your Own Point Clouds from Depth Maps - Point Cloud Processing in Open3D_哔哩哔哩_bilibili

(2)重要!!!我前面的教程

(7)点云数据处理学习——单摄像头深度估计_chencaw的博客-CSDN博客

(6)点云数据处理学习——RGBD图_chencaw的博客-CSDN博客_点云图由几张rgb图像生成

2、 前提回顾和实现

2.1 思路

陈PS:

  1. 用普通相机获得彩色的RGB图
  2. 然后用MiDaS深度学习模型获得深度图
  3. 然后这两个图已对应不就是RGBD图了嘛
  4. 然后用open3D三维点云重建一下。

2.2摄像头标定和参数

(1)根据我前面的教程,可以进行摄像头标定和内参获取

(7)点云数据处理学习——单摄像头深度估计_chencaw的博客-CSDN博客

 (2)内参矩阵为

mtx:
 [[801.31799138   0.         319.96097314]
 [  0.         804.76125593 206.79594003]
 [  0.           0.           1.        ]]
dist畸变值:
 [[-7.21246445e-02 -6.84714453e-01 -1.25501966e-02  5.75752614e-03
   9.50679972e+00]]

(3)外部调节参数

<?xml version="1.0"?>

<opencv_storage>

<intrinsic type_id="opencv-matrix">

  <rows>3</rows>

  <cols>3</cols>

  <dt>d</dt>

  <data>

    1.1476093750000000e+03 0. 2.8008979619154707e+02 0.

    1.1125493164062500e+03 2.7150911855935556e+02 0. 0. 1.</data></intrinsic>

</opencv_storage>

2.3 根据单目深度模型获得RGB图和深度图

(1)本次实现的代码34mono_to_rgbd.py

  1. import torch
  2. import matplotlib.pyplot as plt
  3. import cv2
  4. import numpy as np
  5. import time
  6. rgbd_save_path = "D:/RGBD_CAMERA/python_3d_process/chen_rgbd/"
  7. ##直接将D:/RGBD_CAMERA/mis/MiDaS-master/hubconf.py中的transforms拿来使用
  8. def transforms():
  9. import cv2
  10. from torchvision.transforms import Compose
  11. from midas.transforms import Resize, NormalizeImage, PrepareForNet
  12. from midas import transforms
  13. transforms.default_transform = Compose(
  14. [
  15. lambda img: {"image": img / 255.0},
  16. Resize(
  17. 384,
  18. 384,
  19. resize_target=None,
  20. keep_aspect_ratio=True,
  21. ensure_multiple_of=32,
  22. resize_method="upper_bound",
  23. image_interpolation_method=cv2.INTER_CUBIC,
  24. ),
  25. NormalizeImage(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
  26. PrepareForNet(),
  27. lambda sample: torch.from_numpy(sample["image"]).unsqueeze(0),
  28. ]
  29. )
  30. transforms.small_transform = Compose(
  31. [
  32. lambda img: {"image": img / 255.0},
  33. Resize(
  34. 256,
  35. 256,
  36. resize_target=None,
  37. keep_aspect_ratio=True,
  38. ensure_multiple_of=32,
  39. resize_method="upper_bound",
  40. image_interpolation_method=cv2.INTER_CUBIC,
  41. ),
  42. NormalizeImage(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
  43. PrepareForNet(),
  44. lambda sample: torch.from_numpy(sample["image"]).unsqueeze(0),
  45. ]
  46. )
  47. transforms.dpt_transform = Compose(
  48. [
  49. lambda img: {"image": img / 255.0},
  50. Resize(
  51. 384,
  52. 384,
  53. resize_target=None,
  54. keep_aspect_ratio=True,
  55. ensure_multiple_of=32,
  56. resize_method="minimal",
  57. image_interpolation_method=cv2.INTER_CUBIC,
  58. ),
  59. NormalizeImage(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]),
  60. PrepareForNet(),
  61. lambda sample: torch.from_numpy(sample["image"]).unsqueeze(0),
  62. ]
  63. )
  64. return transforms
  65. # (一)方法一、使用torch.hub或者从官网下载
  66. # https://github.com/isl-org/MiDaS#Accuracy
  67. # model_type = "DPT_Large" # MiDaS v3 - Large (highest accuracy, slowest inference speed)
  68. # #model_type = "DPT_Hybrid" # MiDaS v3 - Hybrid (medium accuracy, medium inference speed)
  69. # #model_type = "MiDaS_small" # MiDaS v2.1 - Small (lowest accuracy, highest inference speed)
  70. # midas = torch.hub.load("intel-isl/MiDaS", model_type)
  71. # (二)方法二、下载本地后直接加载
  72. # (1)Load a model
  73. model_type = "DPT_Large"
  74. # midas = torch.hub.load('intel-isl/MiDaS', path='D:/BaiduNetdiskDownload/dpt_large-midas-2f21e586.pt', source='local',model =model_type )
  75. # midas = torch.hub.load('D:/RGBD_CAMERA/mis/MiDaS-master', path='D:/BaiduNetdiskDownload/dpt_large-midas-2f21e586.pt', source='local',model =model_type,force_reload = False )
  76. midas = torch.hub.load('D:/RGBD_CAMERA/mis/MiDaS-master', source='local',model =model_type,force_reload = False )
  77. #(2)Move model to GPU if available
  78. device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu")
  79. midas.to(device)
  80. midas.eval()
  81. #(3)Load transforms to resize and normalize the image for large or small model
  82. # midas_transforms = torch.hub.load("intel-isl/MiDaS", "transforms")
  83. midas_transforms = transforms()
  84. if model_type == "DPT_Large" or model_type == "DPT_Hybrid":
  85. transform = midas_transforms.dpt_transform
  86. else:
  87. transform = midas_transforms.small_transform
  88. print("chen0")
  89. #(4)Load image and apply transforms
  90. # filename = 'D:/RGBD_CAMERA/python_3d_process/dog.jpg'
  91. # img = cv2.imread(filename)
  92. # img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
  93. # Open up the video capture from a webcam
  94. cap = cv2.VideoCapture(1)
  95. print("chencap")
  96. success, img = cap.read()
  97. cv2.imshow("origin_pic",img)
  98. cv2.waitKey(3)
  99. img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
  100. print("chen1")
  101. input_batch = transform(img).to(device)
  102. #(5)Predict and resize to original resolution
  103. with torch.no_grad():
  104. prediction = midas(input_batch)
  105. prediction = torch.nn.functional.interpolate(
  106. prediction.unsqueeze(1),
  107. size=img.shape[:2],
  108. mode="bicubic",
  109. align_corners=False,
  110. ).squeeze()
  111. output = prediction.cpu().numpy()
  112. print(output.shape)
  113. print("chen2")
  114. #(6)Show result
  115. plt.subplot(1,2,1)
  116. plt.imshow(img)
  117. plt.subplot(1,2,2)
  118. plt.imshow(output)
  119. plt.show()
  120. cv2.imwrite(rgbd_save_path+"chen_depth_img.png",output)
  121. #转换回来
  122. img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
  123. cv2.imwrite(rgbd_save_path+"chen_color_img.jpg",img)
  124. cap.release()
  125. cv2.destroyAllWindows()

(2)RGBD的处理代码

可以参考我前面的教程

(6)点云数据处理学习——RGBD图_chencaw的博客-CSDN博客_点云图由几张rgb图像生成

  1. import open3d as o3d
  2. import numpy as np
  3. from matplotlib import pyplot as plt
  4. rgbd_save_path = "D:/RGBD_CAMERA/python_3d_process/chen_rgbd/"
  5. color_raw = o3d.io.read_image(rgbd_save_path+"chen_color_img.jpg")
  6. # print(np.asarray(color_raw))
  7. # plt.imshow(np.asarray(color_raw))
  8. # plt.show()
  9. depth_raw = o3d.io.read_image(rgbd_save_path+"chen_depth_img.png")
  10. # plt.imshow(np.asarray(depth_raw))
  11. # plt.show()
  12. rgbd_image = o3d.geometry.RGBDImage.create_from_color_and_depth(color_raw, depth_raw)
  13. print(rgbd_image)
  14. plt.subplot(1, 2, 1)
  15. plt.title('SUN grayscale image')
  16. plt.imshow(rgbd_image.color)
  17. plt.subplot(1, 2, 2)
  18. plt.title('SUN depth image')
  19. plt.imshow(rgbd_image.depth)
  20. plt.show()
  21. pcd = o3d.geometry.PointCloud.create_from_rgbd_image(
  22. rgbd_image,
  23. o3d.camera.PinholeCameraIntrinsic(
  24. o3d.camera.PinholeCameraIntrinsicParameters.PrimeSenseDefault))
  25. # Flip it, otherwise the pointcloud will be upside down
  26. # pcd.transform([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]])
  27. pcd.transform([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])
  28. # o3d.visualization.draw_geometries([pcd], zoom=0.5)
  29. o3d.visualization.draw_geometries([pcd])

 (3)效果,咳咳,还是不错的,但是还是放大佬的图吧

 

2.3 把摄像头内参用起来,提高精度

2.3.1 默认内参

(1)注意,以下是默认内参。刚才上面的程序使用了默认内参来实现RGBD图转点云显示

    o3d.camera.PinholeCameraIntrinsic(

        o3d.camera.PinholeCameraIntrinsicParameters.PrimeSenseDefault)

默认内参的值,参照官方教程

RGBD images — Open3D 0.16.0 documentation

这里我们使用PinholeCameraIntrinsicParameters。PrimeSenseDefault作为默认的相机参数。它具有图像分辨率640x480,焦距(fx, fy) =(525.0, 525.0),光学中心(cx, cy) =(319.5, 239.5)。 

2.3.2 使用自己标定的内参

(1)注意:使用了外部调整参数!!!!!

  1. import open3d as o3d
  2. import numpy as np
  3. from matplotlib import pyplot as plt
  4. import cv2
  5. rgbd_save_path = "D:/RGBD_CAMERA/python_3d_process/chen_rgbd/"
  6. color_raw = o3d.io.read_image(rgbd_save_path+"chen_color_img.jpg")
  7. # print(np.asarray(color_raw))
  8. # plt.imshow(np.asarray(color_raw))
  9. # plt.show()
  10. depth_raw = o3d.io.read_image(rgbd_save_path+"chen_depth_img.png")
  11. # plt.imshow(np.asarray(depth_raw))
  12. # plt.show()
  13. rgbd_image = o3d.geometry.RGBDImage.create_from_color_and_depth(color_raw, depth_raw)
  14. print(rgbd_image)
  15. plt.subplot(1, 2, 1)
  16. plt.title('SUN grayscale image')
  17. plt.imshow(rgbd_image.color)
  18. plt.subplot(1, 2, 2)
  19. plt.title('SUN depth image')
  20. plt.imshow(rgbd_image.depth)
  21. plt.show()
  22. #方法(一)默认摄像头内参
  23. # pcd = o3d.geometry.PointCloud.create_from_rgbd_image(
  24. # rgbd_image,
  25. # o3d.camera.PinholeCameraIntrinsic(
  26. # o3d.camera.PinholeCameraIntrinsicParameters.PrimeSenseDefault))
  27. #方法(二)设定自己的摄像机外部调整参数
  28. cv_file = cv2.FileStorage()
  29. cv_file.open('D:/RGBD_CAMERA/python_3d_process/1mono_to_3d/cameraIntrinsic.xml',cv2.FileStorage_READ)
  30. camera_intrinsic = cv_file.getNode('intrinsic').mat()
  31. print(camera_intrinsic)
  32. camera_intrinsic_o3d = o3d.camera.PinholeCameraIntrinsic(width=640,height=480,
  33. fx=camera_intrinsic[0][0],
  34. fy=camera_intrinsic[1][1],
  35. cx=camera_intrinsic[0][2],
  36. cy=camera_intrinsic[1][2])
  37. print(camera_intrinsic_o3d.intrinsic_matrix)
  38. pcd = o3d.geometry.PointCloud.create_from_rgbd_image(
  39. rgbd_image,
  40. camera_intrinsic_o3d)
  41. # Flip it, otherwise the pointcloud will be upside down
  42. # pcd.transform([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]])
  43. #注意:左右转换了一下!否则显示是镜像图
  44. pcd.transform([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])
  45. # o3d.visualization.draw_geometries([pcd], zoom=0.5)
  46. o3d.visualization.draw_geometries([pcd])

(2)效果还是很不错的,图就不上了,完结撒花

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号