Пример #1
0
def main():
    current_dir = realpath(dirname(__file__))
    exr_files = sorted(glob.glob(join(current_dir, 'refs', '*_ref_*.exr')))

    images = []
    for f in exr_files:
        if (os.path.basename(f) == 'result.exr'):
            continue
        images.append(np.array(Bitmap(f)))

    images_np = np.stack(images, axis=-1)
    s = images_np.shape
    h = s[0]
    w = s[1]
    images_np = np.swapaxes(images_np, 2, 3)
    print(f"images_np.shape: {images_np.shape}")
    images_np = np.swapaxes(images_np, 0, 2)
    images_np = np.swapaxes(images_np, 1, 2)
    print(f"images_np.shape: {images_np.shape}")

    n_cols = 4
    n_rows = len(images) // n_cols
    images_np = np.reshape(images_np, [n_rows, n_cols, h, w, 3])
    images_np = np.swapaxes(images_np, 1, 2)
    images_np = np.reshape(images_np, [h * n_rows, w * n_cols, 3])

    # images_np = np.reshape(images_np, [h * 12, w * 2, 3])
    print(f"images_np.shape: {images_np.shape}")
    Bitmap(images_np).write('result.exr')
Пример #2
0
def check_finite_difference(test_name, make_scene, get_diff_params,
                            diff_integrator=diff_integrator_default, diff_spp=4, diff_passes=10,
                            ref_integrator=ref_integrator_default, ref_spp=128, ref_passes=10, ref_eps=0.001):

    from mitsuba.core import Bitmap, Struct
    from mitsuba.python.autodiff import render

    # Render groundtruth image and gradients (using finite difference)
    img_ref, grad_ref = compute_groundtruth(make_scene, ref_integrator, ref_spp, ref_passes, ref_eps)

    ek.cuda_malloc_trim()

    scene = make_scene(diff_integrator, diff_spp, 0.0)
    fsize = scene.sensors()[0].film().size()
    img, grad = render_gradient(scene, diff_passes, get_diff_params(scene))

    error_img = np.abs(img_ref - img).mean()
    error_grad = np.abs(grad_ref - grad).mean()

    if error_img > 0.1:
        print("error_img:", error_img)
        Bitmap(img_ref).write('%s_img_ref.exr' % test_name)
        Bitmap(img).write('%s_img.exr' % test_name)
        assert False

    if error_grad > 0.1:
        print("error_grad:", error_grad)
        scale = np.abs(grad_ref).max()
        write_gradient_image(grad_ref / scale, '%s_grad_ref' % test_name)
        write_gradient_image(grad / scale, '%s_grad' % test_name)
        Bitmap(img_ref).write('%s_img_ref.exr' % test_name)
        Bitmap(img).write('%s_img.exr' % test_name)
        assert False
Пример #3
0
def test_convert_rgb_y(tmpdir):
    # Tests RGBA(float64) -> Y (float32) conversion
    b1 = Bitmap(Bitmap.PixelFormat.RGBA, Struct.Type.Float64, [3, 1])
    b2 = np.array(b1, copy=False)
    b2[:] = [[[1, 0, 0, 1], [0, 1, 0, 0.5], [0, 0, 1, 0]]]
    b3 = np.array(b1.convert(Bitmap.PixelFormat.Y, Struct.Type.Float32,
                             False)).ravel()
    assert np.allclose(b3, [0.212671, 0.715160, 0.072169])
def test_finite_difference(test_name, make_scene, diff_integrator, diff_spp,
                           diff_passes, fd_integrator, fd_spp, fd_passes,
                           fd_eps):

    print("Running test:", test_name)

    path = "output/" + test_name + "/"
    if not os.path.isdir(path):
        os.makedirs(path)

    print("Rendering finite differences...")

    scene_fd0 = make_scene(fd_integrator, fd_spp, 0)
    scene_fd1 = make_scene(fd_integrator, fd_spp, fd_eps)
    fsize = scene_fd0.sensors()[0].film().size()

    for i in range(fd_passes):
        print("pass:"******"Writing " + path + 'radiance_fd0.exr')
    Bitmap(values_fd0).write(path + 'radiance_fd0.exr')
    print("Writing " + path + 'radiance_fd1.exr')
    Bitmap(values_fd1).write(path + 'radiance_fd1.exr')

    gradient_fd = (values_fd1 - values_fd0) / fd_eps
    gradient_fd = gradient_fd[:, :, [0]]

    scale = np.abs(gradient_fd).max()
    write_gradient_image(gradient_fd / scale, path + 'gradient_fd', fsize)

    del scene_fd0, scene_fd1, values_fd0, values_fd1, channels, gradient_fd

    print("Rendering gradients... ({} spp, {} passes)".format(
        diff_spp, diff_passes))

    scene = make_scene(diff_integrator, diff_spp, None)
    assert scene is not None
    params = traverse(scene)
    params.keep(['SDF.data'])

    gradient_rp_np = render_gradient(scene, diff_spp, diff_passes, scale, path,
                                     params, fd_eps)
Пример #5
0
def test_read_write_hdr(tmpdir):
    np.random.seed(12345)

    b = Bitmap(Bitmap.PixelFormat.RGB, Struct.Type.Float32, [10, 20])
    ref = np.float32(np.random.random((20, 10, 3)))
    np.array(b, copy=False)[:] = ref[...]
    tmp_file = os.path.join(str(tmpdir), "out.hdr")
    b.write(tmp_file)
    b2 = Bitmap(tmp_file)
    assert np.abs(np.mean(np.array(b2) - ref)) < 1e-2
    os.remove(tmp_file)
Пример #6
0
def test_read_write_ppm(tmpdir):
    np.random.seed(12345)

    b = Bitmap(Bitmap.PixelFormat.RGB, Struct.Type.UInt8, [10, 20])
    ref = np.uint8(np.random.random((20, 10, 3)) * 255)
    np.array(b, copy=False)[:] = ref[...]
    tmp_file = os.path.join(str(tmpdir), "out.ppm")
    b.write(tmp_file)
    b2 = Bitmap(tmp_file)
    assert np.abs(np.mean(np.array(b2) - ref)) == 0
    os.remove(tmp_file)
Пример #7
0
def test15_test_dither():
    from mitsuba.core import Bitmap
    import numpy.linalg as la

    b = Bitmap(Bitmap.PixelFormat.Y, Struct.Type.Float32, [10, 256])
    value = np.linspace(0, 1 / 255.0, 10)
    np.array(b, copy=False)[:, :, 0] = np.tile(value, (256, 1))
    b = b.convert(Bitmap.PixelFormat.Y, Struct.Type.UInt8, False)
    b = b.convert(Bitmap.PixelFormat.Y, Struct.Type.Float32, False)
    err = la.norm(np.mean(np.array(b, copy=False), axis=(0, 2)) - value)
    assert(err < 5e-4)
Пример #8
0
def render(scene, write_to):
    from mitsuba.core import Bitmap, Struct

    success = scene.integrator().render(scene, scene.sensors()[0])
    assert success

    film = scene.sensors()[0].film()
    bitmap = film.bitmap(raw=False)

    if not bitmap.pixel_format() == Bitmap.PixelFormat.MultiChannel:
        bitmap.convert(Bitmap.PixelFormat.RGB, Struct.Type.UInt8,
                       True).write(write_to)
    elif bitmap.channel_count() == 16:
        # Stokes output, rather specialized for 'integrator_stokes_cbox' scene atm.
        data_np = np.array(bitmap, copy=False).astype(np.float)
        s0 = data_np[:, :, 4]
        z = np.zeros(s0.shape)
        s1 = np.dstack([
            np.maximum(0, -data_np[:, :, 7]),
            np.maximum(0, data_np[:, :, 7]), z
        ])
        s2 = np.dstack([
            np.maximum(0, -data_np[:, :, 10]),
            np.maximum(0, data_np[:, :, 10]), z
        ])
        s3 = np.dstack([
            np.maximum(0, -data_np[:, :, 13]),
            np.maximum(0, data_np[:, :, 13]), z
        ])
        Bitmap(s0).convert(Bitmap.PixelFormat.RGB, Struct.Type.UInt8,
                           True).write(write_to)
        Bitmap(s1).convert(Bitmap.PixelFormat.RGB, Struct.Type.UInt8,
                           True).write(write_to.replace('.jpg', '_s1.jpg'))
        Bitmap(s3).convert(Bitmap.PixelFormat.RGB, Struct.Type.UInt8,
                           True).write(write_to.replace('.jpg', '_s3.jpg'))
        Bitmap(s2).convert(Bitmap.PixelFormat.RGB, Struct.Type.UInt8,
                           True).write(write_to.replace('.jpg', '_s2.jpg'))
    else:
        for name, b in bitmap.split():
            if name == '<root>':
                continue

            # normalize depth map
            if name == 'depth.y':
                data_np = np.array(b, copy=False)
                min_val = np.min(data_np)
                max_val = np.max(data_np)
                data_np = (data_np - min_val) / (max_val - min_val)
                b = Bitmap(data_np, Bitmap.PixelFormat.Y)

            pixel_format = b.pixel_format()
            if not pixel_format == Bitmap.PixelFormat.XYZ:
                pixel_format = Bitmap.PixelFormat.RGB

            f_name = write_to if name == 'image' else write_to.replace(
                '.jpg', '_%s.jpg' % name)
            b.convert(pixel_format, Struct.Type.UInt8, True).write(f_name)
Пример #9
0
 def __init__(self, render_ctx):
     super(InternalBufferDisplay, self).__init__()
     self.ctx = render_ctx
     self.film = self.ctx.scene.getFilm()
     self.size = self.film.getSize()
     self.bitmap = Bitmap(Bitmap.ERGBA, Bitmap.EFloat32, self.size)
     self.bitmap.clear()
     self.buffer = None
     self.fast_buffer = True
     self.do_cancel = False
     self.time = 0
     self.delay = .5
     self.ctx.queue.registerListener(self)
Пример #10
0
def time_errors(method, scene_idx):
    scene_name = scene_names[scene_idx]
    crop_s = 80
    crop_1_x, crop_1_y, crop_2_x, crop_2_y = scene_crops[scene_idx]
    path = "results_{}".format(scene_name)

    N = 20
    times = 10**np.linspace(0, 4, N)

    images = []
    for i in range(len(times)):
        img = np.array(Bitmap("{}/{}_time_{}.exr".format(path, method, i)))

        crops = (img[crop_1_y:crop_1_y+crop_s, crop_1_x:crop_1_x+crop_s],
                 img[crop_2_y:crop_2_y+crop_s, crop_2_x:crop_2_x+crop_s],
                 img)
        images.append(crops)

    ref_1, ref_2, ref_full = images[-1]
    error_1 = []; error_2 = []; error_full = []
    for i in range(N-1):
        cur_1, cur_2, cur_full = images[i]
        error_1.append(error(ref_1, cur_1))
        error_2.append(error(ref_2, cur_2))
        error_full.append(error(ref_full, cur_full))

    return error_1, error_2, error_full
