1
$\begingroup$

I wrote a Python script that exports Pointclouds (only vertices) and their vertex-colors (stored in color_attributes) to a .PLY file. The color on the exported .PLY file is way darker than the original color in Blender. I suppose this is due to sRGB - uchar RBG conversion issues. How can I convert the colors correctly so the exported pointcloud appears like in Blender?

import bpy
import os

# Get the active mesh object
obj = bpy.context.active_object

# Extract vertex coordinates and color values
verts = [v.co for v in obj.data.vertices]
colors = [(obj.data.color_attributes["col"].data[i].color[0], obj.data.color_attributes["col"].data[i].color[1], obj.data.color_attributes["col"].data[i].color[2]) for i in range(len(obj.data.vertices))]

# Convert float color values to uchar RGB values
colors = [[int(c * 255 + 0.5) for c in color] for color in colors]

#Combine vertex coordinates and colors
vertex_data = [(*verts[i], *colors[i]) for i in range(len(verts))]

# Get the path to the desktop
desktop_path = os.path.join(os.path.expanduser("~"), "Desktop")

# Create the .ply file on the desktop
file_path = os.path.join(desktop_path, "pointcloud.ply")

# Write the data to the .ply file
with open(file_path, "w") as f:
    # Write the header
    f.write("ply\n")
    f.write("format ascii 1.0\n")
    f.write(f"element vertex {len(verts)}\n")
    f.write("property float x\n")
    f.write("property float y\n")
    f.write("property float z\n")
    f.write("property uchar red\n")
    f.write("property uchar green\n")
    f.write("property uchar blue\n")
    f.write("end_header\n") 

    # Write the vertex data
    for v in vertex_data:
       f.write(" ".join(str(x) for x in v) + "\n")

# Close the file
f.close()
print("success")

Blender colors

Colors after export

$\endgroup$

1 Answer 1

2
$\begingroup$

Since version 3.4 there is a color_srgb property for color attributes that will return the color in sRGB space.

colors = [
    datum.color_srgb[:3]
    for datum in obj.data.color_attributes["col"].data
]

I notice however you are using 3.3, in which case you can use mathutils.Color.from_scene_linear_to_srgb (added in 3.2) to convert each color from linear to sRGB.

color_linear = mathutils.Color(datum.color[:3])
color_srgb = color_linear.from_scene_linear_to_srgb()
$\endgroup$
1
  • $\begingroup$ Thanks a lot, that soled the issue. $\endgroup$
    – op. 111
    Commented Feb 11, 2023 at 10:48

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .