Exemple #1
0
def index():
    #     return 'Hello World!'
    model = vision_models.InceptionV1()
    model.load_graphdef()
    TEXTURE_SIZE = 1024
    mesh = meshutil.load_obj('article_models/bunny.obj')
    mesh = meshutil.normalize_mesh(mesh)
    original_texture = prepare_image('article_models/bunny.png',
                                     (TEXTURE_SIZE, TEXTURE_SIZE))
    style_url = 'https://upload.wikimedia.org/wikipedia/commons/d/db/RIAN_archive_409362_Literaturnaya_Gazeta_article_about_YuriGagarin%2C_first_man_in_space.jpg'
    style = prepare_image(style_url)
    renderer = glrenderer.MeshRenderer((512, 512))
    googlenet_style_layers = [
        'conv2d2',
        'mixed3a',
        'mixed3b',
        'mixed4a',
        'mixed4b',
        'mixed4c',
    ]
    googlenet_content_layer = 'mixed3b'
    content_weight = 100.0
    # Style Gram matrix weighted average decay coefficient
    style_decay = 0.95

    sess = create_session(timeout_sec=0)

    # t_fragments is used to feed rasterized UV coordinates for the current view.
    # Channels: [U, V, _, Alpha]. Alpha is 1 for pixels covered by the object, and
    # 0 for background.
    t_fragments = tf.placeholder(tf.float32, [None, None, 4])
    t_uv = t_fragments[..., :2]
    t_alpha = t_fragments[..., 3:]

    # Texture atlas to optimize
    t_texture = param.image(TEXTURE_SIZE, fft=True, decorrelate=True)[0]

    # Variable to store the original mesh texture used to render content views
    content_var = tf.Variable(tf.zeros([TEXTURE_SIZE, TEXTURE_SIZE, 3]),
                              trainable=False)

    # Sample current and original textures with provided pixel data
    t_joined_texture = tf.concat([t_texture, content_var], -1)
    t_joined_frame = sample_bilinear(t_joined_texture, t_uv) * t_alpha
    t_frame_current, t_frame_content = t_joined_frame[..., :3], t_joined_frame[
        ..., 3:]
    t_joined_frame = tf.stack([t_frame_current, t_frame_content], 0)

    # Feeding the rendered frames to the Neural Network
    t_input = tf.placeholder_with_default(t_joined_frame,
                                          [None, None, None, 3])
    model.import_graph(t_input)

    # style loss
    style_layers = [
        sess.graph.get_tensor_by_name('import/%s:0' % s)[0]
        for s in googlenet_style_layers
    ]
    # L1-loss seems to be more stable for GoogleNet
    # Note that we use style_decay>0 to average style-describing Gram matrices
    # over the recent viewports. Please refer to StyleLoss for the details.
    sl = StyleLoss(style_layers, style_decay, loss_func=mean_l1_loss)

    # content loss
    content_layer = sess.graph.get_tensor_by_name('import/%s:0' %
                                                  googlenet_content_layer)
    content_loss = mean_l1_loss(content_layer[0],
                                content_layer[1]) * content_weight

    # setup optimization
    total_loss = content_loss + sl.style_loss
    t_lr = tf.constant(0.05)
    trainer = tf.train.AdamOptimizer(t_lr)
    train_op = trainer.minimize(total_loss)

    init_op = tf.global_variables_initializer()
    loss_log = []

    reset(style, original_texture)
    run(mesh)
    texture = t_texture.eval()
    return show.textured_mesh(mesh, texture)
Exemple #2
0
    def textureStyle3D(self):
        print("Importing tensorflow...")
        import tensorflow as tf

        print("Checking that GPU is visible for tensorflow...")
        if not tf.test.is_gpu_available():
            raise Exception("No GPU available for tensorflow!")

        print("Importing other libraries...")
        import os
        import io
        import sys
        from string import Template
        from pathlib import Path

        import numpy as np
        import PIL.Image
        # import matplotlib.pylab as pl

        from IPython.display import clear_output, display, Image, HTML

        # if os.name != 'nt':
        #     from lucid.misc.gl.glcontext import create_opengl_context
        import OpenGL.GL as gl

        from lucid.misc.gl import meshutil
        from lucid.misc.gl import glrenderer
        import lucid.misc.io.showing as show
        import lucid.misc.io as lucid_io
        from lucid.misc.tfutil import create_session

        from lucid.modelzoo import vision_models
        from lucid.optvis import objectives
        from lucid.optvis import param
        from lucid.optvis.style import StyleLoss, mean_l1_loss
        from lucid.optvis.param.spatial import sample_bilinear

        # if os.name != 'nt':
        #     print("Creating OpenGL context...")
        #     create_opengl_context()
        gl.glGetString(gl.GL_VERSION)

        print("Loading vision model...")
        model = vision_models.InceptionV1()
        model.load_graphdef()

        def prepare_image(fn, size=None):
            data = lucid_io.reading.read(fn)
            im = PIL.Image.open(io.BytesIO(data)).convert('RGB')
            if size:
                im = im.resize(size, PIL.Image.ANTIALIAS)
            return np.float32(im) / 255.0

        self.loadCameras()

        print("Loading input model from '{}'...".format(self.input_model_path))
        mesh = meshutil.load_obj(self.input_model_path)
        if self.cameras is None:
            mesh = meshutil.normalize_mesh(mesh)

        print("Loading input texture from '{}'...".format(
            self.input_texture_path))
        original_texture = prepare_image(
            self.input_texture_path, (self.texture_size, self.texture_size))

        print("Loading style from '{}'...".format(self.style_path))
        style = prepare_image(self.style_path)

        rendering_width = self.rendering_width
        rendering_height = int(rendering_width // self.aspect_ratio)

        print("Creating renderer with resolution {}x{}...".format(
            rendering_width, rendering_height))
        renderer = glrenderer.MeshRenderer((rendering_width, rendering_height))
        if self.cameras is not None:
            print("  renderer fovy: {:.2f} degrees".format(self.max_fovy))
            renderer.fovy = self.max_fovy

        sess = create_session(timeout_sec=0)

        # t_fragments is used to feed rasterized UV coordinates for the current view.
        # Channels: [U, V, _, Alpha]. Alpha is 1 for pixels covered by the object, and
        # 0 for background.
        t_fragments = tf.placeholder(tf.float32, [None, None, 4])
        t_uv = t_fragments[..., :2]
        t_alpha = t_fragments[..., 3:]

        # Texture atlas to optimize
        t_texture = param.image(self.texture_size, fft=True,
                                decorrelate=True)[0]

        # Variable to store the original mesh texture used to render content views
        content_var = tf.Variable(tf.zeros(
            [self.texture_size, self.texture_size, 3]),
                                  trainable=False)

        # Sample current and original textures with provided pixel data
        t_joined_texture = tf.concat([t_texture, content_var], -1)
        t_joined_frame = sample_bilinear(t_joined_texture, t_uv) * t_alpha
        t_frame_current, t_frame_content = t_joined_frame[
            ..., :3], t_joined_frame[..., 3:]
        t_joined_frame = tf.stack([t_frame_current, t_frame_content], 0)

        # Feeding the rendered frames to the Neural Network
        t_input = tf.placeholder_with_default(t_joined_frame,
                                              [None, None, None, 3])
        model.import_graph(t_input)

        # style loss
        style_layers = [
            sess.graph.get_tensor_by_name('import/%s:0' % s)[0]
            for s in self.googlenet_style_layers
        ]
        # L1-loss seems to be more stable for GoogleNet
        # Note that we use style_decay>0 to average style-describing Gram matrices
        # over the recent viewports. Please refer to StyleLoss for the details.
        sl = StyleLoss(style_layers, self.style_decay, loss_func=mean_l1_loss)

        # content loss
        content_layer = sess.graph.get_tensor_by_name(
            'import/%s:0' % self.googlenet_content_layer)
        content_loss = mean_l1_loss(content_layer[0],
                                    content_layer[1]) * self.content_weight

        # setup optimization
        total_loss = content_loss + sl.style_loss
        t_lr = tf.constant(0.05)
        trainer = tf.train.AdamOptimizer(t_lr)
        train_op = trainer.minimize(total_loss)

        init_op = tf.global_variables_initializer()
        loss_log = []

        def reset(style_img, content_texture):
            del loss_log[:]
            init_op.run()
            sl.set_style({t_input: style_img[None, ...]})
            content_var.load(content_texture)

        def sample_random_view():
            if self.cameras is None:
                return meshutil.sample_view(10.0, 12.0)
            else:
                rand_m = self.cameras[np.random.randint(0, len(
                    self.cameras))]["transformToCamera"].copy()
                return rand_m

        def run(mesh, step_n=400):
            app = QtWidgets.QApplication.instance()

            for i in range(step_n):
                fragments = renderer.render_mesh(
                    modelview=sample_random_view(),
                    position=mesh['position'],
                    uv=mesh['uv'],
                    face=mesh['face'])
                _, loss = sess.run([train_op, [content_loss, sl.style_loss]],
                                   {t_fragments: fragments})
                loss_log.append(loss)
                if i == 0 or (i + 1) % 50 == 0:
                    # clear_output()
                    last_frame, last_content = sess.run(
                        [t_frame_current, t_frame_content],
                        {t_fragments: fragments})
                    # show.images([last_frame, last_content], ['current frame', 'content'])
                if i == 0 or (i + 1) % 10 == 0:
                    print(len(loss_log), loss)
                    pass

                # Show progress
                self.pBar.setValue(
                    (i + step_n // 10 + 1) / (step_n + step_n // 10) * 100)
                app.processEvents()

        reset(style, original_texture)

        print("Running {} iterations...".format(self.steps_number))
        run(mesh, step_n=self.steps_number)

        print("Finished!")
        texture = t_texture.eval()
        print("Exporting result texture to '{}'...".format(
            self.output_texture_path))
        lucid_io.save(texture, self.output_texture_path, quality=90)

        sess.close()

        print("Importing result model to Metashape '{}'...".format(
            self.result_model_path))
        chunk.model = None
        chunk.importModel(self.result_model_path)
        chunk.model.label = self.style_name

        Metashape.app.messageBox(
            "Everything worked fine!\n"
            "Please save project and RESTART Metashape!\n"
            "Because video memory was not released by TensorFlow!")
t_joined_frame = tf.stack([t_frame_current, t_frame_content], 0)

# Feeding the rendered frames to the Neural Network
t_input = tf.placeholder_with_default(t_joined_frame, [None, None, None, 3])
model.import_graph(t_input)

# style loss
style_layers = [sess.graph.get_tensor_by_name('import/%s:0'%s)[0] for s in googlenet_style_layers]
# L1-loss seems to be more stable for GoogleNet
# Note that we use style_decay>0 to average style-describing Gram matrices
# over the recent viewports. Please refer to StyleLoss for the details.
sl = StyleLoss(style_layers, style_decay, loss_func=mean_l1_loss)

# content loss
content_layer = sess.graph.get_tensor_by_name('import/%s:0'%googlenet_content_layer)
content_loss = mean_l1_loss(content_layer[0], content_layer[1]) * content_weight

# setup optimization
total_loss = content_loss + sl.style_loss
t_lr = tf.constant(0.05)
trainer = tf.train.AdamOptimizer(t_lr)
train_op = trainer.minimize(total_loss)

init_op = tf.global_variables_initializer()
loss_log = []

def reset(style_img, content_texture):
  del loss_log[:]
  init_op.run()
  sl.set_style({t_input: style_img[None,...]})
  content_var.load(content_texture)