亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用 Open3D 從圖像生成點云時出現空白屏幕

使用 Open3D 從圖像生成點云時出現空白屏幕

一只斗牛犬 2022-09-13 15:19:54
所以我嘗試用Python中的Open3D庫創建一個點云,最后,它基本上只是這里引用的2行,但是當我運行我的代碼(見下文)時,我得到的只是一個彈出的白屏。我已經在Jupyter筆記本中運行了它,但是從控制臺在python腳本中運行它沒有改變任何東西,也沒有拋出錯誤。我應該提到我在Blender中創建圖像并將其另存為OpenExr,這意味著深度值范圍在0到4之間(我已將其截斷為4作為背景)。您可以在下面看到它們是正確的圖像,我也可以將它們轉換為Open3D圖片并毫無問題地顯示它們。
查看完整描述

2 回答

?
忽然笑

TA貢獻1806條經驗 獲得超5個贊

簡而言之,Open3D 希望您的 3 通道彩色圖像為 uint8 類型。


否則,它將返回一個空的點云,從而導致您看到的空白窗口。


更新 2020-3-27,深夜在我的時區:)


現在您已經提供了代碼,讓我們開始吧!


從您的函數名稱中,我猜您正在使用Open3D 0.7.0或類似的東西。我提供的代碼在 0.9.0 中。某些函數名稱已更改,并添加了新功能。


當我在 0.9.0 中運行您的代碼時(當然經過一些小的修改后),會出現一個運行時錯誤:


RuntimeError: [Open3D ERROR] [CreatePointCloudFromRGBDImage] Unsupported image format.

我們可以從Open3D源中看到,您的彩色圖像必須是3個通道,每個通道僅占用1個字節(uint8),或者是1個通道并占用4個字節(浮動,這意味著強度圖像):0.9.0


std::shared_ptr<PointCloud> PointCloud::CreateFromRGBDImage(

        const RGBDImage &image,

        const camera::PinholeCameraIntrinsic &intrinsic,

        const Eigen::Matrix4d &extrinsic /* = Eigen::Matrix4d::Identity()*/,

        bool project_valid_depth_only) {

    if (image.depth_.num_of_channels_ == 1 &&

        image.depth_.bytes_per_channel_ == 4) {

        if (image.color_.bytes_per_channel_ == 1 &&

            image.color_.num_of_channels_ == 3) {

            return CreatePointCloudFromRGBDImageT<uint8_t, 3>(

                    image, intrinsic, extrinsic, project_valid_depth_only);

        } else if (image.color_.bytes_per_channel_ == 4 &&

                   image.color_.num_of_channels_ == 1) {

            return CreatePointCloudFromRGBDImageT<float, 1>(

                    image, intrinsic, extrinsic, project_valid_depth_only);

        }

    }

    utility::LogError(

            "[CreatePointCloudFromRGBDImage] Unsupported image format.");

    return std::make_shared<PointCloud>();

}

否則,會出現像我遇到的錯誤。

但是,在 的版本中,源代碼是:0.7.0


std::shared_ptr<PointCloud> CreatePointCloudFromRGBDImage(

        const RGBDImage &image,

        const camera::PinholeCameraIntrinsic &intrinsic,

        const Eigen::Matrix4d &extrinsic /* = Eigen::Matrix4d::Identity()*/) {

    if (image.depth_.num_of_channels_ == 1 &&

        image.depth_.bytes_per_channel_ == 4) {

        if (image.color_.bytes_per_channel_ == 1 &&

            image.color_.num_of_channels_ == 3) {

            return CreatePointCloudFromRGBDImageT<uint8_t, 3>(image, intrinsic,

                                                              extrinsic);

        } else if (image.color_.bytes_per_channel_ == 4 &&

                   image.color_.num_of_channels_ == 1) {

            return CreatePointCloudFromRGBDImageT<float, 1>(image, intrinsic,

                                                            extrinsic);

        }

    }   

    utility::PrintDebug(

            "[CreatePointCloudFromRGBDImage] Unsupported image format.\n");

    return std::make_shared<PointCloud>();

}

這意味著Open3D仍然不支持它,但它只會警告你。并且僅在調試模式下!

