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

how to rot the shape in hdf5 #8

Closed
tianyilt opened this issue Jan 17, 2020 · 6 comments
Closed

how to rot the shape in hdf5 #8

tianyilt opened this issue Jan 17, 2020 · 6 comments

Comments

@tianyilt
Copy link

tianyilt commented Jan 17, 2020

thank you for your excellent work. i have succeed in run it in my own binvox dataset.It is really pretty in Interpolation.

but when i try to rot the 3D shape in hdf5, 1 can't solve the following problem:

  1. the hdf5 structure:
    data_points16 (3,4096,3)
    data_values16(3,4096,1)
    data_points32 =(3,8192,3)
    data_values32 =(3,8192,1)
    data_points64 =(3,32768,3)
    data_values64 =(3,32768,1)
    data_voxels =(3,64.64,64.1)

why the last dim of data_points is 3
why the second dim of data_points32 is 8192,which is 161616*2

  1. rot shape method
    i try to rot shape by numpy.rot90, it work in data_voxels.
    to make sure the data set is all rot, i write the following function:
def visualize_voxels(voxels, thres=0.5, output_dir='voxel_list', filename='out'):
    import mcubes
    """

    :param voxels: ndarray shape like (64,64,64,1) bool value
    :param thres: 
    :param output_dir: 
    :return: 
    """
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    voxels = np.squeeze(voxels)  # (64,64,64,1)->(64,64,64)
    model_float = voxels
    vertices, triangles = mcubes.marching_cubes(model_float, thres)
    mcubes.export_mesh(vertices, triangles, os.path.join(output_dir, filename + ".dae"))
def visualize_voxels_batch(voxels_batch, thres=0.5, output_dir='voxel_list'):
    import mcubes
    """

    :param voxels: ndarray shape like (64,64,64,1) bool value
    :param thres: 
    :param output_dir: 
    :return: 
    """
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)
    for t in range(voxels_batch.shape[0]):
        model_float = np.squeeze(voxels_batch[t])  # (64,64,64,1)->(64,64,64)
        vertices, triangles = mcubes.marching_cubes(model_float, thres)
        mcubes.export_mesh(vertices, triangles, os.path.join(output_dir, str(t) + ".dae"))

def rot_voxel2zheng(voxel_batch):
    return np.flip(np.rot90(voxel_batch,k=1,axes=(2,3)),axis=2)
def rot_pointorvalue2zheng(points_batch):
    d=round(points_batch.shape[1]**(1/3))
    points_batch = points_batch.reshape([points_batch.shape[0],d,d,d,points_batch.shape[-1]])#(num,d**3,3)->(num,d,d,d,3)
    points_batch = np.flip(np.rot90(points_batch,k=1,axes=(2,3)),axis=2)
    return points_batch.reshape(points_batch.shape[0],d**3,points_batch.shape[-1])

Because i can't understand the problem 1, I have no idea how to adjust the data_points and points and values of 32dims.

  1. other efforts in binvox
    after i find it hard to adjust hdf5 file. i try to adjust binvox.
    i use the tool in https://github.com/dimatura/binvox-rw-py
    but i failed in

UnicodeEncodeError: 'gbk' codec can't encode character '\x80' in position 0: illegal multibyte sequence

i have add my question to related issue

@czq142857
Copy link
Owner

data_points32 =(N,8192,3)

This means we sample only 8192 points on 32x32x32 voxels. Since each point has 3 coordinates x,y,z, the last dim of data_points is 3.

If you want to rotate the shape, simply multiply "data_points" with a rotation matrix. Remember that the last dim of data_points is point coordinates (x,y,z). You do not need to change "data_values".

You don't have to change the code in binvox_rw.py.

Best,
Zhiqin

@tianyilt
Copy link
Author

thank you very much! It help me a lot.

@tianyilt
Copy link
Author

does the coordinate of a point in a shape in this hdf5 is the same as the point in binvox file? I want to check the location of point (0,0,0) and the direction of x,y,z axis.

@czq142857
Copy link
Owner

Yes. For example, the corners of a 64x64x64 voxel model are (0,0,0), (63,63,63), ...

Best,
Zhiqin

@tianyilt
Copy link
Author

tianyilt commented Jan 28, 2020

Thank you

@tianyilt
Copy link
Author

tianyilt commented Feb 4, 2020

here is my code for rotting. Thanks sincerely for author's help and instruction.'
The Linear transformation for rotation is found by test.
Used function

  • np.flip
    to flip voxel
  • np.rot90
    to rot voxel
  • np.matmul
    used to rot point pair
  • np.apply_along_axis
    used to rot point pair
import numpy as np
def rot_voxel2zheng(voxel_batch):
    return np.flip(np.rot90(np.rot90(voxel_batch, k=1, axes=(2, 3)), k=3, axes=(1, 2)),
                   axis=3)  # 先yz转一个90度,后xy转三个90度,然后关于z轴对称
def rotx(points, len):
    """
    rot 90 degree based on x axis
    :param points: points in hdf5, shape like (model_num, sample_points_num, 3)
    we should adjust the last dim, which is the (x,y,z) coordination of a sample point
    :param len:the size of voxel like 16 32 64
    :return: ndarray,the same shape as points,(x,y,z)<-(x,y,z)*rotation_matrix'+b_matrix
    """
    new_points = np.copy(points)  # 这里不能浅拷贝,不然rot完原来的points也变了
    for model_num, model in enumerate(points):
        for sample_points_num, sample_point in enumerate(model):
            rotation_matrix = np.array([[1, 0, 0], [0, 0, -1], [0, 1, 0]])
            b_matrix = np.array([0, len - 1, 0])
            new_points[model_num, sample_points_num, :] = np.matmul(sample_point,
                                                                    rotation_matrix.transpose()) + b_matrix

    # np.apply_along_axis(linear_transform_for_1dim, axis=2, arr=new_points)
    return new_points
def rotchair2zheng(points, len):
    """
    rot chair 2 demand direction
    :param points: points in hdf5, shape like (model_num, sample_points_num, 3)
    we should adjust the last dim, which is the (x,y,z) coordination of a sample point in a unit cubic
    (x,y,z) vary from (0,0,0) to (len-1, len-1, len-1)
    :param len:the size of voxel like 16 32 64
    :return: ndarray,the same shape as points,(x,y,z)<-(x,y,z)*rotation_matrix'+b_matrix
    """

    def linear_transform_for_1dim(a, len=len):
        """

        :param a: like points[model_num, sample_points_num, :]
        :return: (x,y,z)<-(x,y,z)*rotation_matrix'+b_matrix
        """
        # len=16
        rotation_matrix1 = np.array([[1, 0, 0], [0, 0, 1], [0, -1, 0]])
        b_matrix1 = np.array([0, 0, len - 1])
        a = np.matmul(a, rotation_matrix1.transpose()) + b_matrix1

        rotation_matrix2 = np.array([[0, -1, 0], [1, 0, 0], [0, 0, 1]])
        b_matrix2 = np.array([len - 1, 0, 0])
        a = np.matmul(a, rotation_matrix2.transpose()) + b_matrix2

        rotation_matrix3 = np.array([[1, 0, 0], [0, 1, 0], [0, 0, -1]])
        b_matrix3 = np.array([0, 0, len - 1])
        a = np.matmul(a, rotation_matrix3.transpose()) + b_matrix3

        rotation_matrix4 = np.array([[-1, 0, 0], [0, 1, 0], [0, 0, 1]])
        b_matrix4 = np.array([len - 1, 0, 0])
        a = np.matmul(a, rotation_matrix4.transpose()) + b_matrix4  # 关于x轴对称
        return a

    new_points = np.copy(points)  # 这里不能浅拷贝,不然rot完原来的points也变了
    new_points = np.apply_along_axis(linear_transform_for_1dim, axis=2, arr=new_points)

    return new_points
if __name__ == "__main__":
    f2 = h5py.File('       .hdf5', 'r')
    f2lb = 904
    f2_points16 = rotchair2zheng(f2['points_16'][:f2lb], 16)
    f2_points32 = rotchair2zheng(f2['points_32'][:f2lb], 32)
    f2_points64 = rotchair2zheng(f2['points_64'][:f2lb], 64)
    f2_values16 = f2['values_16'][:f2lb]
    f2_values32 = f2['values_32'][:f2lb]
    f2_values64 = f2['values_64'][:f2lb]
    f2_voxels = rot_voxel2zheng2(f2['voxels'][:f2lb])

    data_points16 = f2_points16
    data_values16 = f2_values16
    data_points32 = f2_points32
    data_values32 = f2_values32
    data_points64 = f2_points64
    data_values64 = f2_values64
    data_voxels = f2_voxels

    f3 = h5py.File('      .hdf5', 'w')
    f3['points_16'] = data_points16
    f3['values_16'] = data_values16
    f3['points_32'] = data_points32
    f3['values_32'] = data_values32
    f3['points_64'] = data_points64
    f3['values_64'] = data_values64
    f3['voxels'] = data_voxels
    f3.close()

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

2 participants