14
14
from collections import namedtuple
15
15
from io import BytesIO , TextIOBase
16
16
from pathlib import Path
17
- from typing import List , Optional , Tuple , Union
17
+ from typing import List , Optional , Tuple , Union , cast
18
18
19
19
import numpy as np
20
20
import torch
@@ -780,10 +780,24 @@ def _load_ply_raw(f, path_manager: PathManager) -> Tuple[_PlyHeader, dict]:
780
780
781
781
def _get_verts_column_indices (
782
782
vertex_head : _PlyElementType ,
783
- ) -> Tuple [List [int ], Optional [List [int ]]]:
783
+ ) -> Tuple [List [int ], Optional [List [int ]], float ]:
784
784
"""
785
785
Get the columns of verts and verts_colors in the vertex
786
- element of a parsed ply file.
786
+ element of a parsed ply file, together with a color scale factor.
787
+ When the colors are in byte format, they are scaled from 0..255 to [0,1].
788
+ Otherwise they are not scaled.
789
+
790
+ For example, if the vertex element looks as follows:
791
+
792
+ element vertex 892
793
+ property double x
794
+ property double y
795
+ property double z
796
+ property uchar red
797
+ property uchar green
798
+ property uchar blue
799
+
800
+ then the return value will be ([0,1,2], [6,7,8], 1.0/255)
787
801
788
802
Args:
789
803
vertex_head: as returned from load_ply_raw.
@@ -792,6 +806,7 @@ def _get_verts_column_indices(
792
806
point_idxs: List[int] of 3 point columns.
793
807
color_idxs: List[int] of 3 color columns if they are present,
794
808
otherwise None.
809
+ color_scale: value to scale colors by.
795
810
"""
796
811
point_idxs : List [Optional [int ]] = [None , None , None ]
797
812
color_idxs : List [Optional [int ]] = [None , None , None ]
@@ -806,9 +821,17 @@ def _get_verts_column_indices(
806
821
color_idxs [j ] = i
807
822
if None in point_idxs :
808
823
raise ValueError ("Invalid vertices in file." )
809
- if None in color_idxs :
810
- return point_idxs , None
811
- return point_idxs , color_idxs
824
+ color_scale = 1.0
825
+ if all (
826
+ idx is not None and _PLY_TYPES [vertex_head .properties [idx ].data_type ].size == 1
827
+ for idx in color_idxs
828
+ ):
829
+ color_scale = 1.0 / 255
830
+ return (
831
+ point_idxs ,
832
+ None if None in color_idxs else cast (List [int ], color_idxs ),
833
+ color_scale ,
834
+ )
812
835
813
836
814
837
def _get_verts (
@@ -831,7 +854,7 @@ def _get_verts(
831
854
if not isinstance (vertex , list ):
832
855
raise ValueError ("Invalid vertices in file." )
833
856
vertex_head = next (head for head in header .elements if head .name == "vertex" )
834
- point_idxs , color_idxs = _get_verts_column_indices (vertex_head )
857
+ point_idxs , color_idxs , color_scale = _get_verts_column_indices (vertex_head )
835
858
836
859
# Case of no vertices
837
860
if vertex_head .count == 0 :
@@ -856,7 +879,9 @@ def _get_verts(
856
879
# so it was read as a single array and we can index straight into it.
857
880
verts = torch .tensor (vertex [0 ][:, point_idxs ], dtype = torch .float32 )
858
881
if color_idxs is not None :
859
- vertex_colors = torch .tensor (vertex [0 ][:, color_idxs ], dtype = torch .float32 )
882
+ vertex_colors = color_scale * torch .tensor (
883
+ vertex [0 ][:, color_idxs ], dtype = torch .float32
884
+ )
860
885
else :
861
886
# The vertex element is heterogeneous. It was read as several arrays,
862
887
# part by part, where a part is a set of properties with the same type.
@@ -887,6 +912,7 @@ def _get_verts(
887
912
for color in range (3 ):
888
913
partnum , col = prop_to_partnum_col [color_idxs [color ]]
889
914
vertex_colors .numpy ()[:, color ] = vertex [partnum ][:, col ]
915
+ vertex_colors *= color_scale
890
916
891
917
return verts , vertex_colors
892
918
0 commit comments