Пример #11
0
            def get_bitmap_buffer(self, passes=1):
                bitmap_clone = self.bitmap.clone()
                bitmap_clone.flipVertically()

                if passes == 1:
                    return bitmap_clone.buffer()

                if self.buffer is None:
                    self.buffer = Bitmap(
                        Bitmap.ERGBA, Bitmap.EFloat32,
                        Vector2i(self.size[0], self.size[1] * passes))
                    self.buffer.clear()

                self.buffer.copyFrom(bitmap_clone)

                return self.buffer.buffer()
Пример #12
0
def gauss_normalmap(alpha_x,
                    alpha_y,
                    res,
                    scale,
                    num_waves=1000,
                    name=None,
                    noise=0.0,
                    encoding_yan16=False,
                    seed=1):
    np.random.seed(seed)
    U1 = np.random.rand(num_waves)
    U2 = np.random.rand(num_waves)
    U3 = np.random.rand(num_waves)

    factor = np.sqrt(2 / num_waves)

    phi = 2 * np.pi * U1
    theta = 2 * np.pi * U2
    r = np.sqrt(-np.log(1.0 - U3))

    fx = r * np.cos(theta) * alpha_x
    fy = r * np.sin(theta) * alpha_y

    def height(pos):
        return factor * np.sum(np.cos(phi + pos[0] * fx + pos[1] * fy))

    def slope(pos):
        tmp = np.sin(phi + pos[0] * fx + pos[1] * fy)
        res_x = np.sum(-fx * tmp)
        res_y = np.sum(-fy * tmp)
        return factor * np.array([res_x, res_y])

    def normal(pos, noise):
        s = slope(pos)
        n = np.array([
            -s[0] + noise * np.random.uniform(-1, 1),
            -s[1] + noise * np.random.uniform(-1, 1), 1.0
        ])
        return n / np.sqrt(n[0]**2 + n[1]**2 + n[2]**2)

    xx = np.linspace(0, scale, res)
    yy = np.linspace(0, scale, res)

    normalmap = np.zeros((res, res, 3))
    for j, x in enumerate(xx):
        print("Generate \"%s\": %.2f%%" % (name, 100 * j / (res - 1)),
              end="\r")
        for i, y in enumerate(yy):
            n = normal(np.array([x, y]), noise)
            if encoding_yan16:
                normalmap[i, j, 0] = n[0]
                normalmap[i, j, 1] = n[1]
                normalmap[i, j, 2] = n[2]
            else:
                normalmap[i, j, 0] = 0.5 * (n[0] + 1.0)
                normalmap[i, j, 1] = 0.5 * (n[1] + 1.0)
                normalmap[i, j, 2] = 0.5 * (n[2] + 1.0)
    Bitmap(normalmap).convert(Bitmap.PixelFormat.RGB, Struct.Type.Float32,
                              False).write("textures/{}.exr".format(name))
    print("")
Пример #13
0
def write_bitmap(filename, data, resolution, write_async=True):
    """
    Write the linearized RGB image in `data` to a PNG/EXR/.. file with
    resolution `resolution`.
    """
    import numpy as np
    from mitsuba.core import Bitmap, Struct

    if type(data).__name__ == 'Tensor':
        data = data.detach().cpu()

    data = np.array(data.numpy())
    data = data.reshape(*resolution, -1)
    bitmap = Bitmap(data)
    if filename.endswith('.png') or \
       filename.endswith('.jpg') or \
       filename.endswith('.jpeg'):
        bitmap = bitmap.convert(Bitmap.PixelFormat.RGB,
                                Struct.Type.UInt8, True)
    quality = 0 if filename.endswith('png') else -1

    if write_async:
        bitmap.write_async(filename, quality=quality)
    else:
        bitmap.write(filename, quality=quality)
Пример #14
0
def test_read_write_png(tmpdir):
    np.random.seed(12345)
    tmp_file = os.path.join(str(tmpdir), "out.png")

    b = Bitmap(Bitmap.PixelFormat.Y, Struct.Type.UInt8, [10, 10])
    ref = np.uint8(np.random.random((10, 10)) * 255)
    np.array(b, copy=False)[:] = ref[..., np.newaxis]
    b.write(tmp_file)
    b2 = Bitmap(tmp_file)
    assert np.sum(np.abs(np.float32(np.array(b2)[:, :, 0]) - ref)) == 0

    b = Bitmap(Bitmap.PixelFormat.RGBA, Struct.Type.UInt8, [10, 10])
    ref = np.uint8(np.random.random((10, 10, 4)) * 255)
    np.array(b, copy=False)[:] = ref
    b.write(tmp_file)
    b2 = Bitmap(tmp_file)
    assert np.sum(np.abs(np.float32(np.array(b2)) - ref)) == 0

    os.remove(tmp_file)
Пример #15
0
def write_gradient_image(grad, name, fsize):

    # print("grad min", grad.min())
    # print("grad max", grad.max())

    # Compute RGB channels for .exr image (no grad = black)

    grad_R = grad.copy()
    grad_R[grad_R < 0] = 0.0
    grad_B = grad.copy()
    grad_B[grad_B > 0] = 0.0
    grad_B *= -1.0
    grad_G = grad.copy() * 0.0

    grad_np = np.concatenate((grad_R, grad_G, grad_B), axis=2)

    print('Writing', name + ".exr")
    Bitmap(grad_np).write(name + ".exr")

    # Compute RGB channels for .png image (no grad = white)

    grad_clamped = grad.copy()
    grad_clamped *= 3.0  # Arbitrary, for visualization
    grad_clamped[grad_clamped > 1] = 1
    grad_clamped[grad_clamped < -1] = -1
    grad_R = grad_clamped.copy()
    grad_G = grad_clamped.copy()
    grad_B = grad_clamped.copy()

    pos = grad_clamped >= 0
    neg = grad_clamped < 0
    grad_R[neg] = (1.0 + grad_clamped)[neg]
    grad_R[pos] = 1.0
    grad_G[neg] = (1.0 + grad_clamped)[neg]
    grad_G[pos] = (1.0 - grad_clamped)[pos]
    grad_B[neg] = 1.0
    grad_B[pos] = (1.0 - grad_clamped)[pos]
    grad_np = np.concatenate((grad_R, grad_G, grad_B), axis=2)

    print('Writing', name + ".png")
    Bitmap(((np.clip(grad_np, a_min=0.0, a_max=1.0)) * 255).astype(
        np.uint8)).write(name + ".png")
Пример #16
0
def test_read_write_jpeg(tmpdir):
    np.random.seed(12345)
    tmp_file = os.path.join(str(tmpdir), "out.jpg")

    b = Bitmap(Bitmap.PixelFormat.Y, Struct.Type.UInt8, [10, 10])
    ref = np.uint8(np.random.random((10, 10)) * 255)
    np.array(b, copy=False)[:] = ref[..., np.newaxis]
    b.write(tmp_file, quality=50)
    b2 = Bitmap(tmp_file)
    assert np.sum(np.abs(np.float32(np.array(b2)[:, :, 0]) -
                         ref)) / (10 * 10 * 255) < 0.07

    b = Bitmap(Bitmap.PixelFormat.RGB, Struct.Type.UInt8, [10, 10])
    ref = np.uint8(np.random.random((10, 10, 3)) * 255)
    np.array(b, copy=False)[:] = ref
    b.write(tmp_file, quality=100)
    b2 = Bitmap(tmp_file)
    assert np.sum(
        np.abs(np.float32(np.array(b2)) - ref)) / (3 * 10 * 10 * 255) < 0.2

    os.remove(tmp_file)
Пример #17
0
def test_convert_rgb_y_gamma(tmpdir):
    def to_srgb(value):
        if value <= 0.0031308:
            return 12.92 * value
        return 1.055 * (value**(1.0 / 2.4)) - 0.055

    # Tests RGBA(float64) -> Y (uint8_t, linear) conversion
    b1 = Bitmap(Bitmap.PixelFormat.RGBA, Struct.Type.Float64, [3, 1])
    b2 = np.array(b1, copy=False)
    b2[:] = [[[1, 0, 0, 1], [0, 1, 0, 0.5], [0, 0, 1, 0]]]
    b3 = np.array(b1.convert(Bitmap.PixelFormat.Y, Struct.Type.UInt8,
                             False)).ravel()
    assert np.allclose(b3, [0.212671 * 255, 0.715160 * 255, 0.072169 * 255],
                       atol=1)

    # Tests RGBA(float64) -> Y (uint8_t, gamma) conversion
    b1 = Bitmap(Bitmap.PixelFormat.RGBA, Struct.Type.Float64, [3, 1])
    b2 = np.array(b1, copy=False)
    b2[:] = [[[1, 0, 0, 1], [0, 1, 0, 0.5], [0, 0, 1, 0]]]
    b3 = np.array(b1.convert(Bitmap.PixelFormat.Y, Struct.Type.UInt8,
                             True)).ravel()
    assert np.allclose(b3, [
        to_srgb(0.212671) * 255,
        to_srgb(0.715160) * 255,
        to_srgb(0.072169) * 255
    ],
                       atol=1)
Пример #18
0
 def __init__(self, render_ctx):
     super(InternalBufferDisplay, self).__init__()
     self.ctx = render_ctx
     self.film = self.ctx.scene.getFilm()
     self.size = self.film.getSize()
     self.bitmap = Bitmap(Bitmap.ERGBA, Bitmap.EFloat32, self.size)
     self.bitmap.clear()
     self.buffer = None
     self.fast_buffer = True
     self.do_cancel = False
     self.time = 0
     self.delay = .5
     self.ctx.queue.registerListener(self)
Пример #19
0
            def get_bitmap_buffer(self, passes=1):
                bitmap_clone = self.bitmap.clone()
                bitmap_clone.flipVertically()

                if passes == 1:
                    return bitmap_clone.buffer()

                if self.buffer is None:
                    self.buffer = Bitmap(Bitmap.ERGBA, Bitmap.EFloat32, Vector2i(self.size[0], self.size[1] * passes))
                    self.buffer.clear()

                self.buffer.copyFrom(bitmap_clone)

                return self.buffer.buffer()
Пример #20
0
def test_premultiply_alpha(tmpdir):
    # Tests RGBA(float64) -> Y (float32) conversion
    b1 = Bitmap(Bitmap.PixelFormat.RGBA, Struct.Type.Float64, [3, 1])
    assert b1.premultiplied_alpha()
    b1.set_premultiplied_alpha(False)
    assert not b1.premultiplied_alpha()

    b2 = np.array(b1, copy=False)
    b2[:] = [[[1, 0, 0, 1], [0, 1, 0, 0.5], [0, 0, 1, 0]]]

    # Premultiply
    b3 = np.array(
        b1.convert(Bitmap.PixelFormat.RGBA, Struct.Type.Float32, False,
                   Bitmap.AlphaTransform.Premultiply)).ravel()
    assert np.allclose(
        b3, [1.0, 0.0, 0.0, 1.0, 0.0, 0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0])

    # Unpremultiply
    b1.set_premultiplied_alpha(True)
    b3 = np.array(
        b1.convert(Bitmap.PixelFormat.RGBA, Struct.Type.Float32, False,
                   Bitmap.AlphaTransform.Unpremultiply)).ravel()
    assert np.allclose(
        b3, [1.0, 0.0, 0.0, 1.0, 0.0, 2, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0])
Пример #21
0
def run_rendering(xml, save_name):
    scene = load_file(xml)
    sensor = scene.sensors()[0]
    scene.integrator().render(scene, sensor)
    film = sensor.film()

    result = film.bitmap(raw=False)
    result = np.array(result, copy=False).astype(np.float)
    image = np.stack([result[:, :, 2], result[:, :, 1], result[:, :, 0]],
                     axis=-1)
    image = np.array(
        Bitmap(image, Bitmap.PixelFormat.RGB).convert(Bitmap.PixelFormat.RGB,
                                                      Struct.Type.UInt8,
                                                      srgb_gamma=True))

    cv2.imwrite(dataset_output_dir + save_name, image)
    cv2.waitKey()
Пример #22
0
def test_read_convert_yc(tmpdir):
    # Tests reading & upsampling a luminance/chroma image
    b = Bitmap(find_resource('resources/data/tests/bitmap/XYZ_YC.exr'))
    # Tests float16 XYZ -> float32 RGBA conversion
    b = b.convert(Bitmap.PixelFormat.RGBA, Struct.Type.Float32, False)
    ref = [0.36595437, 0.27774358, 0.11499051, 1.]
    # Tests automatic Bitmap->NumPy conversion
    assert np.allclose(np.mean(b, axis=(0, 1)), ref, atol=1e-3)
    tmp_file = os.path.join(str(tmpdir), "out.exr")
    # Tests bitmap resampling filters
    rfilter = mitsuba.core.xml.load_string(
        "<rfilter version='2.0.0' type='box'/>")
    b = b.resample(
        [1, 1], rfilter,
        (FilterBoundaryCondition.Zero, FilterBoundaryCondition.Zero))
    # Tests OpenEXR bitmap writing
    b.write(tmp_file)
    b = Bitmap(tmp_file)
    os.remove(tmp_file)
    assert np.allclose(np.mean(b, axis=(0, 1)), ref, atol=1e-3)
def render_gradient(scene, spp, pass_count, scale, path, params, eps):
    sensor = scene.sensors()[0]
    fsize = sensor.film().size()

    for i in range(pass_count):
        print("grad:", i, end='\r')
        set_requires_gradient(params['SDF.data'])
        y_i = render(scene)

        set_gradient(params['SDF.data'], np.sign(eps), backward=False)

        Float32.forward()  #i == pass_count - 1

        nb_channels = len(y_i) // (fsize[1] * fsize[0])
        grad_i = gradient(y_i).numpy().reshape(fsize[1], fsize[0], nb_channels)
        grad_i = grad_i[:, :, 0]

        grad_i[grad_i != grad_i] = 0
        if i == 0:
            y = y_i.numpy()
            y[y != y] = 0
            grad = grad_i
        else:
            temp = detach(y_i).numpy()
            temp[temp != temp] = 0
            y += temp
            del y_i
            grad += grad_i

    grad /= pass_count
    y /= pass_count

    if (scale == 0.0):
        scale = np.abs(grad).max()

    grad = grad.reshape(fsize[1], fsize[0], 1)

    write_gradient_image(grad / scale, path + 'gradient', fsize)

    y_np = y.reshape(fsize[1], fsize[0], nb_channels)
    print('Writing ' + path + 'radiance.exr')
    Bitmap(y_np).write(path + 'radiance.exr')

    return grad
Пример #24
0
def test_read_write_complex_exr(tmpdir):
    # Tests reading and writing of complex multi-channel images with custom properties
    b1 = Bitmap(Bitmap.PixelFormat.MultiChannel, Struct.Type.Float32, [4, 5],
                6)
    a = b1.struct_()
    for i in range(6):
        a[i].name = "my_ch_%i" % i
    b2 = np.array(b1, copy=False)
    meta = b1.metadata()
    meta["str_prop"] = "value"
    meta["int_prop"] = 15
    meta["dbl_prop"] = 30.0
    meta["vec3_prop"] = [1.0, 2.0, 3.0]
    # meta["mat_prop"] = np.arange(16, dtype=float_dtype).reshape((4, 4)) + np.eye(4, dtype=float_dtype) # TODO py::implicitly_convertible<py::array, Transform4f>() doesn't seem to work in transform_v.cpp

    assert b2.shape == (5, 4, 6)
    assert b2.dtype == np.float32
    b2[:] = np.arange(4 * 5 * 6).reshape((5, 4, 6))
    tmp_file = os.path.join(str(tmpdir), "out.exr")
    b1.write(tmp_file)

    b3 = Bitmap(tmp_file)
    os.remove(tmp_file)
    meta = b3.metadata()
    meta.remove_property("generatedBy")
    meta.remove_property("pixelAspectRatio")
    meta.remove_property("screenWindowWidth")
    assert b3 == b1
    b2[0, 0, 0] = 3
    assert b3 != b1
    b2[0, 0, 0] = 0
    assert b3 == b1
    assert str(b3) == str(b1)
    meta["str_prop"] = "value2"
    assert b3 != b1
    assert str(b3) != str(b1)
Пример #25
0
def test_render(variants_all, scene_fname):
    from mitsuba.core import Bitmap, Struct, Thread

    scene_dir = dirname(scene_fname)

    if os.path.split(scene_dir)[1] in EXCLUDE_FOLDERS:
        pytest.skip(f"Skip rendering scene {scene_fname}")

    Thread.thread().file_resolver().append(scene_dir)

    ref_fname = get_ref_fname(scene_fname)
    assert os.path.exists(ref_fname)

    scene = mitsuba.core.xml.load_file(scene_fname,
                                       parameters=[('spp', str(32))])
    scene.integrator().render(scene, scene.sensors()[0])

    film = scene.sensors()[0].film()

    cur_bitmap = film.bitmap(raw=True).convert(Bitmap.PixelFormat.RGB,
                                               Struct.Type.Float32, False)
    cur_image = np.array(cur_bitmap, copy=False)

    ref_bitmap = Bitmap(ref_fname).convert(Bitmap.PixelFormat.RGB,
                                           Struct.Type.Float32, False)
    ref_image = np.array(ref_bitmap, copy=False)

    error = np.mean(np.mean(np.abs(ref_image - cur_image)))
    threshold = 0.5 * np.mean(np.mean(ref_image))
    success = error < threshold

    if not success:
        print("Failed. error: {} // threshold: {}".format(error, threshold))

        # Write rendered image to a file
        cur_fname = os.path.splitext(
            scene_fname)[0] + '_render_' + mitsuba.variant() + '.exr'
        cur_bitmap.write(cur_fname)
        print('Saved rendered image to: ' + cur_fname)

        assert False
Пример #26
0
def write_gradient_image(grad, name):
    """Convert signed floats to blue/red gradient exr image"""
    from mitsuba.core import Bitmap

    convert_to_rgb = True

    if convert_to_rgb:
        # Compute RGB channels for .exr image (no grad = black)
        grad_R = grad.copy()
        grad_R[grad_R < 0] = 0.0
        grad_B = grad.copy()
        grad_B[grad_B > 0] = 0.0
        grad_B *= -1.0
        grad_G = grad.copy() * 0.0

        grad_np = np.concatenate((grad_R, grad_G, grad_B), axis=2)
    else:
        grad_np = np.concatenate((grad, grad, grad), axis=2)

    print('Writing', name + ".exr")
    Bitmap(grad_np).write(name + ".exr")
    def _get_film_ensure_initialized(self, job):
        """ Ensure that all internal data structure are set up to deal
        with the given rendering job """
        film = job.getScene().getFilm()
        size = film.getSize()

        if self.size != size:
            self.size = size
            # Round the buffer size to the next power of 4 to ensure 32-bit
            # aligned scanlines in the underlying buffer. This is needed so
            # that QtGui.QImage and mitsuba.Bitmap have exactly the same
            # in-memory representation.

            bufsize = Vector2i((size.x + 3) // 4 * 4, (size.y + 3) // 4 * 4)
            # Create an 8-bit Mitsuba bitmap that will store tonemapped pixels
            self.bitmap = Bitmap(Bitmap.ERGB, Bitmap.EUInt8, bufsize)
            self.bitmap.clear()
            # Create a QImage that is backed by the Mitsuba Bitmap instance
            # (i.e. without doing unnecessary bitmap copy operations)
            self.qimage = QImage(self.bitmap.getNativeBuffer(), self.size.x,
            self.size.y, QImage.Format_RGB888)
            self.callback(MitsubaRenderBuffer.GEOMETRY_CHANGED)
        return film
Пример #28
0
def imaging(blocks, film_size, aovs=False, invalid_sample=False):
    """Imaging result with aovs"""

    label = ['result']
    if aovs:
        label.append('scatter')
        label.append('non_scatter')

    if invalid_sample:
        label.append('invalid')

    for i in label:
        xyzaw_np = np.array(blocks[i].data()).reshape(
            [film_size[1], film_size[0], 5])

        bmp = Bitmap(xyzaw_np, Bitmap.PixelFormat.XYZAW)
        bmp = bmp.convert(Bitmap.PixelFormat.RGB,
                          Struct.Type.Float32,
                          srgb_gamma=False)
        bmp.write(i + '.exr')
        bmp.convert(Bitmap.PixelFormat.RGB, Struct.Type.UInt8,
                    srgb_gamma=True).write(i + '.jpg')
Пример #29
0
def run(prefix):
	img= cv2.imread(dataset_output_dir + prefix + 'mask_2x.png')
	img_i = cv2.bitwise_not(img)
	cv2.imwrite(output_dir + 'graycode_01.png', img_i)
	
	copyfile(dataset_output_dir + prefix + 'rho_2x.png', output_dir + 'graycode_02.png')
	
	tree = et.parse('img_gen.xml')
	root = tree.getroot()
	for i in range(1, 21):
			
		r = root.find('shape/emitter/texture/string')
		r.set('value', graycode_dir + 'graycode_'+ str(i) +'.png')
		r = root.findall('sensor/film/integer')
		[rr.set('value', '1024') for rr in r]
		tree.write('img_gen.xml')
		
		
		scene = load_file("img_gen.xml")
		sensor = scene.sensors()[0]
		scene.integrator().render(scene, sensor)
		film = sensor.film()
		
		result = film.bitmap(raw=False)
		result = np.array(result, copy=False).astype(np.float)
		image = np.stack([result[:, :, 2], result[:, :, 1], result[:, :, 0]], axis=-1)
		image = np.array(Bitmap(image, Bitmap.PixelFormat.RGB).convert(Bitmap.PixelFormat.RGB, Struct.Type.UInt8, srgb_gamma=True))
		
		#cv2.imshow("image", image)
		cv2.imwrite(output_dir + 'graycode_'+ str(f'{i+2:02d}') +'.png',image)
		cv2.waitKey()
	
	f_run()
	
	copyfile('flow_gen/flow/flow.flo', dataset_output_dir + prefix + 'flow_2x.flo')
	copyfile('flow_gen/flow/flow.png', dataset_output_dir + prefix + 'flow_2x.png')
Пример #30
0
                                               sample3=0)

# Intersect rays with the scene geometry
surface_interaction = scene.ray_intersect(rays)

# Given intersection, compute the final pixel values as the depth t
# of the sampled surface interaction
result = surface_interaction.t

# Set to zero if no intersection was found
result[~surface_interaction.is_valid()] = 0

block = ImageBlock(film.crop_size(),
                   channel_count=5,
                   filter=film.reconstruction_filter(),
                   border=False)
block.clear()
# ImageBlock expects RGB values (Array of size (n, 3))
block.put(position_sample, rays.wavelengths, Vector3f(result, result, result),
          1)

# Write out the result from the ImageBlock
# Internally, ImageBlock stores values in XYZAW format
# (color XYZ, alpha value A and weight W)
xyzaw_np = block.data().reshape([film_size[1], film_size[0], 5])

# We then create a Bitmap from these values and save it out as EXR file
bmp = Bitmap(xyzaw_np, Bitmap.PixelFormat.XYZAW)
bmp = bmp.convert(Bitmap.PixelFormat.Y, Struct.Type.Float32, srgb_gamma=False)
bmp.write('depth.exr')
class MitsubaRenderBuffer(RenderListener):
    """
    Implements the Mitsuba callback interface to capture notifications about
    rendering progress. Partially completed image blocks are efficiently
    tonemapped into a local 8-bit Mitsuba Bitmap instance and exposed as a QImage.
    """
    RENDERING_FINISHED = 0
    RENDERING_CANCELLED = 1
    RENDERING_UPDATED = 2

    GEOMETRY_CHANGED = 3
    def __init__(self, queue, callback):
        super(MitsubaRenderBuffer, self).__init__()
        self.bitmap = self.qimage = None
        self.callback = callback
        self.time = 0
        self.size = Vector2i(0, 0)
        queue.registerListener(self)

    def workBeginEvent(self, job, wu, thr):
        """ Callback: a worker thread started rendering an image block.
        Draw a rectangle to highlight this """
        _ = self._get_film_ensure_initialized(job)
        self.bitmap.drawWorkUnit(wu.getOffset(), wu.getSize(), thr)
        self._potentially_send_update()

    def workEndEvent(self, job, wr, cancelled):
        """ Callback: a worker thread finished rendering an image block.
        Tonemap the associated pixels and store them in 'self.bitmap' """
        film = self._get_film_ensure_initialized(job)
        film.develop(wr.getOffset(), wr.getSize(), wr.getOffset(), self.bitmap)
        self._potentially_send_update()

    def refreshEvent(self, job):
        """ Callback: the entire image changed (some rendering techniques
        do this occasionally). Hence, tonemap the full film. """
        film = self._get_film_ensure_initialized(job)
        film.develop(Point2i(0), self.size, Point2i(0), self.bitmap)
        self._potentially_send_update()

    def finishJobEvent(self, job, cancelled):
        """ Callback: the rendering job has finished or was cancelled.
        Re-develop the image once more for the final result. """
        film = self._get_film_ensure_initialized(job)
        film.develop(Point2i(0), self.size, Point2i(0), self.bitmap)
        self.callback(MitsubaRenderBuffer.RENDERING_CANCELLED if cancelled else MitsubaRenderBuffer.RENDERING_FINISHED)

    def _get_film_ensure_initialized(self, job):
        """ Ensure that all internal data structure are set up to deal
        with the given rendering job """
        film = job.getScene().getFilm()
        size = film.getSize()

        if self.size != size:
            self.size = size
            # Round the buffer size to the next power of 4 to ensure 32-bit
            # aligned scanlines in the underlying buffer. This is needed so
            # that QtGui.QImage and mitsuba.Bitmap have exactly the same
            # in-memory representation.

            bufsize = Vector2i((size.x + 3) // 4 * 4, (size.y + 3) // 4 * 4)
            # Create an 8-bit Mitsuba bitmap that will store tonemapped pixels
            self.bitmap = Bitmap(Bitmap.ERGB, Bitmap.EUInt8, bufsize)
            self.bitmap.clear()
            # Create a QImage that is backed by the Mitsuba Bitmap instance
            # (i.e. without doing unnecessary bitmap copy operations)
            self.qimage = QImage(self.bitmap.getNativeBuffer(), self.size.x,
            self.size.y, QImage.Format_RGB888)
            self.callback(MitsubaRenderBuffer.GEOMETRY_CHANGED)
        return film

    def _potentially_send_update(self):
        """ Send an update request to any attached widgets, but not too often """
        now = time.time()
        if now - self.time > .25:
            self.time = now
            self.callback(MitsubaRenderBuffer.RENDERING_UPDATED)
Пример #32
0
def test_accumulate():
    # ----- Accumulate the whole bitmap
    b1 = Bitmap(Bitmap.PixelFormat.RGB, Struct.Type.UInt8, [10, 10])
    n = b1.height() * b1.width()
    # 0, 1, 2, ..., 99
    np.array(b1, copy=False)[:] = np.arange(n).reshape(b1.height(), b1.width(),
                                                       1)

    b2 = Bitmap(Bitmap.PixelFormat.RGB, Struct.Type.UInt8, [10, 10])
    # 100, 99, ..., 1
    np.array(b2,
             copy=False)[:] = np.arange(n, 0,
                                        -1).reshape(b2.height(), b2.width(), 1)

    b1.accumulate(b2)
    assert np.all(np.array(b1, copy=False) == n)

    # ----- Accumulate only a sub-frame
    np.array(b1, copy=False)[:] = np.arange(n).reshape(b1.height(), b1.width(),
                                                       1)
    ref = np.array(b1)
    ref[1:6, 3:4, :] += np.array(b2, copy=False)[3:8, 5:6, :]

    # Recall that positions are specified as (x, y) in Mitsuba convention,
    # but (row, column) in arrays.
    b1.accumulate(b2, [5, 3], [3, 1], [1, 5])
    assert np.all(np.array(b1, copy=False) == ref)
Пример #33
0
def test_read_tga():
    b1 = Bitmap(
        find_resource('resources/data/tests/bitmap/tga_uncompressed.tga'))
    b2 = Bitmap(
        find_resource('resources/data/tests/bitmap/tga_compressed.tga'))
    assert b1 == b2
Пример #34
0
def test_read_bmp():
    b = Bitmap(find_resource('resources/data/common/textures/flower.bmp'))
    ref = [136.50910448, 134.07641791, 85.67253731]
    assert np.allclose(np.mean(b, axis=(0, 1)), ref)
Пример #35
0
        class InternalBufferDisplay(RenderListener):
            '''
            Class to monitor rendering and update blender render result
            '''
            def __init__(self, render_ctx):
                super(InternalBufferDisplay, self).__init__()
                self.ctx = render_ctx
                self.film = self.ctx.scene.getFilm()
                self.size = self.film.getSize()
                self.bitmap = Bitmap(Bitmap.ERGBA, Bitmap.EFloat32, self.size)
                self.bitmap.clear()
                self.buffer = None
                self.fast_buffer = True
                self.do_cancel = False
                self.time = 0
                self.delay = .5
                self.ctx.queue.registerListener(self)

            def get_offset_size(self, wu):
                offset = wu.getOffset()
                size = wu.getSize()
                end = offset + size
                offset.x = max(0, offset.x)
                offset.y = max(0, offset.y)
                end.x = min(self.size.x, end.x)
                end.y = min(self.size.y, end.y)
                size = end - offset

                return offset, size

            def workBeginEvent(self, job, wu, thr):
                offset, size = self.get_offset_size(wu)
                self.bitmap.drawWorkUnit(offset, size, thr)
                self.timed_update_result()

            def workEndEvent(self, job, wr, cancelled):
                offset, size = self.get_offset_size(wr)
                self.film.develop(offset, size, offset, self.bitmap)
                self.timed_update_result()

            def refreshEvent(self, job):
                self.film.develop(Point2i(0), self.size, Point2i(0), self.bitmap)
                self.update_result()

            def finishJobEvent(self, job, cancelled):
                MtsLog('Render Job Finished')
                self.film.develop(Point2i(0), self.size, Point2i(0), self.bitmap)
                self.update_result(render_end=True)

            def get_bitmap_buffer(self, passes=1):
                bitmap_clone = self.bitmap.clone()
                bitmap_clone.flipVertically()

                if passes == 1:
                    return bitmap_clone.buffer()

                if self.buffer is None:
                    self.buffer = Bitmap(Bitmap.ERGBA, Bitmap.EFloat32, Vector2i(self.size[0], self.size[1] * passes))
                    self.buffer.clear()

                self.buffer.copyFrom(bitmap_clone)

                return self.buffer.buffer()

            def get_bitmap_list(self):
                self.delay = 1.5
                bitmap_list = numpy.ndarray((self.size[0] * self.size[1], 4), buffer=self.get_bitmap_buffer(), dtype='float32')  # .tolist()

                return bitmap_list

            def timed_update_result(self):
                now = time.time()

                if now - self.time > self.delay:
                    self.time = now
                    self.update_result()

            def update_result(self, render_end=False):
                if self.ctx.test_break():
                    return

                try:
                    render_result = self.ctx.render_engine.begin_result(0, 0, self.size[0], self.size[1])

                    if render_result is None:
                        err_msg = 'ERROR: Cannot not load render result: begin_result() returned None.'
                        self.do_cancel = True
                        raise Exception(err_msg)

                    if self.fast_buffer:
                        passes = len(render_result.layers[0].passes)
                        bitmap_buffer = self.get_bitmap_buffer(passes)
                        render_result.layers[0].passes.foreach_set('rect', bitmap_buffer)

                    else:
                        bitmap_buffer = self.get_bitmap_list()
                        render_result.layers[0].passes[0].rect = bitmap_buffer

                    self.ctx.render_engine.end_result(render_result, 0)

                except Exception as err:
                    MtsLog('%s' % err)

                    if self.fast_buffer:
                        self.fast_buffer = False

                    else:
                        self.do_cancel = True

                    if self.do_cancel:
                        self.ctx.render_cancel()