Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I failed to compress the downsampled point cloud file with draco_encoder. #1057

Open
Zhouwudexiazhou opened this issue Mar 25, 2024 · 1 comment

Comments

@Zhouwudexiazhou
Copy link

The specific situation is that I use your draco_encoder to compress point cloud file.The code is :
import numpy as np
import open3d as o3d
import os
import config
from typing import List
import subprocess
import pickle

import os
import subprocess

def compress_point_cloud(file_path, output_path):
try:
output_file_path = os.path.join(output_path, os.path.basename(file_path).replace(".ply", ".drc"))
command = ["D:/volumetric video/open 3d/draco/draco_encoder.exe", "-i", file_path, "-o", output_file_path]

    process = subprocess.Popen(command, cwd="D:/volumetric video/open 3d/draco", stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE)
    stdout, stderr = process.communicate()

    if process.returncode == 0:
        print(f"{file_path} 压缩完成,压缩文件保存在:{output_file_path}")
    else:
        if stderr:
            error_msg = stderr.decode()
        else:
            error_msg = "未知错误"
        print("压缩失败:", error_msg)

except FileNotFoundError as e:
    print("文件未找到:", e)
except subprocess.CalledProcessError as e:
    print("调用子进程错误:", e)
except OSError as e:
    print("系统调用错误:", e)
except Exception as e:
    print("压缩出现异常:", e)

if name == "main":
patch_path = r"D:\volumetric video\open 3d\draco\1\longdress_vox10_1051.ply"
output_path = r"D:\volumetric video\open 3d\draco\2"
compress_point_cloud(patch_path, output_path)

"D:\volumetric video\open 3d\draco\1\longdress_vox10_1051.ply" is unprocessed files while i download in the net.But i use the
longdress_vox10_1051.ply to downsample by the code as :

import numpy as np
import open3d as o3d

def remove_outliers(pcd, nb_neighbors=20, std_ratio=2.0):
cl, ind = pcd.remove_statistical_outlier(nb_neighbors=nb_neighbors, std_ratio=std_ratio)
inlier_cloud = pcd.select_by_index(ind)
return inlier_cloud

def random_down_sample_with_outlier_removal(file_path, rate, nb_neighbors=20, std_ratio=2.0):
# 读取点云数据
pcd = o3d.io.read_point_cloud(file_path)

# 移除异常值
pcd_without_outliers = remove_outliers(pcd, nb_neighbors, std_ratio)

# 将点云数据转换为numpy数组
points = np.asarray(pcd_without_outliers.points).astype(np.float32)  # 将坐标属性转换为float32类型
colors = np.asarray(pcd_without_outliers.colors).astype(np.float32) if len(pcd_without_outliers.colors) > 0 else None  # 将颜色属性转换为float32类型

# 随机下采样
mask = np.random.choice([True, False], size=len(points), p=[rate, 1 - rate])
down_sampled_points = points[mask]
down_sampled_colors = colors[mask] if colors is not None else None

# 创建下采样后的点云
down_sampled_pcd = o3d.geometry.PointCloud()
down_sampled_pcd.points = o3d.utility.Vector3dVector(down_sampled_points)
if down_sampled_colors is not None:
    down_sampled_pcd.colors = o3d.utility.Vector3dVector(down_sampled_colors)

return down_sampled_pcd

down_sampled_pcd = random_down_sample_with_outlier_removal(r"D:\volumetric video\open 3d\draco\1\longdress_vox10_1051.ply", 0.8, nb_neighbors=20, std_ratio=2.0)

o3d.io.write_point_cloud(r"D:\volumetric video\open 3d\draco\2\longdress_vox10_1051_0.8.ply", down_sampled_pcd, write_ascii=True)

I got the downsampled point cloud file longdress_vox10_1051_0.8.ply by the code. Then i want to longdress_vox10_1051_0.8.ply to compress.so i compress it by the code as:

import os
import subprocess

def compress_point_cloud(file_path, output_path):
try:
output_file_path = os.path.join(output_path, os.path.basename(file_path).replace(".ply", ".drc"))
command = ["D:/volumetric video/open 3d/draco/draco_encoder.exe", "-i", file_path, "-o", output_file_path]

    process = subprocess.Popen(command, cwd="D:/volumetric video/open 3d/draco", stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE)
    stdout, stderr = process.communicate()

    if process.returncode == 0:
        print(f"{file_path} 压缩完成,压缩文件保存在:{output_file_path}")
    else:
        if stderr:
            error_msg = stderr.decode()
        else:
            error_msg = "未知错误"
        print("压缩失败:", error_msg)

except FileNotFoundError as e:
    print("文件未找到:", e)
except subprocess.CalledProcessError as e:
    print("调用子进程错误:", e)
except OSError as e:
    print("系统调用错误:", e)
except Exception as e:
    print("压缩出现异常:", e)

if name == "main":
patch_path = r"D:\volumetric video\open 3d\draco\2\longdress_vox10_1051_0.8.ply"
output_path = r"D:\volumetric video\open 3d\draco\2"
compress_point_cloud(patch_path, output_path)
It failed. I did't change anything except the point cloud file i was compressing.I work when i compress the longdress_vox10_1051.ply,but when i compress the downsampled point cloud file longdress_vox10_1051_0.8.ply,it failed. An exception was thrown at run time:压缩失败: 未知错误(it mean Compression failure: unknown error)
I try many times .But it did't work.Can you tell me why?What causes compression failure when i compress the downsampled point cloud file?

@Zhouwudexiazhou
Copy link
Author

I ran the compressed code directly from the command line, and here is the result:
image
So,the reason is that use open3d's o3d.io.write_point_cloud("longdress_vox10_1051_0.8_float32.ply", down_sampled_pcd, write_ascii=False) to save a point cloud file. Its xyz coordinate type is saved as' double 'by default, so I was wondering if I could just compress it with the object, But the command you gave to compress draco_cencoder also needs to pass in the path of the necessary point cloud files such as./draco_encoder -i./1/longdress_vox10_1051.ply -o out.drc, so now both sides are stuck, So can you compress the point cloud object pcd directly instead of the point cloud file path, because once you save the file with open3d, its type xyz will become a double, and draco_encoder requires that the type of the point cloud file point be float and int.
So can you tell me the way to this problem?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant