StanfordVL / iGibson

A Simulation Environment to train Robots in Large Realistic Interactive Scenes
http://svl.stanford.edu/igibson
MIT License
623 stars 154 forks source link

UnicodeDecodeError #126

Closed huangjy-pku closed 2 years ago

huangjy-pku commented 2 years ago

When I input: python -m igibson.examples.demo.mesh_renderer_example_pbr ./igibson/data/ig_dataset/objects/sink/sink_1/shape/visual to test a PBR example, it appeared to generate a decoding error.

The problem lies in the following two lines in function 'load_obj_np' in 'mesh_renderer_example_pbr.py': with open(filename_obj) as f: lines = f.readlines() UnicodeDecodeError: 'utf-8' codec can't decode byte 0x97 in position 0: invalid start byte

So confusing about it.

ChengshuLi commented 2 years ago

Is your dataset fully downloaded? Could you check the file size of the files inside ./igibson/data/ig_dataset/objects/sink/sink_1/shape/visual and make sure they are valid OBJ files?

fxia22 commented 2 years ago

load_object_np doesn't work with encrypted assets, to use it on encrypted assets, you can change the python script to:


import os
import sys

import cv2
import numpy as np

from igibson.render.mesh_renderer.mesh_renderer_cpu import MeshRenderer
from igibson.render.mesh_renderer.mesh_renderer_settings import MeshRendererSettings
from igibson.render.profiler import Profiler
from igibson.utils.assets_utils import get_scene_path

def load_obj_np(filename_obj, normalization=False, texture_size=4, texture_wrapping="REPEAT", use_bilinear=True):
    """Load Wavefront .obj file into numpy array
    This function only supports vertices (v x x x) and faces (f x x x).
    """
    # load vertices
    vertices = []
    with open(filename_obj) as f:
        lines = f.readlines()

    for line in lines:
        if len(line.split()) == 0:
            continue
        if line.split()[0] == "v":
            vertices.append([float(v) for v in line.split()[1:4]])
    vertices = np.vstack(vertices).astype(np.float32)

    # load faces
    faces = []
    for line in lines:
        if len(line.split()) == 0:
            continue
        if line.split()[0] == "f":
            vs = line.split()[1:]
            nv = len(vs)
            v0 = int(vs[0].split("/")[0])
            for i in range(nv - 2):
                v1 = int(vs[i + 1].split("/")[0])
                v2 = int(vs[i + 2].split("/")[0])
                faces.append((v0, v1, v2))
    faces = np.vstack(faces).astype(np.int32) - 1

    assert normalization is False  # Since I commented out the block below

    return vertices, faces

def main():
    global _mouse_ix, _mouse_iy, down, view_direction

    if len(sys.argv) > 1:
        model_path = sys.argv[1]
    else:
        model_path = os.path.join(get_scene_path("Rs_int"), "mesh_z_up.obj")
    settings = MeshRendererSettings(msaa=True, enable_shadow=True)
    renderer = MeshRenderer(width=512, height=512, vertical_fov=70, rendering_settings=settings)
    renderer.set_light_position_direction([0, 0, 10], [0, 0, 0])

    i = 0

    #v = []
    #for fn in os.listdir(model_path):
    #    if fn.endswith("obj"):
    #        vertices, faces = load_obj_np(os.path.join(model_path, fn))
    #        v.append(vertices)

    #v = np.vstack(v)
    #print(v.shape)
    #xlen = np.max(v[:, 0]) - np.min(v[:, 0])
    #ylen = np.max(v[:, 1]) - np.min(v[:, 1])
    #scale = 2.0 / (max(xlen, ylen))
    scale = 1.0

    for fn in os.listdir(model_path):
        if fn.endswith("obj"):
            renderer.load_object(os.path.join(model_path, fn), scale=[scale, scale, scale])
            renderer.add_instance(i)
            i += 1

    print(renderer.visual_objects, renderer.instances)
    print(renderer.material_idx_to_material_instance_mapping, renderer.shape_material_idx)

    px = 1
    py = 1
    pz = 1

    camera_pose = np.array([px, py, pz])
    view_direction = np.array([-1, -1, -1])
    renderer.set_camera(camera_pose, camera_pose + view_direction, [0, 0, 1])

    _mouse_ix, _mouse_iy = -1, -1
    down = False

    def change_dir(event, x, y, flags, param):
        global _mouse_ix, _mouse_iy, down, view_direction
        if event == cv2.EVENT_LBUTTONDOWN:
            _mouse_ix, _mouse_iy = x, y
            down = True
        if event == cv2.EVENT_MOUSEMOVE:
            if down:
                dx = (x - _mouse_ix) / 100.0
                dy = (y - _mouse_iy) / 100.0
                _mouse_ix = x
                _mouse_iy = y
                r1 = np.array([[np.cos(dy), 0, np.sin(dy)], [0, 1, 0], [-np.sin(dy), 0, np.cos(dy)]])
                r2 = np.array([[np.cos(-dx), -np.sin(-dx), 0], [np.sin(-dx), np.cos(-dx), 0], [0, 0, 1]])
                view_direction = r1.dot(r2).dot(view_direction)
        elif event == cv2.EVENT_LBUTTONUP:
            down = False

    cv2.namedWindow("test")
    cv2.setMouseCallback("test", change_dir)

    while True:
        with Profiler("Render"):
            frame = renderer.render(modes=("rgb", "normal", "seg", "ins_seg"))
        cv2.imshow("test", cv2.cvtColor(np.concatenate(frame, axis=1), cv2.COLOR_RGB2BGR))

        q = cv2.waitKey(1)
        if q == ord("w"):
            px += 0.1
        elif q == ord("s"):
            px -= 0.1
        elif q == ord("a"):
            py += 0.1
        elif q == ord("d"):
            py -= 0.1
        elif q == ord("q"):
            break

        camera_pose = np.array([px, py, 1])
        renderer.set_camera(camera_pose, camera_pose + view_direction, [0, 0, 1])

    renderer.release()

if __name__ == "__main__":
    main()
huangjy-pku commented 2 years ago

Is your dataset fully downloaded? Could you check the file size of the files inside ./igibson/data/ig_dataset/objects/sink/sink_1/shape/visual and make sure they are valid OBJ files?

Yep, my OBJ files are OK.

huangjy-pku commented 2 years ago

load_object_np doesn't work with encrypted assets, to use it on encrypted assets, you can change the python script to:

import os
import sys

import cv2
import numpy as np

from igibson.render.mesh_renderer.mesh_renderer_cpu import MeshRenderer
from igibson.render.mesh_renderer.mesh_renderer_settings import MeshRendererSettings
from igibson.render.profiler import Profiler
from igibson.utils.assets_utils import get_scene_path

def load_obj_np(filename_obj, normalization=False, texture_size=4, texture_wrapping="REPEAT", use_bilinear=True):
    """Load Wavefront .obj file into numpy array
    This function only supports vertices (v x x x) and faces (f x x x).
    """
    # load vertices
    vertices = []
    with open(filename_obj) as f:
        lines = f.readlines()

    for line in lines:
        if len(line.split()) == 0:
            continue
        if line.split()[0] == "v":
            vertices.append([float(v) for v in line.split()[1:4]])
    vertices = np.vstack(vertices).astype(np.float32)

    # load faces
    faces = []
    for line in lines:
        if len(line.split()) == 0:
            continue
        if line.split()[0] == "f":
            vs = line.split()[1:]
            nv = len(vs)
            v0 = int(vs[0].split("/")[0])
            for i in range(nv - 2):
                v1 = int(vs[i + 1].split("/")[0])
                v2 = int(vs[i + 2].split("/")[0])
                faces.append((v0, v1, v2))
    faces = np.vstack(faces).astype(np.int32) - 1

    assert normalization is False  # Since I commented out the block below

    return vertices, faces

def main():
    global _mouse_ix, _mouse_iy, down, view_direction

    if len(sys.argv) > 1:
        model_path = sys.argv[1]
    else:
        model_path = os.path.join(get_scene_path("Rs_int"), "mesh_z_up.obj")
    settings = MeshRendererSettings(msaa=True, enable_shadow=True)
    renderer = MeshRenderer(width=512, height=512, vertical_fov=70, rendering_settings=settings)
    renderer.set_light_position_direction([0, 0, 10], [0, 0, 0])

    i = 0

    #v = []
    #for fn in os.listdir(model_path):
    #    if fn.endswith("obj"):
    #        vertices, faces = load_obj_np(os.path.join(model_path, fn))
    #        v.append(vertices)

    #v = np.vstack(v)
    #print(v.shape)
    #xlen = np.max(v[:, 0]) - np.min(v[:, 0])
    #ylen = np.max(v[:, 1]) - np.min(v[:, 1])
    #scale = 2.0 / (max(xlen, ylen))
    scale = 1.0

    for fn in os.listdir(model_path):
        if fn.endswith("obj"):
            renderer.load_object(os.path.join(model_path, fn), scale=[scale, scale, scale])
            renderer.add_instance(i)
            i += 1

    print(renderer.visual_objects, renderer.instances)
    print(renderer.material_idx_to_material_instance_mapping, renderer.shape_material_idx)

    px = 1
    py = 1
    pz = 1

    camera_pose = np.array([px, py, pz])
    view_direction = np.array([-1, -1, -1])
    renderer.set_camera(camera_pose, camera_pose + view_direction, [0, 0, 1])

    _mouse_ix, _mouse_iy = -1, -1
    down = False

    def change_dir(event, x, y, flags, param):
        global _mouse_ix, _mouse_iy, down, view_direction
        if event == cv2.EVENT_LBUTTONDOWN:
            _mouse_ix, _mouse_iy = x, y
            down = True
        if event == cv2.EVENT_MOUSEMOVE:
            if down:
                dx = (x - _mouse_ix) / 100.0
                dy = (y - _mouse_iy) / 100.0
                _mouse_ix = x
                _mouse_iy = y
                r1 = np.array([[np.cos(dy), 0, np.sin(dy)], [0, 1, 0], [-np.sin(dy), 0, np.cos(dy)]])
                r2 = np.array([[np.cos(-dx), -np.sin(-dx), 0], [np.sin(-dx), np.cos(-dx), 0], [0, 0, 1]])
                view_direction = r1.dot(r2).dot(view_direction)
        elif event == cv2.EVENT_LBUTTONUP:
            down = False

    cv2.namedWindow("test")
    cv2.setMouseCallback("test", change_dir)

    while True:
        with Profiler("Render"):
            frame = renderer.render(modes=("rgb", "normal", "seg", "ins_seg"))
        cv2.imshow("test", cv2.cvtColor(np.concatenate(frame, axis=1), cv2.COLOR_RGB2BGR))

        q = cv2.waitKey(1)
        if q == ord("w"):
            px += 0.1
        elif q == ord("s"):
            px -= 0.1
        elif q == ord("a"):
            py += 0.1
        elif q == ord("d"):
            py -= 0.1
        elif q == ord("q"):
            break

        camera_pose = np.array([px, py, 1])
        renderer.set_camera(camera_pose, camera_pose + view_direction, [0, 0, 1])

    renderer.release()

if __name__ == "__main__":
    main()

Oh, thank you. This works!