之后,它將返回一個空的點云。(實際上兩個版本都這樣做。這解釋了空白窗口。


現在你應該知道,你可以成功。雖然您仍然應該首先規范化您的彩色圖像。

或者,您可以將彩色圖像轉換為范圍和類型 。

兩者都行得通。convert_rgb_to_intensity=True[0, 255]uint8


現在我希望一切都清楚了。萬歲!


附言:實際上我通常發現Open3D源代碼易于閱讀。如果你知道C++,每當這樣的事情發生時,你都可以閱讀它。


2020-3-27更新:


我無法重現您的結果,我不知道為什么會發生這種情況(您應該提供一個最小的可重現示例)。


使用您在注釋中提供的圖像,我編寫了以下代碼,并且運行良好。如果它仍然無法在您的計算機上工作,則可能是您的Open3D已損壞。


(我不熟悉 .exr 圖像,因此數據提取可能很丑陋:)


import Imath

import array

import OpenEXR


import numpy as np

import open3d as o3d



# extract data from exr files

f = OpenEXR.InputFile('frame.exr')

FLOAT = Imath.PixelType(Imath.PixelType.FLOAT)

cs = list(f.header()['channels'].keys())  # channels

data = [np.array(array.array('f', f.channel(c, FLOAT))) for c in cs] 

data = [d.reshape(720, 1280) for d in data]

rgb = np.concatenate([data[i][:, :, np.newaxis] for i in [3, 2, 1]], axis=-1)

# rgb /= np.max(rgb)  # this will result in a much darker image

np.clip(rgb, 0, 1.0)  # to better visualize as HDR is not supported?


# get rgbd image

img = o3d.geometry.Image((rgb * 255).astype(np.uint8))

depth = o3d.geometry.Image((data[-1] * 1000).astype(np.uint16))

rgbd = o3d.geometry.RGBDImage.create_from_color_and_depth(img, depth, convert_rgb_to_intensity=False)


# some guessed intrinsics

intr = o3d.open3d.camera.PinholeCameraIntrinsic(1280, 720, fx=570, fy=570, cx=640, cy=360)


# get point cloud and visualize

pcd = o3d.geometry.PointCloud.create_from_rgbd_image(rgbd, intr)

o3d.visualization.draw_geometries([pcd])

結果是:

http://img1.sycdn.imooc.com//63202f39000113d906470362.jpg

原始答案:


您誤解了 的含義。depth_scale


使用以下行:

depth = o3d.geometry.Image(np.array(img_array[:, :, 3]*1000).astype('uint16'))


Open3D文檔說,深度值將首先被縮放,然后被截斷。實際上,這意味著深度圖像中的像素值將首先除以此數字而不是乘法,正如您在Open3D源代碼中看到的那樣:


std::shared_ptr<Image> Image::ConvertDepthToFloatImage(

        double depth_scale /* = 1000.0*/, double depth_trunc /* = 3.0*/) const {

    // don't need warning message about image type

    // as we call CreateFloatImage

    auto output = CreateFloatImage();

    for (int y = 0; y < output->height_; y++) {

        for (int x = 0; x < output->width_; x++) {

            float *p = output->PointerAt<float>(x, y);

            *p /= (float)depth_scale;

            if (*p >= depth_trunc) *p = 0.0f;

        }

    }

    return output;

}

實際上,我們通常想當然地認為深度圖像的值應該是整數(我想這就是為什么Open3D沒有在他們的文檔中明確指出這一點),因為浮點圖像不太常見。

您無法將米存儲在.png圖像中,因為它們會失去精度。因此,我們存儲了深度圖像,稍后的進程將首先將其轉換回 。1.3413401.34


至于深度圖像的相機固有函數,我猜在創建Blender時會有配置參數。我不熟悉攪拌機,所以我不會談論它。但是,如果您不了解一般的相機固有特性,則可能需要看一下。


查看完整回答
反對 回復 2022-09-13
?
慕娘9325324

TA貢獻1783條經驗 獲得超4個贊

但是,我假設他的Open3D版本與我的版本不同,我不得不像這樣更改2個函數調用(并稍微更改了命名):


exr_img = OpenEXR.InputFile('frame0100.exr')

cs = list(exr_img.header()['channels'].keys())  # channels

FLOAT = Imath.PixelType(Imath.PixelType.FLOAT)


img_data = [np.array(array.array('f', exr_img.channel(c, FLOAT))) for c in cs]

img_data = [d.reshape(720,1280) for d in img_data]


rgb = np.concatenate([img_data[i][:, :, np.newaxis] for i in [3, 2, 1]], axis=-1)

np.clip(rgb, 0, 1.0)  # to better visualize as HDR is not supported?



img = o3d.geometry.Image((rgb * 255).astype(np.uint8))

depth = o3d.geometry.Image((img_data[-1] * 1000).astype(np.uint16))

#####rgbd = o3d.geometry.RGBDImage.create_from_color_and_depth(img, depth, convert_rgb_to_intensity=False)


rgbd = o3d.create_rgbd_image_from_color_and_depth(img, depth, convert_rgb_to_intensity=False)



# some guessed intrinsics

intr = o3d.open3d.camera.PinholeCameraIntrinsic(1280, 720, fx=570, fy=570, cx=640, cy=360)


# get point cloud and visualize

#####pcd = o3d.geometry.PointCloud.create_from_rgbd_image(rgbd, intr)

pcd = o3d.create_point_cloud_from_rgbd_image(rgbd, intr)



o3d.visualization.draw_geometries([pcd])

否則我得到以下錯誤:


AttributeError: type object 'open3d.open3d.geometry.RGBDImage' has no attribute 'create_from_color_and_depth'

希望這也能幫助其他人使用我的Python / Open3D版本。不太確定我的代碼中的錯誤究竟在哪里,但我對擁有可用的代碼感到滿意。再次感謝趙晶!


查看完整回答
反對 回復 2022-09-13
  • 2 回答
  • 0 關注
  • 1735 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號