コード例 #1
0
ファイル: views.py プロジェクト: ngageoint/voxel-globe
def write_ply_file(points):
  '''
  Given a string of comma-separated values that represent 2d points, parse
  the string, create a ply file in the temp storage directory representing
  the shape formed by the string, and return the filepath.
  '''

  import voxel_globe.tools
  with voxel_globe.tools.storage_dir('event_trigger_ply') as ply_dir:
    num_files = len([name for name in os.listdir(ply_dir)])
    filepath = os.path.join(ply_dir, 'mesh_%d.ply' % num_files)
  
  import numpy
  import plyfile
  from plyfile import PlyData, PlyElement
  
  vertex = numpy.array(points,
                      dtype=[('x', 'double'), ('y', 'double'),
                             ('z', 'double')])
  face = numpy.array([(range(len(points)),)], [('vertex_indices', '|O')])
  el1 = PlyElement.describe(vertex, 'vertex')
  el2 = PlyElement.describe(face, 'face')
  
  PlyData([el1, el2], text=True, comments=['mesh-feature'], 
    obj_info=['a bmsh3d_mesh object']).write(filepath)

  return filepath
コード例 #2
0
ファイル: test_plyfile.py プロジェクト: 4sp1r3/python-plyfile
def tet_ply(text, byte_order):
    vertex = numpy.array([(0, 0, 0), (0, 1, 1), (1, 0, 1), (1, 1, 0)], dtype=[("x", "f4"), ("y", "f4"), ("z", "f4")])

    face = numpy.array(
        [([0, 1, 2], 255, 255, 255), ([0, 2, 3], 255, 0, 0), ([0, 1, 3], 0, 255, 0), ([1, 2, 3], 0, 0, 255)],
        dtype=[("vertex_indices", "i4", (3,)), ("red", "u1"), ("green", "u1"), ("blue", "u1")],
    )

    return PlyData(
        [PlyElement.describe(vertex, "vertex", comments=["tetrahedron vertices"]), PlyElement.describe(face, "face")],
        text=text,
        byte_order=byte_order,
        comments=["single tetrahedron with colored faces"],
    )
コード例 #3
0
ファイル: mesh.py プロジェクト: JinlongYANG/sp
    def save_ply(self, filename):
        vertex = np.array([tuple(i) for i in self.v], dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4')])
        face = np.array([(tuple(i), 0, 100, 255) for i in self.f] , 
            dtype=[('vertex_indices', 'i4', (3,)),
            ('red', 'u1'), ('green', 'u1'),
            ('blue', 'u1')])
	edge = np.array([(tuple(i)[0], tuple(i)[1], 255, 255, 255) for i in self.e] , 
            dtype=[('vertex1', 'i4'), ('vertex2', 'i4'),
            ('red', 'u1'), ('green', 'u1'),
            ('blue', 'u1')])
        el = PlyElement.describe(vertex, 'vertex')
        el2 = PlyElement.describe(face, 'face')
	el3 = PlyElement.describe(edge, 'edge')
        plydata = PlyData([el, el2, el3])
        plydata.write(filename)
コード例 #4
0
ファイル: normals.py プロジェクト: shawn-lo/532cv
 def write_ply(self, coords, normals, path):
     l = []
     size = coords.shape[0]
     for i in range(0, size):
         l.append((coords[i][0], coords[i][1], coords[i][2], normals[i][0], normals[i][1], normals[i][2]))
     vertex = np.array(l, dtype=[('x', 'f4'),('y', 'f4'),('z', 'f4'),('nx','f4'),('ny','f4'),('nz','f4')])
     el = PlyElement.describe(vertex, 'vertex')
     PlyData([el]).write(path)
コード例 #5
0
ファイル: test_plyfile.py プロジェクト: 4sp1r3/python-plyfile
def test_assign_elements(tet_ply_txt):
    test = PlyElement.describe(numpy.zeros(1, dtype=[("a", "i4")]), "test")
    tet_ply_txt.elements = [test]
    assert len(tet_ply_txt.elements) == 1
    assert len(tet_ply_txt) == 1
    assert "vertex" not in tet_ply_txt
    assert "face" not in tet_ply_txt
    assert "test" in tet_ply_txt

    for (k, elt) in enumerate(tet_ply_txt):
        assert elt.name == "test"
        assert k == 0
コード例 #6
0
def CreatePLY(P1,parameters,filename,surf_type,originalPLYfile):
        x1 = P1[:,0]
        y1 = P1[:,1]
        z1 = P1[:,2]

        if surf_type == 'lin':
            z1new = np.hstack((x1,y1,np.matrix(np.ones(np.size(P1,0))).T))*parameters
        else:
            z1new = np.hstack((np.multiply(x1,x1),np.multiply(y1,y1), np.multiply(x1,y1), x1, y1,np.matrix(np.ones(np.size(P1,0))).T))*parameters

        originalPLY = PLYLoader(originalPLYfile)
        point_cloud = (originalPLY.get_points()).T
        color_matrix = (originalPLY.get_colors()).T
        normals_matrix = (originalPLY.get_normals()).T

        x1 = np.array(x1)
        y1 = np.array(y1)
        z1new = np.array(z1new)

        x = point_cloud[:,0]
    	y = point_cloud[:,1]
    	z = point_cloud[:,2]

    	new_pointcloud = np.zeros((np.size(P1,0), 9))
    	pdb.set_trace()
    	
    	for Prow in range(len(x1)):
    		print 'Prow = ' 
    		print Prow
    		for originalPLY_row in range(len(x)):
    			if ((x[originalPLY_row] == x1[Prow]) and (y[originalPLY_row] == y1[Prow])):
    				print 'found'
    				print Prow
    				#point_cloud[originalPLY_row,2] = z1new[Prow]
    				new_pointcloud[Prow,0:2] = (P1[Prow,0:2])
    				new_pointcloud[Prow,2] = (z1new[Prow])
    				new_pointcloud[Prow,3:6] = (normals_matrix[originalPLY_row,:])
    				new_pointcloud[Prow,6:9] = color_matrix[originalPLY_row,:]

    				


    	pdb.set_trace()
    	#vertex = point_cloud

    	#new_mat = np.concatenate((vertex,normals_matrix,color_matrix),axis=1)
    	new_mat = new_pointcloud
    	vertex_new = map(tuple, new_mat)
    	vertex_new = np.array(vertex_new, dtype=[('x', 'f4'), ('y', 'f4'),('z', 'f4'),('nx','f4'),('ny','f4'),('nz','f4'),('diffuse_red', 'u1'), ('diffuse_green', 'u1'),('diffuse_blue', 'u1')])
    	el = PlyElement.describe(vertex_new, 'vertex')

    	
    	PlyData([el], text=True).write(filename)
コード例 #7
0
ファイル: test_plyfile.py プロジェクト: 4sp1r3/python-plyfile
def test_list_property_type(tmpdir, np_type):
    a = numpy.array([([0],), ([1, 2, 3],)], dtype=[("x", object)])

    ply0 = PlyData([PlyElement.describe(a, "test", val_types={"x": np_type})])

    assert ply0.elements[0].name == "test"
    assert ply0.elements[0].properties[0].name == "x"
    assert ply0.elements[0].properties[0].val_dtype == np_type

    ply1 = write_read(ply0, tmpdir)

    assert ply1.elements[0].name == "test"
    assert ply1.elements[0].data[0]["x"].dtype == numpy.dtype(np_type)
    verify(ply0, ply1)
コード例 #8
0
ファイル: test_plyfile.py プロジェクト: 4sp1r3/python-plyfile
def test_property_type(tmpdir, np_type):
    dtype = [("x", np_type), ("y", np_type), ("z", np_type)]
    a = numpy.array([(1, 2, 3), (4, 5, 6)], dtype=dtype)

    ply0 = PlyData([PlyElement.describe(a, "test")])

    assert ply0.elements[0].name == "test"
    assert ply0.elements[0].properties[0].name == "x"
    assert ply0.elements[0].properties[0].val_dtype == np_type
    assert ply0.elements[0].properties[1].name == "y"
    assert ply0.elements[0].properties[1].val_dtype == np_type
    assert ply0.elements[0].properties[2].name == "z"
    assert ply0.elements[0].properties[2].val_dtype == np_type

    ply1 = write_read(ply0, tmpdir)

    assert ply1.elements[0].name == "test"
    assert ply1.elements[0].data.dtype == dtype
    verify(ply0, ply1)
コード例 #9
0
def filter_depth(scan_folder, out_folder, plyfilename):
    # the pair file
    pair_file = os.path.join(scan_folder, "pair.txt")
    # for the final point cloud
    vertexs = []
    vertex_colors = []

    pair_data = read_pair_file(pair_file)
    nviews = len(pair_data)
    # TODO: hardcode size
    # used_mask = [np.zeros([296, 400], dtype=np.bool) for _ in range(nviews)]

    # for each reference view and the corresponding source views
    for ref_view, src_views in pair_data:
        # load the camera parameters
        ref_intrinsics, ref_extrinsics = read_camera_parameters(
            os.path.join(scan_folder, 'cams/{:0>8}_cam.txt'.format(ref_view)))
        # load the reference image
        ref_img = read_img(
            os.path.join(scan_folder, 'images/{:0>8}.jpg'.format(ref_view)))
        # load the estimated depth of the reference view
        ref_depth_est = read_pfm(
            os.path.join(out_folder,
                         'depth_est/{:0>8}.pfm'.format(ref_view)))[0]
        # load the photometric mask of the reference view
        confidence = read_pfm(
            os.path.join(out_folder,
                         'confidence/{:0>8}.pfm'.format(ref_view)))[0]
        photo_mask = confidence > 0.8

        all_srcview_depth_ests = []
        all_srcview_x = []
        all_srcview_y = []
        all_srcview_geomask = []

        # compute the geometric mask
        geo_mask_sum = 0
        for src_view in src_views:
            # camera parameters of the source view
            src_intrinsics, src_extrinsics = read_camera_parameters(
                os.path.join(scan_folder,
                             'cams/{:0>8}_cam.txt'.format(src_view)))
            # the estimated depth of the source view
            src_depth_est = read_pfm(
                os.path.join(out_folder,
                             'depth_est/{:0>8}.pfm'.format(src_view)))[0]

            geo_mask, depth_reprojected, x2d_src, y2d_src = check_geometric_consistency(
                ref_depth_est, ref_intrinsics, ref_extrinsics, src_depth_est,
                src_intrinsics, src_extrinsics)
            geo_mask_sum += geo_mask.astype(np.int32)
            all_srcview_depth_ests.append(depth_reprojected)
            all_srcview_x.append(x2d_src)
            all_srcview_y.append(y2d_src)
            all_srcview_geomask.append(geo_mask)

        depth_est_averaged = (sum(all_srcview_depth_ests) +
                              ref_depth_est) / (geo_mask_sum + 1)
        # at least 3 source views matched
        geo_mask = geo_mask_sum >= 3
        final_mask = np.logical_and(photo_mask, geo_mask)

        os.makedirs(os.path.join(out_folder, "mask"), exist_ok=True)
        save_mask(
            os.path.join(out_folder, "mask/{:0>8}_photo.png".format(ref_view)),
            photo_mask)
        save_mask(
            os.path.join(out_folder, "mask/{:0>8}_geo.png".format(ref_view)),
            geo_mask)
        save_mask(
            os.path.join(out_folder, "mask/{:0>8}_final.png".format(ref_view)),
            final_mask)

        print("processing {}, ref-view{:0>2}, photo/geo/final-mask:{}/{}/{}".
              format(scan_folder, ref_view, photo_mask.mean(), geo_mask.mean(),
                     final_mask.mean()))

        if args.display:
            import cv2
            cv2.imshow('ref_img', ref_img[:, :, ::-1])
            cv2.imshow('ref_depth', ref_depth_est / 800)
            cv2.imshow('ref_depth * photo_mask',
                       ref_depth_est * photo_mask.astype(np.float32) / 800)
            cv2.imshow('ref_depth * geo_mask',
                       ref_depth_est * geo_mask.astype(np.float32) / 800)
            cv2.imshow('ref_depth * mask',
                       ref_depth_est * final_mask.astype(np.float32) / 800)
            cv2.waitKey(0)

        height, width = depth_est_averaged.shape[:2]
        x, y = np.meshgrid(np.arange(0, width), np.arange(0, height))
        # valid_points = np.logical_and(final_mask, ~used_mask[ref_view])
        valid_points = final_mask
        print("valid_points", valid_points.mean())
        x, y, depth = x[valid_points], y[valid_points], depth_est_averaged[
            valid_points]
        color = ref_img[1:-16:4,
                        1::4, :][valid_points]  # hardcoded for DTU dataset
        xyz_ref = np.matmul(np.linalg.inv(ref_intrinsics),
                            np.vstack((x, y, np.ones_like(x))) * depth)
        xyz_world = np.matmul(np.linalg.inv(ref_extrinsics),
                              np.vstack((xyz_ref, np.ones_like(x))))[:3]
        vertexs.append(xyz_world.transpose((1, 0)))
        vertex_colors.append((color * 255).astype(np.uint8))

        # # set used_mask[ref_view]
        # used_mask[ref_view][...] = True
        # for idx, src_view in enumerate(src_views):
        #     src_mask = np.logical_and(final_mask, all_srcview_geomask[idx])
        #     src_y = all_srcview_y[idx].astype(np.int)
        #     src_x = all_srcview_x[idx].astype(np.int)
        #     used_mask[src_view][src_y[src_mask], src_x[src_mask]] = True

    vertexs = np.concatenate(vertexs, axis=0)
    vertex_colors = np.concatenate(vertex_colors, axis=0)
    vertexs = np.array([tuple(v) for v in vertexs],
                       dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4')])
    vertex_colors = np.array([tuple(v) for v in vertex_colors],
                             dtype=[('red', 'u1'), ('green', 'u1'),
                                    ('blue', 'u1')])

    vertex_all = np.empty(len(vertexs),
                          vertexs.dtype.descr + vertex_colors.dtype.descr)
    for prop in vertexs.dtype.names:
        vertex_all[prop] = vertexs[prop]
    for prop in vertex_colors.dtype.names:
        vertex_all[prop] = vertex_colors[prop]

    el = PlyElement.describe(vertex_all, 'vertex')
    PlyData([el]).write(plyfilename)
    print("saving the final model to", plyfilename)
コード例 #10
0
ファイル: pc_utils.py プロジェクト: CurryYuan/InstanceRefer
def write_ply(points, filename, text=True):
    """ input: Nx3, write points to filename as PLY format. """
    points = [(points[i,0], points[i,1], points[i,2]) for i in range(points.shape[0])]
    vertex = np.array(points, dtype=[('x', 'f4'), ('y', 'f4'),('z', 'f4')])
    el = PlyElement.describe(vertex, 'vertex', comments=['vertices'])
    PlyData([el], text=text).write(filename)
コード例 #11
0
programSV3DRegion = glumpy_setting.ProgramSV3DRegion(
    data=data, name=None, point_size=1, anchor=anchor_matrix_whole)
gpyWindow.add_program(programSV3DRegion)

print(data['a_position'][0, 0, 0])
print(np.isnan(data['a_position'][0, 0, 0]))
print(~np.isnan(data['a_position'][0, 0, 0]))
data['a_color'] *= 255
data['a_color'].astype(int)

data = data[np.nonzero(~np.isnan(data['a_position'][:, :, 0]))]
xyzzz = np.zeros(len(data),
                 dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4'), ('r', 'f4'),
                        ('g', 'f4'), ('b', 'f4')])
xyzzz['x'] = data['a_position'][:, 0]
xyzzz['y'] = data['a_position'][:, 1]
xyzzz['z'] = data['a_position'][:, 2]
xyzzz['r'] = data['a_color'][:, 0]
xyzzz['g'] = data['a_color'][:, 1]
xyzzz['b'] = data['a_color'][:, 2]
el = PlyElement.describe(xyzzz, 'vertex')

PlyData([el]).write('some_binary.ply')
PlyData([el], text=True).write('some_ascii.ply')

programAxis = glumpy_setting.ProgramAxis(line_length=5)
gpyWindow.add_program(programAxis)

gpyWindow.run()
コード例 #12
0
func = np.exp(-mesh[0]**2 / 500.0) * np.exp(-mesh[1]**2 / 750.0) * surf

x, y, z = mesh[0].flatten(), mesh[1].flatten(), surf.flatten()
data = func.flatten()

n0, n1 = func.shape
v_list, f_list = [], []
for i0 in range(n0):
    for j0 in range(n1):
        i1, j1 = i0 + 1, j0 + 1
        v_list.append(
            (mesh[0][i0, j0], mesh[1][i0, j0], surf[i0, j0], func[i0, j0]))
for i0 in range(n0 - 1):
    for j0 in range(n1 - 1):
        i1, j1 = i0 + 1, j0 + 1
        v_n00 = i0 * n1 + j0
        v_n01 = v_n00 + 1
        v_n10 = v_n00 + n1
        v_n11 = v_n10 + 1
        val = (func[i0, j0] + func[i0, j1] + func[i1, j0] + func[i1, j1]) / 4
        f_list.append(([v_n00, v_n01, v_n11, v_n10], val))
vertex = np.array(v_list,
                  dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4'),
                         ('data', 'f4')])
face = np.array(f_list,
                dtype=[('vertex_indices', 'i4', (4, )), ('face_color', 'f4')])
elv = PlyElement.describe(vertex, "vertex")
elf = PlyElement.describe(face, "face")

PlyData([elv, elf], text=True).write('./create_ply_simple1.ply')
コード例 #13
0
def test_element_parse_error_repr():
    prop = PlyProperty('x', 'f4')
    elt = PlyElement('test', [prop], 0)
    e = PlyElementParseError('text', elt, 0, prop)
    assert repr(e)
コード例 #14
0
def test_invalid_array(a):
    with Raises(ValueError):
        PlyElement.describe(a, 'test')
コード例 #15
0
def gen_box_and_pl(ply_fn, box_vertexes, pl_xyz=None, extra=''):
    '''
    Generate box and points together in the same file. box_vertexes and pl_xyz
      independently. The 8 vertexs are included automatically in the box.
      pl_xyz is used to provide other points.
    box_vertexes:[num_box,8,3]
    pl_xyz:  [num_point,3]
    '''
    assert box_vertexes.ndim == 3
    assert box_vertexes.shape[1] == 8
    assert box_vertexes.shape[-1] == 3

    box_vertexes = np.reshape(box_vertexes, (-1, 3))
    num_box = box_vertexes.shape[0] // 8
    if type(pl_xyz) != type(None):
        assert pl_xyz.shape[-1] == 3
        pl_xyz = np.reshape(pl_xyz, (-1, 3))
        num_vertex = box_vertexes.shape[0] + pl_xyz.shape[0]
    else:
        num_vertex = box_vertexes.shape[0]
    vertex = np.zeros(shape=(num_vertex)).astype([('x', 'f8'), ('y', 'f8'),
                                                  ('z', 'f8')])
    for i in range(box_vertexes.shape[0]):
        vertex[i] = (box_vertexes[i, 0], box_vertexes[i, 1], box_vertexes[i,
                                                                          2])

    if type(pl_xyz) != type(None):
        for i in range(pl_xyz.shape[0]):
            vertex[i + box_vertexes.shape[0]] = (pl_xyz[i, 0], pl_xyz[i, 1],
                                                 pl_xyz[i, 2])

    el_vertex = PlyElement.describe(vertex, 'vertex')

    # define the order of the 8 vertexs for a box
    edge_basic = np.array([(0, 1, 255, 0, 0), (1, 2, 255, 0, 0),
                           (2, 3, 255, 0, 0), (3, 0, 255, 0, 0),
                           (4, 5, 255, 0, 0), (5, 6, 255, 0, 0),
                           (6, 7, 255, 0, 0), (7, 4, 255, 0, 0),
                           (0, 4, 255, 0, 0), (1, 5, 255, 0, 0),
                           (2, 6, 255, 0, 0), (3, 7, 255, 0, 0)])
    if extra == 'random_color_between_boxes':
        color = np.random.randint(0, 256, 3)
        color[2] = 255 - color[0] - color[1]
    edge_basic[:, 2:5] = color

    edge_val = np.concatenate([edge_basic] * num_box, 0)
    for i in range(num_box):
        edge_val[i * 12:(i + 1) * 12, 0:2] += (8 * i)
    edge = np.zeros(shape=(edge_val.shape[0])).astype(
        dtype=[('vertex1',
                'i4'), ('vertex2',
                        'i4'), ('red', 'u1'), ('green', 'u1'), ('blue', 'u1')])
    for i in range(edge_val.shape[0]):
        edge[i] = (edge_val[i, 0], edge_val[i, 1], edge_val[i, 2],
                   edge_val[i, 3], edge_val[i, 4])
    el_edge = PlyElement.describe(edge, 'edge')

    dirname = os.path.dirname(ply_fn)
    if not os.path.exists(dirname):
        os.makedirs(dirname)
    PlyData([el_vertex, el_edge], text=True).write(ply_fn)
    print('write %s ok' % (ply_fn))
コード例 #16
0
    ##### Until mesh extraction here, it is the same as the original repo. ######

    vertices_ = (vertices/N).astype(np.float32)
    ## invert x and y coordinates (WHY? maybe because of the marching cubes algo)
    x_ = (ymax-ymin) * vertices_[:, 1] + ymin
    y_ = (xmax-xmin) * vertices_[:, 0] + xmin
    vertices_[:, 0] = x_
    vertices_[:, 1] = y_
    vertices_[:, 2] = (zmax-zmin) * vertices_[:, 2] + zmin
    vertices_.dtype = [('x', 'f4'), ('y', 'f4'), ('z', 'f4')]

    face = np.empty(len(triangles), dtype=[('vertex_indices', 'i4', (3,))])
    face['vertex_indices'] = triangles

    PlyData([PlyElement.describe(vertices_[:, 0], 'vertex'), 
             PlyElement.describe(face, 'face')]).write(f'{args.scene_name}.ply')

    # remove noise in the mesh by keeping only the biggest cluster
    print('Removing noise ...')
    mesh = o3d.io.read_triangle_mesh(f"{args.scene_name}.ply")
    idxs, count, _ = mesh.cluster_connected_triangles()
    max_cluster_idx = np.argmax(count)
    triangles_to_remove = [i for i in range(len(face)) if idxs[i] != max_cluster_idx]
    mesh.remove_triangles_by_index(triangles_to_remove)
    mesh.remove_unreferenced_vertices()
    print(f'Mesh has {len(mesh.vertices)/1e6:.2f} M vertices and {len(mesh.triangles)/1e6:.2f} M faces.')

    vertices_ = np.asarray(mesh.vertices).astype(np.float32)
    triangles = np.asarray(mesh.triangles)
コード例 #17
0
def write_PLY(fn, disp, Q, flagFlip=False, distLimit=100., mask=None, color=None, binary=True):
    """
    fn: The output filename.
    disp: The disparity. A NumPy array with dimension (H, W).
    mask: Logical NumPy array.
    Q: The reprojection matrix. A NumP array of dimension 4x4.
    color: The color image. The image could be (H, W) or (H, W, C).
           C could be 1 or 3. If color==None, no color properties 
           will be in the output PLY file.
    binary: Set True to write a binary format PLY file. Set False for
            a ASCII version.
    """

    disp = disp.copy()

    # Get the size of the image.
    H = disp.shape[0]
    W = disp.shape[1]

    # Make x and y.
    xLin = np.linspace( 0, W-1, W, dtype=np.float32 )
    yLin = np.linspace( 0, H-1, H, dtype=np.float32 )

    x, y = np.meshgrid( xLin, yLin )
    x = x.reshape((-1,))
    y = y.reshape((-1,))

    # Make the coordinate array.
    d  = disp.reshape((-1,))
    hg = np.ones((1, d.shape[0]), dtype=np.float32).reshape((-1,))

    # Mask.
    m  = d > 0
    nm = np.logical_not(m)
    m  = m.reshape((-1,))
    
    d[nm] = 1.0

    if ( mask is not None ):
        m = np.logical_and( m, mask.reshape((-1,)) )

    coor = np.stack( [ x, y, d, hg ], axis=-1 ).transpose()

    # Calculate the world coordinate.
    if ( flagFlip ):
        Q = Q.copy()
        Q[1, 1] *= -1
        Q[1, 3] *= -1
        Q[2, 3] *= -1

    coor = Q.dot( coor )

    coor[0, :] = coor[0, :] / coor[3, :]
    coor[1, :] = coor[1, :] / coor[3, :]
    coor[2, :] = coor[2, :] / coor[3, :]

    coor = coor.transpose()[:, 0:3]

    # Filter the points. Only keep the points within distLimit.
    dispMask = np.abs( coor[:, 2] ) <= distLimit
    m = np.logical_and( m, dispMask.reshape((-1,)) )

    # Handle color.
    if ( color is not None ):
        if ( 2 == len( color.shape ) ):
            color = np.stack([ color, color, color ], axis=-1)
        
        color = color.reshape(-1, 3)
        color = color[m, 0:3]
        coor  = coor[m, 0:3]
        
        color = np.clip( color, 0, 255 ).astype(np.uint8)

        # Concatenate.
        vertex = np.concatenate([coor, color], axis=1)

        # Create finial vetex array.
        vertex = convert_2D_array_2_1D_list(vertex)
        vertex = np.array( vertex, dtype=[\
            ( "x", "f4" ), \
            ( "y", "f4" ), \
            ( "z", "f4" ), \
            ( "red", "u1" ), \
            ( "green", "u1" ), \
            ( "blue", "u1" ) \
            ] )
    else:
        coor = convert_2D_array_2_1D_list(coor)
        vertex = np.array( coor, dtype=[\
            ( "x", "f4" ), \
            ( "y", "f4" ), \
            ( "z", "f4" ) \
            ] )
    
    # Save the PLY file.
    el = PlyElement.describe(vertex, "vertex")

    PlyData([el], text= (not binary) ).write(fn)
コード例 #18
0
ファイル: kinectapi.py プロジェクト: wanweiwei07/pyhiro
    def getMakerXYZ(self, markercolumnid, markerrowid, markerdepth):
        if markerdepth > 0:
            point3d = self.kinect.mapper().MapDepthPointToCameraSpace(
                PyKinectV2._DepthSpacePoint(ctypes.c_float(markercolumnid), ctypes.c_float(markerrowid)),
                ctypes.c_ushort(markerdepth))
            return [point3d.x, point3d.y, point3d.z]
        else:
            return []

if __name__=='__main__':

    base = pandactrl.World(camp=[0,0,3000], lookatp=[0,0,0])

    kapi = KinectAPI()
    # points
    pntclds = kapi.getPointCloud()

    colors = []
    color = [np.random.rand(), np.random.rand(), np.random.rand(), np.random.rand()]
    for pnt in pntclds:
        colors.append(color)
    pntsnp = pg.genPntsnp(pntclds, colors=colors)
    pntsnp.reparentTo(base.render)

    from plyfile import PlyData, PlyElement
    verts = np.array(pntclds, dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4')])
    el = PlyElement.describe(verts, 'vertex')
    PlyData([el], text=True).write('pythoncloud.ply')

    base.run()
コード例 #19
0
ファイル: show.py プロジェクト: rafalcieslak/ComVis
def save_to_ply(points, filename):
    points = np.array(points,
                      dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4'),
                             ('red', 'u1'), ('green', 'u1'), ('blue', 'u1')])
    el = PlyElement.describe(points, 'vertex')
    PlyData([el]).write(filename)
コード例 #20
0
from plyfile import PlyData, PlyElement
import numpy as np

# p = PlyData.read("../data/feature_1.ply")
# print(p)

a = np.array([(0, 0, 0), (0, 1, 1), (1, 0, 1), (1, 1, 0)],
             dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4')])
print(a)
el = PlyElement.describe(a, 'myvertices')
PlyData([el]).write('some_binary.ply')
PlyData([el], text=True).write('some_ascii.ply')
コード例 #21
0
def create_ply(xyz0,
               ply_fn,
               label=None,
               label2color=None,
               force_color=None,
               box=None,
               cut_threshold=[1, 1, 1]):
    '''
    xyz0: (num_block,num_point,3) or (num_point,3) or (num_block,num_point,6) or (num_point,6)
    label: (num_block,num_point) or (num_point)
    force_color: (3,)

    (1) color in xyz0: xyz0.shape[-]==6,  label=None, label2color=None
    (2) no color: xyz0.shape[-1]==3, label=None, label2color=None
    (3) color by label: xyz0.shape[-1]==3,label.shape= (num_block,num_point) or (num_point)
    (4) set consistent color: xyz0.shape[-1]==3, label=None, label2color=None, force_color=[255,0,0]
  '''
    print(ply_fn)
    folder = os.path.dirname(ply_fn)
    if not os.path.exists(folder):
        os.makedirs(folder)
    new_xyz_ls = []
    is_keep_ls = []
    is_cut = xyz0.ndim >= 3
    if is_cut:
        for i in range(xyz0.shape[0]):
            new_xyz_i, is_keep_i = cut_xyz(xyz0[i], cut_threshold)
            new_xyz_ls.append(new_xyz_i)
            is_keep_ls.append(is_keep_i)
        xyz = np.concatenate(new_xyz_ls, 0)
        is_keep = np.concatenate(is_keep_ls, 0)
    else:
        xyz = xyz0

    if xyz.shape[-1] == 3:
        if type(label) != type(None) and label2color != None:
            #(3) color by label: xyz0.shape[-1]==3,label.shape= (num_block,num_point) or (num_point)
            label2color_ls = []
            for i in range(len(label2color)):
                label2color_ls.append(
                    np.reshape(np.array(label2color[i]), (1, 3)))
            label2colors = np.concatenate(label2color_ls, 0)
            color = np.take(label2colors, label, axis=0)
            color = np.reshape(color, (-1, 3))
            if is_cut:
                color = color[is_keep, :]
            xyz = np.concatenate([xyz, color], -1)
        elif type(force_color) != type(None):
            #(4) set consistent color: xyz0.shape[-1]==3, label=None, label2color=None, force_color=[255,0,0]
            color = np.reshape(np.array(force_color), [1, 3])
            color = np.tile(color, [xyz.shape[0], 1])
            xyz = np.concatenate([xyz, color], -1)
    if xyz.shape[-1] == 3:
        #(2) no color: xyz0.shape[-1]==3, label=None, label2color=None
        vertex = np.zeros(shape=(xyz.shape[0])).astype([('x', 'f8'),
                                                        ('y', 'f8'),
                                                        ('z', 'f8')])
        for i in range(xyz.shape[0]):
            vertex[i] = (xyz[i, 0], xyz[i, 1], xyz[i, 2])
    elif xyz.shape[-1] == 6:
        vertex = np.zeros(shape=(xyz.shape[0])).astype([('x', 'f8'),
                                                        ('y', 'f8'),
                                                        ('z', 'f8'),
                                                        ('red', 'u1'),
                                                        ('green', 'u1'),
                                                        ('blue', 'u1')])
        for i in range(xyz.shape[0]):
            vertex[i] = (xyz[i, 0], xyz[i, 1], xyz[i, 2], xyz[i, 3], xyz[i, 4],
                         xyz[i, 5])
    else:
        raise NotImplementedError

    el_vertex = PlyElement.describe(vertex, 'vertex')
    PlyData([el_vertex], text=True).write(ply_fn)

    print('save ply file: %s' % (ply_fn))
コード例 #22
0
ファイル: pc_utils.py プロジェクト: xuyongzhi/CorDet
 def write_ply(array, filepath):
     ply_el = PlyElement.describe(array, 'vertex')
     target_path, _ = os.path.split(filepath)
     if target_path != '' and not os.path.exists(target_path):
         os.makedirs(target_path)
     PlyData([ply_el]).write(filepath)
コード例 #23
0
ファイル: extract_color_mesh.py プロジェクト: zuru/nerf_pl
    ##### Until mesh extraction here, it is the same as the original repo. ######

    vertices_ = (vertices / N).astype(np.float32)
    ## invert x and y coordinates (WHY? maybe because of the marching cubes algo)
    x_ = (ymax - ymin) * vertices_[:, 1] + ymin
    y_ = (xmax - xmin) * vertices_[:, 0] + xmin
    vertices_[:, 0] = x_
    vertices_[:, 1] = y_
    vertices_[:, 2] = (zmax - zmin) * vertices_[:, 2] + zmin
    vertices_.dtype = [('x', 'f4'), ('y', 'f4'), ('z', 'f4')]

    face = np.empty(len(triangles), dtype=[('vertex_indices', 'i4', (3, ))])
    face['vertex_indices'] = triangles

    PlyData([
        PlyElement.describe(vertices_[:, 0], 'vertex'),
        PlyElement.describe(face, 'face')
    ]).write(f'{args.scene_name}.ply')

    # remove noise in the mesh by keeping only the biggest cluster
    print('Removing noise ...')
    mesh = o3d.io.read_triangle_mesh(f"{args.scene_name}.ply")
    idxs, count, _ = mesh.cluster_connected_triangles()
    max_cluster_idx = np.argmax(count)
    triangles_to_remove = [
        i for i in range(len(face)) if idxs[i] != max_cluster_idx
    ]
    mesh.remove_triangles_by_index(triangles_to_remove)
    mesh.remove_unreferenced_vertices()
    print(
        f'Mesh has {len(mesh.vertices)/1e6:.2f} M vertices and {len(mesh.triangles)/1e6:.2f} M faces.'
コード例 #24
0
# for i0 in range(n0):
#    for j0 in range(n1):
#        i1, j1 = i0 + 1, j0 + 1
#        v_list.append((
#            mesh[0][i0, j0],
#            mesh[1][i0, j0],
#            surf[i0, j0],
#            func[i0, j0]
#        ))
# for i0 in range(n0 - 1):
#    for j0 in range(n1 - 1):
#        i1, j1 = i0 + 1, j0 + 1
#        v_n00 = i0 * n1 + j0
#        v_n01 = v_n00 + 1
#        v_n10 = v_n00 + n1
#        v_n11 = v_n10 + 1
#        val = (func[i0, j0] + func[i0, j1] + func[i1, j0] + func[i1, j1]) / 4
#        f_list.append((
#            [v_n00, v_n01, v_n11, v_n10],
#            val
#        ))
vertex = np.array(v_list,
                  dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4'),
                         ('data', 'f4')])
elv = PlyElement.describe(vertex, "vertex")
# face = np.array(
#    f_list, dtype=[('vertex_indices', 'i4', (4,)), ('face_color', 'f4')])
#elf = PlyElement.describe(face, "face")

PlyData([elv], text=True).write('./create_ply_simple3.ply')
コード例 #25
0
def export_ply(pc, filename):
	vertex = np.zeros(pc.shape[0], dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4')])
	for i in range(pc.shape[0]):
		vertex[i] = (pc[i][0], pc[i][1], pc[i][2])
	ply_out = PlyData([PlyElement.describe(vertex, 'vertex', comments=['vertices'])])
	ply_out.write(filename)
コード例 #26
0
def test_invalid_array_type():
    with Raises(TypeError):
        PlyElement.describe([0, 1, 2], 'test')
コード例 #27
0
ファイル: eval_eth.py プロジェクト: zhipengY/PatchmatchNet
def filter_depth(scan_folder, out_folder, plyfilename, geo_pixel_thres,
                 geo_depth_thres, photo_thres, img_wh, geo_mask_thres):
    # the pair file
    pair_file = os.path.join(scan_folder, "pair.txt")
    # for the final point cloud
    vertexs = []
    vertex_colors = []

    pair_data = read_pair_file(pair_file)
    nviews = len(pair_data)

    # for each reference view and the corresponding source views
    for ref_view, src_views in pair_data:

        # load the reference image
        ref_img, original_h, original_w = read_img(
            os.path.join(scan_folder, 'images/{:0>8}.jpg'.format(ref_view)),
            img_wh)
        ref_intrinsics, ref_extrinsics = read_cam_file(
            os.path.join(scan_folder,
                         'cams_1/{:0>8}_cam.txt'.format(ref_view)))[0:2]
        ref_intrinsics[0] *= img_wh[0] / original_w
        ref_intrinsics[1] *= img_wh[1] / original_h

        # load the estimated depth of the reference view
        ref_depth_est = read_pfm(
            os.path.join(out_folder,
                         'depth_est/{:0>8}.pfm'.format(ref_view)))[0]
        ref_depth_est = np.squeeze(ref_depth_est, 2)
        # load the photometric mask of the reference view
        confidence = read_pfm(
            os.path.join(out_folder,
                         'confidence/{:0>8}.pfm'.format(ref_view)))[0]

        photo_mask = confidence > photo_thres
        photo_mask = np.squeeze(photo_mask, 2)

        all_srcview_depth_ests = []

        # compute the geometric mask
        geo_mask_sum = 0
        for src_view in src_views:
            # camera parameters of the source view
            _, original_h, original_w = read_img(
                os.path.join(scan_folder,
                             'images/{:0>8}.jpg'.format(src_view)), img_wh)
            src_intrinsics, src_extrinsics = read_cam_file(
                os.path.join(scan_folder,
                             'cams_1/{:0>8}_cam.txt'.format(src_view)))[0:2]
            src_intrinsics[0] *= img_wh[0] / original_w
            src_intrinsics[1] *= img_wh[1] / original_h

            # the estimated depth of the source view
            src_depth_est = read_pfm(
                os.path.join(out_folder,
                             'depth_est/{:0>8}.pfm'.format(src_view)))[0]

            geo_mask, depth_reprojected, x2d_src, y2d_src = check_geometric_consistency(
                ref_depth_est, ref_intrinsics, ref_extrinsics, src_depth_est,
                src_intrinsics, src_extrinsics, geo_pixel_thres,
                geo_depth_thres)
            geo_mask_sum += geo_mask.astype(np.int32)
            all_srcview_depth_ests.append(depth_reprojected)

        depth_est_averaged = (sum(all_srcview_depth_ests) +
                              ref_depth_est) / (geo_mask_sum + 1)

        geo_mask = geo_mask_sum >= geo_mask_thres
        final_mask = np.logical_and(photo_mask, geo_mask)

        os.makedirs(os.path.join(out_folder, "mask"), exist_ok=True)
        save_mask(
            os.path.join(out_folder, "mask/{:0>8}_photo.png".format(ref_view)),
            photo_mask)
        save_mask(
            os.path.join(out_folder, "mask/{:0>8}_geo.png".format(ref_view)),
            geo_mask)
        save_mask(
            os.path.join(out_folder, "mask/{:0>8}_final.png".format(ref_view)),
            final_mask)

        if args.display:
            import cv2
            cv2.imshow('ref_img', ref_img[:, :, ::-1])
            cv2.imshow('ref_depth', ref_depth_est)
            cv2.imshow('ref_depth * photo_mask',
                       ref_depth_est * photo_mask.astype(np.float32))
            cv2.imshow('ref_depth * geo_mask',
                       ref_depth_est * geo_mask.astype(np.float32))
            cv2.imshow('ref_depth * mask',
                       ref_depth_est * final_mask.astype(np.float32))
            cv2.waitKey(1)

        height, width = depth_est_averaged.shape[:2]
        x, y = np.meshgrid(np.arange(0, width), np.arange(0, height))

        valid_points = final_mask

        x, y, depth = x[valid_points], y[valid_points], depth_est_averaged[
            valid_points]

        color = ref_img[valid_points]
        xyz_ref = np.matmul(np.linalg.inv(ref_intrinsics),
                            np.vstack((x, y, np.ones_like(x))) * depth)
        xyz_world = np.matmul(np.linalg.inv(ref_extrinsics),
                              np.vstack((xyz_ref, np.ones_like(x))))[:3]
        vertexs.append(xyz_world.transpose((1, 0)))
        vertex_colors.append((color * 255).astype(np.uint8))

    vertexs = np.concatenate(vertexs, axis=0)
    vertex_colors = np.concatenate(vertex_colors, axis=0)
    vertexs = np.array([tuple(v) for v in vertexs],
                       dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4')])
    vertex_colors = np.array([tuple(v) for v in vertex_colors],
                             dtype=[('red', 'u1'), ('green', 'u1'),
                                    ('blue', 'u1')])

    vertex_all = np.empty(len(vertexs),
                          vertexs.dtype.descr + vertex_colors.dtype.descr)
    for prop in vertexs.dtype.names:
        vertex_all[prop] = vertexs[prop]
    for prop in vertex_colors.dtype.names:
        vertex_all[prop] = vertex_colors[prop]

    el = PlyElement.describe(vertex_all, 'vertex')
    PlyData([el]).write(plyfilename)
    print("saving the final model to", plyfilename)
コード例 #28
0
quality_list_with_statistical_outliers = pointcloud_with_outliers[
    'vertex'].data['quality']

mean = numpy.mean(quality_list_with_statistical_outliers, axis=0)
print("The mean of the vertex radius is: " + mean.__str__())
sd = numpy.std(quality_list_with_statistical_outliers, axis=0)
print("The Standard Deviation of the vertex radius is: " + sd.__str__())

print("Removing all vertices above sigma of " +
      remove_all_vertices_above_sd_sigma_of.__str__())

list_of_vertices_without_SO = []

for index, x in enumerate(quality_list_with_statistical_outliers):
    if x < mean + remove_all_vertices_above_sd_sigma_of * sd:
        list_of_vertices_without_SO.append(
            pointcloud_with_outliers["vertex"][index])

print("Removed " + (len(quality_list_with_statistical_outliers) -
                    len(list_of_vertices_without_SO)).__str__() +
      " outlier vertices")
print("Creating PLY file now")

vertex = numpy.array(list_of_vertices_without_SO,
                     dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4'),
                            ('quality', 'f4'), ('radius', 'f4')])

new_ply_element = PlyElement.describe(vertex, "vertex")

PlyData([new_ply_element]).write("Temp_File_Without_Outliers.ply")
コード例 #29
0
def write_scene_pc(points, output_path):
    vertex = np.array([tuple(x) for x in points],
                      dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4'), ('red', 'u1'), ('green', 'u1'), ('blue', 'u1'), ])
    vertex_el = PlyElement.describe(vertex, 'vertex')
    PlyData([vertex_el]).write(output_path)  # write the new ply file
コード例 #30
0
ファイル: ppfmatch.py プロジェクト: wanweiwei07/pyhiro
    def match(self, perceivedpnts, perceivednormals, ddist = 5.0, dangle = 30.0):
        """
        do a match
        :return: rotmats of top matches

        author: weiwei
        date: 20170802
        """

        # save txt
        pverts = np.array([tuple(x) for x in perceivedpnts], dtype=[('x', 'f4'),('y', 'f4'),('z', 'f4')])
        el = PlyElement.describe(pverts, 'vertex')
        PlyData([el], text = True).write('perceivedpnts.ply')
        # save txt
        vandnarray = []
        for i in range(len(self.temppnts)):
            v = self.temppnts[i]
            n = self.tempnormals[i]
            vandn = (v[0],v[1],v[2],n[0],n[1],n[2])
            vandnarray.append(vandn)
        pverts = np.array(vandnarray, dtype=[('x', 'f4'),('y', 'f4'),('z', 'f4'),\
                                                                    ('nx','f4'),('ny','f4'),('nz','f4')])
        el = PlyElement.describe(pverts, 'vertex')
        PlyData([el], text = True).write('ttube.ply')

        accspace = {}
        # get the preceived global model descriptor
        nperceivedpnts = perceivedpnts.shape[0]
        i = np.argmax(perceivedpnts, axis = 0)[2]
        for j in range(0,nperceivedpnts):
            print j, nperceivedpnts
            m_0 = np.asarray(perceivedpnts[i])
            m_1 = np.asarray(perceivedpnts[j])
            v_m0m1 = m_0-m_1
            v_m1m0 = m_1-m_0
            n_m0 = perceivednormals[i]
            n_m1 = perceivednormals[j]
            # f1, namely ||d||2
            f1 = np.linalg.norm(m_0-m_1)
            # f2, namely angle between n_m0 and v_m1m0
            f2 = rm.degree_between(n_m0, v_m1m0)
            # f3, namely angle between n_m1 and v_m0m1
            f3 = rm.degree_between(n_m1, v_m0m1)
            # f4, namely angle between n_m0 and n_m1
            f4 = rm.degree_between(n_m0, n_m1)
            # discretize the values
            try:
                f1d = int(math.floor(f1/ddist)*ddist+ddist)
                f2d = int(math.floor(f2/dangle)*dangle+dangle)
                f3d = int(math.floor(f3/dangle)*dangle+dangle)
                f4d = int(math.floor(f4/dangle)*dangle+dangle)
            except:
                continue
            key = (f1d, f2d, f3d, f4d)
            # angle between n_m0 and x+
            xplus = np.asarray([1,0,0])
            yplus = np.asarray([0,1,0])
            nm0xangle = math.degrees(rm.radian_between(n_m0, xplus))
            rotax = np.cross(xplus, n_m0)
            if np.isnan(rotax).any() or not rotax.any():
                continue
            rotmat = rm.rodrigues(rotax, nm0xangle)
            v_m1m0onxplus = np.dot(v_m1m0, rotmat)
            v_m1m0onxplusyzproj = np.asarray([0, v_m1m0onxplus[1], v_m1m0onxplus[2]])
            alpha_m0 = rm.radian_between(v_m1m0onxplusyzproj, yplus)
            if v_m1m0onxplus[2] < 0:
                alpha_m0 = 2*math.pi - alpha_m0
            if key in self.gmd.keys():
                malist = self.gmd[key]
                print len(malist)
                for maslot in malist:
                    alpha = math.degrees(alpha_m0-maslot[2])
                    try:
                        alphadiscrete = int(math.floor(alpha/dangle)*dangle+dangle)
                    except:
                        continue
                    acckey = (maslot[0], alphadiscrete)
                    if acckey in accspace.keys():
                        accspace[acckey] += 1
                    else:
                        accspace[acckey] = 1
        if len(accspace.keys()) is 0:
            return (None, None)
        # find top matches and rot matrices
        maxn = sorted(accspace.iteritems(), key=operator.itemgetter(1), reverse=True)[:5]
        rotmat4list = []
        silist = []
        milist = []
        for maxnele in maxn:
            mi, alpha = maxnele[0]
            # step1 move to temppnts[mi]
            displacement0 = -self.temppnts[mi]
            rotmat4_0 = Mat4.translateMat(displacement0[0], displacement0[1], displacement0[2])
            # step2 rotate to goal
            normalangle = math.degrees(rm.radian_between(self.tempnormals[mi], perceivednormals[i]))
            normalrotax = np.cross(self.tempnormals[mi], perceivednormals[i])
            normalrotmat = rm.rodrigues(normalrotax, normalangle)
            anglerotmat = rm.rodrigues(perceivednormals[i], -alpha)
            rotmat = np.dot(anglerotmat, normalrotmat)
            rotmat4_1 = pg.npToMat4(rotmat)
            # step3 move to perceivedpnts[i]
            displacement1 = perceivedpnts[i]
            rotmat4_2 = Mat4.translateMat(displacement1[0], displacement1[1], displacement1[2])
            rotmat4 = rotmat4_0*rotmat4_1*rotmat4_2
            rotmat4list.append(rotmat4)
            silist.append(i)
            milist.append(mi)

        return rotmat4list, silist, milist
コード例 #31
0
def write_ply(cloud, file_name):    
    el = PlyElement.describe(cloud, 'vertex') 
    PlyData([el]).write(file_name)   
コード例 #32
0
def convert_tsdf_to_ply(tsdf_bin_filename, tsdf_mesh_filename):
    """
    Converts the tsdf binary file to a mesh file in ply format

    The indexing in the tsdf is
    (x,y,z) <--> (x + y * dim_x + z * dim_x * dim_y)
    """
    start_time = time.time()
    fin = open(tsdf_bin_filename, "rb")

    tsdfHeader = array.array("f")  # f is the typecode for float32
    tsdfHeader.fromfile(fin, 8)
    # print tsdfHeader
    # print type(tsdfHeader)

    voxelGridDim = tsdfHeader[0:3]
    voxelGridDim = np.asarray(voxelGridDim, dtype=np.int)
    voxelGridOrigin = tsdfHeader[3:6]
    voxelSize = tsdfHeader[6]
    truncMargin = tsdfHeader[7]

    dim_x = voxelGridDim[0]
    dim_y = voxelGridDim[1]
    dim_z = voxelGridDim[2]

    headerSize = 8
    tsdf_vec = np.fromfile(tsdf_bin_filename, np.float32)
    tsdf_vec = tsdf_vec[headerSize:]
    tsdf = np.reshape(tsdf_vec, voxelGridDim,
                      order='F')  # reshape using Fortran order

    # for loop version of the above reshape operation
    # for x in xrange(0, dim_x):
    #     for y in xrange(0, dim_y):
    #         for z in xrange(0, dim_z):
    #             idx = x + y * dim_x + z * dim_x * dim_y
    #             tsdf[x,y,z] = tsdf_vec[idx]

    print "tsdf.shape:", tsdf.shape
    print "voxelGridDim: ", voxelGridDim
    print "voxeGridOrigin: ", voxelGridOrigin
    print "tsdf.shape:", tsdf.shape

    verts, faces, normals, values = measure.marching_cubes_lewiner(
        tsdf, spacing=[voxelSize] * 3)

    print "type(verts): ", type(verts)
    print "verts.shape: ", verts.shape
    print "faces.shape:", faces.shape

    print "np.max(verts[:,0]): ", np.max(verts[:, 0])
    print "np.min(verts[:,0]): ", np.min(verts[:, 0])

    print "verts[0,:] = ", verts[0, :]
    print "faces[0,:] = ", faces[0, :]

    # transform from voxel coordinates to camera coordinates
    # note x and y are flipped in the output of marching_cubes
    mesh_points = np.zeros_like(verts)
    # mesh_points = verts
    mesh_points[:, 0] = voxelGridOrigin[0] + verts[:, 0]
    mesh_points[:, 1] = voxelGridOrigin[1] + verts[:, 1]
    mesh_points[:, 2] = voxelGridOrigin[2] + verts[:, 2]

    # permute faces to get visualization
    # faces = np.flip(faces, 1)

    # try writing to the ply file
    print "converting numpy arrays to format for ply file"
    ply_conversion_start_time = time.time()

    num_verts = verts.shape[0]
    num_faces = faces.shape[0]

    verts_tuple = np.zeros((num_verts, ),
                           dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4')])
    faces_tuple = np.zeros((num_faces, ),
                           dtype=[('vertex_indices', 'i4', (3, ))])

    for i in xrange(0, num_verts):
        verts_tuple[i] = tuple(mesh_points[i, :])

    for i in xrange(0, num_faces):
        faces_tuple[i] = faces[i, :].tolist()

    # save it out
    # try to save it
    el_verts = PlyElement.describe(verts_tuple, 'vertex')
    el_faces = PlyElement.describe(faces_tuple, 'face')

    ply_data = PlyData([el_verts, el_faces])
    print "saving mesh to %s" % (tsdf_mesh_filename)
    ply = ply_data.write(tsdf_mesh_filename)

    print "converting to ply format and writing to file took", time.time(
    ) - start_time
コード例 #33
0
    '''


programSV3DRegion = glumpy_setting.ProgramSV3DRegion(data=data, name=None, point_size=1, anchor=anchor_matrix_whole)
gpyWindow.add_program(programSV3DRegion)

print(data['a_position'][0, 0, 0])
print(np.isnan(data['a_position'][0, 0, 0]))
print(~np.isnan(data['a_position'][0, 0, 0]))
data['a_color'] *= 255
data['a_color'].astype(int)

data = data[np.nonzero(~np.isnan(data['a_position'][:, :, 0]))]
xyzzz = np.zeros(len(data), dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4'), ('r', 'f4'), ('g', 'f4'), ('b', 'f4')])
xyzzz['x'] = data['a_position'][:, 0]
xyzzz['y'] = data['a_position'][:, 1]
xyzzz['z'] = data['a_position'][:, 2]
xyzzz['r'] = data['a_color'][:, 0]
xyzzz['g'] = data['a_color'][:, 1]
xyzzz['b'] = data['a_color'][:, 2]
el = PlyElement.describe(xyzzz, 'vertex')

PlyData([el]).write('some_binary.ply')
PlyData([el], text=True).write('some_ascii.ply')

programAxis = glumpy_setting.ProgramAxis(line_length=5)
gpyWindow.add_program(programAxis)

gpyWindow.run()

コード例 #34
0
            for f in mesh.faces:
                faces.append((np.array(f[0:3]) + len(verts0),))
                n0 = cad_mesh.parser.normals[f[3]]
                v0 = cad_mesh.vertices[f[0]]
                v1 = cad_mesh.vertices[f[1]]
                v2 = cad_mesh.vertices[f[2]]
                if len(v0) == 3:
                    cad_mesh.vertices[f[0]] = v0 + n0 + color
                if len(v1) == 3:
                    cad_mesh.vertices[f[1]] = v1 + n0 + color
                if len(v2) == 3:
                    cad_mesh.vertices[f[2]] = v2 + n0 + color
        faces0.extend(faces)
        
        for v in cad_mesh.vertices[:]:
            if len(v) != 9:
                v = (0, 0, 0) + (0, 0, 0) + (0, 0, 0)
            vi = tuple(np.dot(Mcad, np.array([v[0], v[1], v[2], 1]))[0:3])
            ni = tuple(np.dot(np.linalg.inv(Mcad).transpose(), np.array([v[3], v[4], v[5], 1]))[0:3])
            ci = tuple(v[6:9])
            verts.append(vi + ni + ci)
        verts0.extend(verts)

    verts0 = np.asarray(verts0, dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4'), ('nx', 'f4'), ('ny', 'f4'), ('nz', 'f4'), ('red', 'u1'), ('green', 'u1'), ('blue', 'u1')])
    faces0 = np.asarray(faces0, dtype=[('vertex_indices', 'i4', (3,))])
    objdata = PlyData([PlyElement.describe(verts0, 'vertex', comments=['vertices']),  PlyElement.describe(faces0, 'face')], comments=['faces'])
    with open(outdir + "/alignment.ply", mode='wb') as f:
        PlyData(objdata).write(f)


コード例 #35
0
ファイル: mesh.py プロジェクト: shawn-lo/532cv
    return face


if __name__ == "__main__":
    # load image
    img0 = np.array(Image.open("gargoyle/disp1.pgm"), dtype="int64")
    img1 = np.array(Image.open("gargoyle/view3.png"))
    img2 = np.array(Image.open("gargoyle/disp5.pgm"), dtype="int64")

    # construct 3d coordinates
    coords3d = []
    coords3d1 = construct3D(img0, 1)
    coords3d2 = construct3D(img2, 5)
    coords3d = coords3d1 + coords3d2

    # get disp map
    #    depth_map = project_nearest(coords3d)
    disp_map = project_nearest(coords3d)
    #    scipy.misc.imsave('disp3.png', disp_map)

    # connect
    raw_face = generate_mesh(disp_map)
    raw_vertex = construct_and_texture(disp_map, img1, 3)
    vertex = np.array(
        raw_vertex, dtype=[("x", "f4"), ("y", "f4"), ("z", "f4"), ("red", "u1"), ("green", "u1"), ("blue", "u1")]
    )
    face = np.array(raw_face, dtype=[("vertex_indices", "int32", (3,))])
    elv = PlyElement.describe(vertex, "vertex")
    elf = PlyElement.describe(face, "face")
    PlyData([elv, elf]).write("mesh.ply")
コード例 #36
0
parser.add_argument('--bbmax',
                    nargs=3,
                    type=float,
                    help='bounding box max',
                    default=[np.inf, np.inf, np.inf])

args = parser.parse_args()
minx, miny, minz, maxx, maxy, maxz = args.bbmin[0], args.bbmin[1], args.bbmin[
    2], args.bbmax[0], args.bbmax[1], args.bbmax[2]
print(args)

vertex = []
with open(args.infile) as f:
    for line in f:
        if line[0] != '#':
            ls = line.strip().split()
            x, y, z = float(ls[0]), float(ls[1]), float(ls[2])
            nx, ny, nz = float(ls[3]), float(ls[4]), float(ls[5])
            if (x >= minx) and (x <= maxx) and (y >= miny) and (
                    y <= maxy) and (z >= minz) and (z <= maxz):
                vertex.append(
                    (x, y, z, nx, ny, nz, int(ls[6]), int(ls[7]), int(ls[8])))

print('num vertices', len(vertex))
vertex = np.array(vertex,
                  dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4'), ('nx', 'f4'),
                         ('ny', 'f4'), ('nz', 'f4'), ('red', 'u1'),
                         ('green', 'u1'), ('blue', 'u1')])
el = PlyElement.describe(vertex, 'vertex')
PlyData([el]).write(args.outfile)
コード例 #37
0
ファイル: pc_util.py プロジェクト: joosm/pointnet2
def write_ply(points, filename, text=True):
    """ input: Nx3, write points to filename as PLY format. """
    points = [(points[i,0], points[i,1], points[i,2]) for i in range(points.shape[0])]
    vertex = np.array(points, dtype=[('x', 'f4'), ('y', 'f4'),('z', 'f4')])
    el = PlyElement.describe(vertex, 'vertex', comments=['vertices'])
    PlyData([el], text=text).write(filename)
コード例 #38
0
def save_ply(vert,face,fname):
    el1 = PlyElement.describe(np.array([(x[0],x[1],x[2]) for x in vert],dtype=[('x', 'f8'), ('y', 'f8'),('z', 'f8')]), 'vertex')
    el2 = PlyElement.describe(np.array([([x[0],x[1],x[2]], 0) for x in face],dtype=[('vertex_indices', 'i4', (3,)), ('red', 'u1')]), 'face')
    PlyData([el1,el2], text=True).write(fname)
コード例 #39
0
ファイル: test.py プロジェクト: chachi/python-plyfile
                      (0, 1, 1),
                      (1, 0, 1),
                      (1, 1, 0)],
                     dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4')])

face = numpy.array([([0, 1, 2], 255, 255, 255),
                    ([0, 2, 3], 255,   0,   0),
                    ([0, 1, 3],   0, 255,   0),
                    ([1, 2, 3],   0,   0, 255)],
                   dtype=[('vertex_indices', 'i4', (3,)),
                          ('red', 'u1'), ('green', 'u1'),
                          ('blue', 'u1')])


print "Assembling initial PlyData instance..."
ply0 = PlyData([PlyElement.describe(vertex, 'vertex',
                                    comments=['tetrahedron vertices']),
                PlyElement.describe(face, 'face')],
               text=True,
               comments=['single tetrahedron with colored faces'])

print "Writing test0.ply (ascii)..."
ply0.write('test0.ply')

print "Reading test0.ply..."
ply1 = PlyData.read('test0.ply')

print "(verifying result...)"
verify(ply0, ply1)

print "Writing test1.ply (binary_little_endian)..."
ply1.text = False
コード例 #40
0
ファイル: normal.py プロジェクト: shawn-lo/532cv
        vertex_normal[index3] = np.add(vertex_normal[index3], normal2)

    # 3, normalize vector
    for i in range(0, vertex_number):
        vertex_normal[i] = normalize(vertex_normal[i])

    # 4, write to ply
    result = []
    # The properties are 'x, y, z, nx, ny, nz'
    for i in range(0, vertex_number):
        record = (
            plyData["vertex"][i][0],
            plyData["vertex"][i][1],
            plyData["vertex"][i][2],
            vertex_normal[i][0],
            vertex_normal[i][1],
            vertex_normal[i][2],
        )
        result.append(record)

    # print(result)
    new_vertex_data = np.array(
        result,
        dtype=[("x", "float32"), ("y", "float32"), ("z", "float32"), ("nx", "float"), ("ny", "float"), ("nz", "float")],
    )
    elv = PlyElement.describe(new_vertex_data, "vertex")
    PlyData([elv]).write("p1.ply")

    # 5, write to txt
    np.savetxt("test.txt", new_vertex_data, delimiter=" ", fmt="%.6f")
コード例 #41
0
def test_invalid_property_names():
    with Raises(ValueError):
        PlyElement.describe(numpy.zeros(1, dtype=[('\xb0', 'i4')]), 'test')

    with Raises(ValueError):
        PlyElement.describe(numpy.zeros(1, dtype=[('a b', 'i4')]), 'test')
コード例 #42
0
def filter_depth(dataset_root, scan, out_folder, plyfilename):
    print("Starting fusion for:" + out_folder)

    # the pair file
    pair_file = os.path.join(dataset_root, 'Cameras/pair.txt')
    # for the final point cloud
    vertexs = []
    vertex_colors = []

    pair_data = read_pair_file(pair_file)
    nviews = len(pair_data)

    # for each reference view and the corresponding source views
    for ref_view, src_views in pair_data:
        # load the camera parameters
        ref_intrinsics, ref_extrinsics = read_camera_parameters(
            os.path.join(dataset_root,
                         'Cameras/{:0>8}_cam.txt'.format(ref_view)))

        # load the reference image
        ref_img = read_img(
            os.path.join(
                dataset_root, "Rectified", scan,
                'rect_{:03d}_3_r5000.png'.format(ref_view +
                                                 1)))  # Image start from 1.
        # load the estimated depth of the reference view
        ref_depth_est, scale = read_pfm(
            os.path.join(out_folder, 'depth_est/{:0>8}.pfm'.format(ref_view)))
        # load the photometric mask of the reference view
        confidence, scale = read_pfm(
            os.path.join(out_folder, 'confidence/{:0>8}.pfm'.format(ref_view)))
        photo_mask = confidence > 0.9

        all_srcview_depth_ests = []
        all_srcview_x = []
        all_srcview_y = []
        all_srcview_geomask = []

        # compute the geometric mask
        geo_mask_sum = 0
        for src_view in src_views:
            # camera parameters of the source view
            src_intrinsics, src_extrinsics = read_camera_parameters(
                os.path.join(dataset_root,
                             'Cameras/{:0>8}_cam.txt'.format(src_view)))

            # the estimated depth of the source view
            src_depth_est, scale = read_pfm(
                os.path.join(out_folder,
                             'depth_est/{:0>8}.pfm'.format(src_view)))

            geo_mask, depth_reprojected, x2d_src, y2d_src = check_geometric_consistency(
                ref_depth_est, ref_intrinsics, ref_extrinsics, src_depth_est,
                src_intrinsics, src_extrinsics)

            geo_mask_sum += geo_mask.astype(np.int32)
            all_srcview_depth_ests.append(depth_reprojected)
            all_srcview_x.append(x2d_src)
            all_srcview_y.append(y2d_src)
            all_srcview_geomask.append(geo_mask)

        depth_est_averaged = (sum(all_srcview_depth_ests) +
                              ref_depth_est) / (geo_mask_sum + 1)
        # at least 3 source views matched
        geo_mask = geo_mask_sum >= 3
        final_mask = np.logical_and(photo_mask, geo_mask)

        os.makedirs(os.path.join(out_folder, "mask"), exist_ok=True)
        save_mask(
            os.path.join(out_folder, "mask/{:0>8}_photo.png".format(ref_view)),
            photo_mask)
        save_mask(
            os.path.join(out_folder, "mask/{:0>8}_geo.png".format(ref_view)),
            geo_mask)
        save_mask(
            os.path.join(out_folder, "mask/{:0>8}_final.png".format(ref_view)),
            final_mask)

        print("processing {}, ref-view{:0>2}, photo/geo/final-mask:{}/{}/{}".
              format(scan, ref_view, photo_mask.mean(), geo_mask.mean(),
                     final_mask.mean()))

        height, width = depth_est_averaged.shape[:2]
        x, y = np.meshgrid(np.arange(0, width), np.arange(0, height))
        # valid_points = np.logical_and(final_mask, ~used_mask[ref_view])
        valid_points = final_mask
        print("valid_points", valid_points.mean())
        x, y, depth = x[valid_points], y[valid_points], depth_est_averaged[
            valid_points]
        ref_img = np.array(ref_img)

        color = ref_img[valid_points]

        xyz_ref = np.matmul(np.linalg.inv(ref_intrinsics),
                            np.vstack((x, y, np.ones_like(x))) * depth)
        xyz_world = np.matmul(np.linalg.inv(ref_extrinsics),
                              np.vstack((xyz_ref, np.ones_like(x))))[:3]
        vertexs.append(xyz_world.transpose((1, 0)))
        vertex_colors.append((color).astype(np.uint8))

    vertexs = np.concatenate(vertexs, axis=0)
    vertex_colors = np.concatenate(vertex_colors, axis=0)
    vertexs = np.array([tuple(v) for v in vertexs],
                       dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4')])
    vertex_colors = np.array([tuple(v) for v in vertex_colors],
                             dtype=[('red', 'u1'), ('green', 'u1'),
                                    ('blue', 'u1')])

    vertex_all = np.empty(len(vertexs),
                          vertexs.dtype.descr + vertex_colors.dtype.descr)
    for prop in vertexs.dtype.names:
        vertex_all[prop] = vertexs[prop]
    for prop in vertex_colors.dtype.names:
        vertex_all[prop] = vertex_colors[prop]

    el = PlyElement.describe(vertex_all, 'vertex')
    print("Saving the final model to", plyfilename)
    PlyData([el],
            comments=['Model created by AACVP-MVSNet.']).write(plyfilename)
    print("Model saved.")
コード例 #43
0
        if createSV and needOutput:
            data = programSV3DRegion.data
            data['a_color'] *= 255
            data['a_color'].astype(int)

            dataPLY = np.zeros(len(data), dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4'), ('red', 'u1'), ('green', 'u1'),
                                                 ('blue', 'u1')])
            dataPLY['x'] = data['a_position'][:, 0]
            dataPLY['y'] = data['a_position'][:, 1]
            dataPLY['z'] = data['a_position'][:, 2]

            dataPLY['red'] = data['a_color'][:, 0]
            dataPLY['green'] = data['a_color'][:, 1]
            dataPLY['blue'] = data['a_color'][:, 2]

            el = PlyElement.describe(dataPLY, 'vertex')

            # PlyData([el], text=True).write('137_4_ascii.ply')
            PlyData([el]).write('/home/andy/src/ply/' + fileID + '_non_ground_binary.ply')

            if needGround:
                dataGnd = programSV3DRegion.data
                dataGnd['a_color'] *= 255
                dataGnd['a_color'].astype(int)

                dataPLY = np.zeros(len(dataGnd), dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4'),
                                                        ('red', 'u1'), ('green', 'u1'), ('blue', 'u1')])
                dataPLY['x'] = dataGnd['a_position'][:, 0]
                dataPLY['y'] = dataGnd['a_position'][:, 1]
                dataPLY['z'] = dataGnd['a_position'][:, 2]
コード例 #44
0
ファイル: 6_mesh.py プロジェクト: ydnaandy123/DashCam_python
"""
ALL PLY EXPORT IN HERE
"""

data = programSV3DRegion.data
data['a_color'] *= 255
data['a_color'].astype(int)

xyzzz = np.zeros(len(data), dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4'), ('red', 'u1'), ('green', 'u1'), ('blue', 'u1')])
xyzzz['x'] = data['a_position'][:, 0]
xyzzz['y'] = data['a_position'][:, 1]
xyzzz['z'] = data['a_position'][:, 2]
xyzzz['red'] = data['a_color'][:, 0]
xyzzz['green'] = data['a_color'][:, 1]
xyzzz['blue'] = data['a_color'][:, 2]
el = PlyElement.describe(xyzzz, 'vertex')

face = np.zeros(len(tri), dtype=[('vertex_indices', 'i4', 3)])
face['vertex_indices'] = tri
tri = PlyElement.describe(face, 'face')

PlyData([el, tri], text=True).write('some_ascii.ply')
#PlyData([el]).write('over_simple_binary.ply')
"""
ALL PLY EXPORT IN HERE
"""

programAxis = glumpy_setting.ProgramAxis(line_length=5)
gpyWindow.add_program(programAxis)

gpyWindow.run()
コード例 #45
0
ファイル: pc_utils.py プロジェクト: jgwak/GSDN
def save_point_cloud(points_3d,
                     filename,
                     binary=True,
                     with_label=False,
                     verbose=True):
    """Save an RGB point cloud as a PLY file.

  Args:
    points_3d: Nx6 matrix where points_3d[:, :3] are the XYZ coordinates and points_3d[:, 4:] are
        the RGB values. If Nx3 matrix, save all points with [128, 128, 128] (gray) color.
  """
    assert points_3d.ndim == 2
    if with_label:
        assert points_3d.shape[1] == 7 or points_3d.shape[1] == 8
        if points_3d.shape[1] == 7:
            python_types = (float, float, float, int, int, int, int)
            npy_types = [('x', 'f4'), ('y', 'f4'), ('z', 'f4'), ('red', 'u1'),
                         ('green', 'u1'), ('blue', 'u1'), ('label', 'u1')]
        else:
            python_types = (float, float, float, int, int, int, int, int)
            npy_types = [('x', 'f4'), ('y', 'f4'), ('z', 'f4'), ('red', 'u1'),
                         ('green', 'u1'), ('blue', 'u1'),
                         ('label_class', 'u1'), ('label_instance', 'u2')]
    else:
        if points_3d.shape[1] == 3:
            gray_concat = np.tile(np.array([128], dtype=np.uint8),
                                  (points_3d.shape[0], 3))
            points_3d = np.hstack((points_3d, gray_concat))
        assert points_3d.shape[1] == 6
        python_types = (float, float, float, int, int, int)
        npy_types = [('x', 'f4'), ('y', 'f4'), ('z', 'f4'), ('red', 'u1'),
                     ('green', 'u1'), ('blue', 'u1')]
    if binary is True:
        # Format into NumPy structured array
        vertices = []
        for row_idx in range(points_3d.shape[0]):
            cur_point = points_3d[row_idx]
            vertices.append(
                tuple(
                    dtype(point)
                    for dtype, point in zip(python_types, cur_point)))
        vertices_array = np.array(vertices, dtype=npy_types)
        el = PlyElement.describe(vertices_array, 'vertex')

        # Write
        PlyData([el]).write(filename)
    else:
        # PlyData([el], text=True).write(filename)
        with open(filename, 'w') as f:
            f.write('ply\n'
                    'format ascii 1.0\n'
                    'element vertex %d\n'
                    'property float x\n'
                    'property float y\n'
                    'property float z\n'
                    'property uchar red\n'
                    'property uchar green\n'
                    'property uchar blue\n'
                    'property uchar alpha\n'
                    'end_header\n' % points_3d.shape[0])
            for row_idx in range(points_3d.shape[0]):
                X, Y, Z, R, G, B = points_3d[row_idx]
                f.write('%f %f %f %d %d %d 0\n' % (X, Y, Z, R, G, B))
    if verbose is True:
        print('Saved point cloud to: %s' % filename)
コード例 #46
0
ファイル: read_h5.py プロジェクト: Blitzman/cviu-si-dl-study
def export_ply(pc, filename):
    vertex = np.zeros(pc.shape[0], dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4')])
    for i in range(pc.shape[0]):
        vertex[i] = (pc[i][0], pc[i][1], pc[i][2])
    ply_out = PlyData([PlyElement.describe(vertex, 'vertex', comments=['vertices'])])
    ply_out.write(filename)
コード例 #47
0
ファイル: meshes.py プロジェクト: russell0/SyConn
def make_ply_string(dest_path, indices, vertices, rgba_color):
    """
    Creates a ply str that can be included into a .k.zip for rendering
    in KNOSSOS.
    # TODO: write out normals

    Parameters
    ----------
    indices : np.array
    vertices : np.array
    rgba_color : Tuple[uint8] or np.array

    Returns
    -------
    str
    """
    # create header
    vertices = vertices.astype(np.float32)
    indices = indices.astype(np.int32)
    if not indices.ndim == 2:
        indices = np.array(indices, dtype=np.int).reshape((-1, 3))
    if not vertices.ndim == 2:
        vertices = np.array(vertices, dtype=np.float32).reshape((-1, 3))
    if len(rgba_color) != len(vertices) and len(rgba_color) == 4:
        # TODO: create per tree color instead of per vertex color
        rgba_color = np.array([rgba_color for i in range(len(vertices))],
                              dtype=np.uint8)
    else:
        if not (len(rgba_color) == len(vertices) and len(rgba_color[0]) == 4):
            msg = 'Color array has to be RGBA and to provide a color value f' \
                  'or every vertex!'
            log_proc.error(msg)
            raise ValueError(msg)
    if not rgba_color.ndim == 2:
        rgba_color = np.array(rgba_color, dtype=np.int).reshape((-1, 4))
    if type(rgba_color) is list:
        rgba_color = np.array(rgba_color, dtype=np.uint8)
        log_proc.warn("Color input is list. It will now be converted "
                      "automatically, data will be unusable if not normalized"
                      " between 0 and 255. min/max of data:"
                      " {}, {}".format(rgba_color.min(), rgba_color.max()))
    elif rgba_color.dtype.kind != "u1":
        log_proc.warn("Color array is not of type integer or unsigned integer."
                      " It will now be converted automatically, data will be "
                      "unusable if not normalized between 0 and 255."
                      "min/max of data: {}, {}".format(rgba_color.min(),
                                                       rgba_color.max()))
        rgba_color = np.array(rgba_color, dtype=np.uint8)
    # ply file requires 1D object arrays,
    vertices = np.concatenate(
        [vertices.astype(np.object),
         rgba_color.astype(np.object)], axis=1)
    vertices = np.array([tuple(el) for el in vertices],
                        dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4'),
                               ('red', 'u1'), ('green', 'u1'), ('blue', 'u1'),
                               ('alpha', 'u1')])
    # ply file requires 1D object arrays.
    indices = np.array([tuple([el], ) for el in indices],
                       dtype=[('vertex_indices', 'i4', (3, ))])
    PlyData([
        PlyElement.describe(vertices, 'vertex'),
        PlyElement.describe(indices, 'face')
    ]).write(dest_path)