def run(args):
    if args.out_dir != None:
        if not os.path.exists(args.out_dir):
            try:
                os.mkdir(args.out_dir)
            except:
                print 'cannot make directory {}'.format(args.out_dir)
                exit()
        elif not os.path.isdir(args.out_dir):
            print 'file path {} exists but is not directory'.format(args.out_dir)
            exit()
    if args.type == 'vgg19':
        vgg = VGG19()
    else:
        vgg = VGG()
    content_image = open_and_resize_image(args.content, args.width, vgg)
    print 'loading content image completed'
    style_image = open_and_resize_image(args.style, args.width, vgg)
    if args.match_color_histogram:
        style_image = util.match_color_histogram(style_image, content_image)
    if args.luminance_only:
        content_image, content_iq = util.split_bgr_to_yiq(content_image)
        style_image, style_iq = util.split_bgr_to_yiq(style_image)
        content_mean = np.mean(content_image, axis=(1,2,3), keepdims=True)
        content_std = np.std(content_image, axis=(1,2,3), keepdims=True)
        style_mean = np.mean(style_image, axis=(1,2,3), keepdims=True)
        style_std = np.std(style_image, axis=(1,2,3), keepdims=True)
        style_image = (style_image - style_mean) / style_std * content_std + content_mean
    print 'loading style image completed'
    serializers.load_hdf5(args.model, vgg)
    print 'loading neural network model completed'
    optimizer = LBFGS(args.lr)
    content_layers = args.content_layers.split(',')
    style_layers = args.style_layers.split(',')

    def on_epoch_done(epoch, x, losses):
        if (epoch + 1) % args.save_iter == 0:
            image = cuda.to_cpu(x.data)
            if args.luminance_only:
                image = util.join_yiq_to_bgr(image, content_iq)
            image = vgg.postprocess(image[0], output_type='RGB').clip(0, 255).astype(np.uint8)
            Image.fromarray(image).save(os.path.join(args.out_dir, 'out_{0:04d}.png'.format(epoch + 1)))
            print 'epoch {} done'.format(epoch + 1)
            print 'losses:'
            label_width = max(map(lambda (name, loss): len(name), losses))
            for name, loss in losses:
                print '  {0:{width}s}: {1:f}'.format(name, loss, width=label_width)

    if args.method == 'mrf':
        model = MRF(vgg, optimizer, args.content_weight, args.style_weight, args.tv_weight, content_layers, style_layers, args.resolution_num, args.gpu, initial_image=args.initial_image, keep_color=args.keep_color)
    else:
        model = NeuralStyle(vgg, optimizer, args.content_weight, args.style_weight, args.tv_weight, content_layers, style_layers, args.resolution_num, args.gpu, initial_image=args.initial_image, keep_color=args.keep_color)
    out_image = model.fit(content_image, style_image, args.iter, on_epoch_done)
    out_image = cuda.to_cpu(out_image.data)
    if args.luminance_only:
        out_image = util.join_yiq_to_bgr(out_image, content_iq)
    image = vgg.postprocess(out_image[0], output_type='RGB').clip(0, 255).astype(np.uint8)
    Image.fromarray(image).save(os.path.join(args.out_dir, 'out.png'))
Beispiel #2
0
def style_transfer():
    enc = VGG19(input_shape)
    decs = [Decoder(enc, i, name='decoder %d' % i) for i in indices]
    sty_net = StyleTransfer(enc, decs)

    X = T.tensor4('input')
    Y = T.tensor4('style')

    mon = nn.Monitor(current_folder=args.path_to_weight_files)
    for idx, layer in enumerate(indices):
        weights = mon.load('decoder-%d-final.npz' % layer)
        nn.utils.numpy2shared(weights, decs[idx].params)

    nn.set_training_off()
    X_styled = sty_net(X, Y)
    transfer = nn.function([X, Y], X_styled, name='transfer style')

    if os.path.isfile(input_path_test) and os.path.isfile(style_path_test):
        input = prep_image_test(misc.imread(input_path_test))
        style = prep_image_test(misc.imread(style_path_test))
        output = transfer(input, style)
        mon.imwrite('test %s' % input_path_test[:-4], input)
        mon.imwrite('test %s' % style_path_test[:-4], style)
        mon.imwrite('test %s %s' % (input_path_test[:-4], style_path_test[:-4]), output)
    elif os.path.isfile(input_path_test) and os.path.isdir(style_path_test):
        input = prep_image_test(misc.imread(input_path_test))
        style_files = os.listdir(style_path_test)
        for style_file in style_files:
            style = prep_image_test(misc.imread(os.path.join(style_path_test, style_file)))
            output = transfer(input, style)
            mon.imwrite('test %s' % style_file[:-4], style)
            mon.imwrite('test %s %s' % (input_path_test[:-4], style_file[:-4]), output)
        mon.imwrite('test %s' % input_path_test[:-4], input)
    elif os.path.isdir(input_path_test) and os.path.isfile(style_path_test):
        style = prep_image_test(misc.imread(style_path_test))
        input_files = os.listdir(input_path_test)
        for input_file in input_files:
            input = prep_image_test(misc.imread(os.path.join(input_path_test, input_file)))
            output = transfer(input, style)
            mon.imwrite('test %s' % input_file[:-4], input)
            mon.imwrite('test %s %s' % (input_file[:-4], style_path_test[:-4]), output)
        mon.imwrite('test %s' % style_path_test[:-4], style)
    else:
        style_files = os.listdir(style_path_test)
        input_files = os.listdir(input_path_test)
        for style_file in style_files:
            style = prep_image_test(misc.imread(os.path.join(style_path_test, style_file)))
            for input_file in input_files:
                input = prep_image_test(misc.imread(os.path.join(input_path_test, input_file)))
                output = transfer(input, style)
                mon.imwrite('test %s' % input_file[:-4], input)
                mon.imwrite('test %s %s' % (input_file[:-4], style_file[:-4]), output)
            mon.imwrite('test %s' % style_file[:-4], style)
    mon.flush()
    print('Testing finished!')
Beispiel #3
0
def train():
    enc = VGG19(input_shape)
    decs = [Decoder(enc, i, name='decoder %d' % i) for i in indices]
    sty_net = StyleTransfer(enc, decs)

    X = T.tensor4('input')
    Y = T.tensor4('style')
    idx = T.scalar('iter', 'int32')
    X_ = nn.placeholder((bs,) + input_shape[1:], name='input_plhd')
    Y_ = nn.placeholder((bs,) + input_shape[1:], name='style_plhd')
    lr_ = nn.placeholder(value=lr, name='lr_plhd')

    nn.set_training_on()
    losses = [dec.cost(X) for dec in decs]
    updates = [nn.adam(loss[0] + weight * loss[1], dec.trainable, lr) for loss, dec in zip(losses, decs)]
    nn.anneal_learning_rate(lr_, idx, 'inverse', decay=decay)
    trains = [nn.function([], [loss[0], loss[1], dec(X, True)], givens={X: X_}, updates=update, name='train decoder')
              for loss, dec, update in zip(losses, decs, updates)]

    nn.set_training_off()
    X_styled = sty_net(X, Y)
    transfer = nn.function([], X_styled, givens={X: X_, Y: Y_}, name='transfer style')

    data_train = DataManager(X_, input_path_train, bs, n_epochs, True, num_val_imgs=num_val_imgs, input_shape=input_shape)
    data_test = DataManagerStyleTransfer((X_, Y_), (input_path_val, style_path_val), bs, 1, input_shape=input_shape)
    mon = nn.Monitor(model_name='WCT', valid_freq=print_freq)

    print('Training...')
    for it in data_train:
        results = [train(it) for train in trains]

        with mon:
            for layer, res in zip(indices, results):
                if np.isnan(res[0] + res[1]) or np.isinf(res[0] + res[1]):
                    raise ValueError('Training failed!')
                mon.plot('pixel loss at layer %d' % layer, res[0])
                mon.plot('feature loss at layer %d' % layer, res[1])

            if it % val_freq == 0:
                mon.imwrite('recon img at layer %d' % layer, res[2])

                for i in data_test:
                    img = transfer()
                    mon.imwrite('stylized image %d' % i, img)
                    mon.imwrite('input %d' % i, X_.get_value())
                    mon.imwrite('style %d' % i, Y_.get_value())

                for idx, dec in zip(indices, decs):
                    mon.dump(nn.utils.shared2numpy(dec.params), 'decoder-%d.npz' % idx, 5)
    mon.flush()
    for idx, dec in zip(indices, decs):
        mon.dump(nn.utils.shared2numpy(dec.params), 'decoder-%d-final.npz' % idx)
    print('Training finished!')
Beispiel #4
0
                    break
                if a[1].data.shape != b[1].data.shape:
                    match = False
                    break
            if not match:
                print 'Ignore %s because of parameter mismatch' % child.name
                continue
            for a, b in zip(child.namedparams(), dst_child.namedparams()):
                b[1].data = a[1].data
            print 'Copy %s' % child.name


if len(sys.argv) > 1 and sys.argv[1] == 'vgg19':
    print 'load VGG19 caffemodel'
    ref = CaffeFunction('VGG_ILSVRC_19_layers.caffemodel')
    vgg = VGG19()
    print 'copy weights'
    copy_model(ref, vgg)

    print 'save "vgg19.model"'
    serializers.save_hdf5('vgg19.model', vgg)
else:
    print 'load VGG16 caffemodel'
    ref = CaffeFunction('VGG_ILSVRC_16_layers.caffemodel')
    vgg = VGG()
    print 'copy weights'
    copy_model(ref, vgg)

    print 'save "vgg16.model"'
    serializers.save_hdf5('vgg16.model', vgg)
Beispiel #5
0
def preprocess_image(image, image_size, clip_rect=None):
    if clip_rect is not None:
        image = image.crop(clip_rect)
    image = image.resize(image_size, Image.BILINEAR)
    x = np.asarray(image, dtype=np.float32)
    return VGG19.preprocess(x, input_type='RGB')
Beispiel #6
0
def train(args,
          image_path,
          source_image_paths,
          target_image_paths,
          input_clip_rect=None,
          clip_rect=None):
    iteration = args.iter
    batch_size = args.batch_size
    device_id = args.gpu
    lr = args.lr
    tv_weight = args.tv_weight
    near_image_num = args.near_image
    make_dir(os.path.split(args.output_image)[0])
    net = VGG19()
    serializers.load_npz(args.model, net)
    if device_id >= 0:
        net.to_gpu(device_id)
    xp = net.xp

    original_image = Image.open(image_path).convert('RGB')
    if input_clip_rect is not None:
        original_image = original_image.crop(input_clip_rect)
    image = preprocess_image(original_image, input_image_size)
    image_mean = np.mean(image, axis=(2, 3), keepdims=True)
    image_std = np.std(image, axis=(2, 3), keepdims=True)
    x = xp.asarray(image)
    org_layers = feature(net, x)
    org_layers = [layer.data for layer in org_layers]
    org_layer_norms = [
        xp.asarray(np.linalg.norm(cuda.to_cpu(layer), axis=1, keepdims=True))
        for layer in org_layers
    ]

    print('Calculating source feature')
    if len(source_image_paths) > near_image_num:
        source_image_paths = rank_image(net, source_image_paths,
                                        input_image_size, image,
                                        near_image_num, clip_rect)
    source_feature = mean_feature(net, source_image_paths, input_image_size,
                                  org_layers[-1], near_image_num, batch_size,
                                  clip_rect)

    print('Calculating target feature')
    if len(target_image_paths) > near_image_num:
        target_image_paths = rank_image(net, target_image_paths,
                                        input_image_size, image,
                                        near_image_num, clip_rect)
    target_feature = mean_feature(net, target_image_paths, input_image_size,
                                  org_layers[-1], near_image_num, batch_size,
                                  clip_rect)

    attribute_vectors = [
        normalized_diff(s, t) for s, t in zip(source_feature, target_feature)
    ]

    base, ext = os.path.splitext(args.output_image)
    residuals = []
    initial_x = xp.random.uniform(-10, 10, x.shape).astype(np.float32)
    print('Calculating residuals')
    link = chainer.Link(x=x.shape)
    if device_id >= 0:
        link.to_gpu(device_id)
    link.x.data[...] = initial_x
    optimizer = LBFGS(lr, stack_size=5)
    optimizer.setup(link)
    for j in six.moves.range(600):
        losses = update(net, optimizer, link, org_layers, tv_weight)
        if (j + 1) % 20 == 0:
            z = cuda.to_cpu(link.x.data)
            z = adjust_color_distribution(z, image_mean, image_std)
            residuals.append(z - image)
    for i in six.moves.range(1, 6):
        w = i * 0.1
        print('Generating image for weight: {0:.2f}'.format(w))
        link = chainer.Link(x=x.shape)
        if device_id >= 0:
            link.to_gpu(device_id)
        link.x.data[...] = initial_x
        target_layers = [
            layer + w * n * a for layer, n, a in zip(
                org_layers, org_layer_norms, attribute_vectors)
        ]
        optimizer = LBFGS(lr, stack_size=5)
        optimizer.setup(link)
        for j in six.moves.range(iteration):
            losses = update(net, optimizer, link, target_layers, tv_weight)
            if (j + 1) % 100 == 0:
                print('iter {} done loss:'.format(j + 1))
                print(losses)
            if (j + 1) % 500 == 0:
                z = cuda.to_cpu(link.x.data)
                z = adjust_color_distribution(z, image_mean, image_std)
                z -= find_nearest(residuals, z - image)
                file_name = '{0}_{1:02d}_{2:04d}{3}'.format(
                    base, i, j + 1, ext)
                postprocess_image(original_image, z - image).save(file_name)
        z = cuda.to_cpu(link.x.data)
        z = adjust_color_distribution(z, image_mean, image_std)
        z -= find_nearest(residuals, z - image)
        file_name = '{0}_{1:02d}{2}'.format(base, i, ext)
        postprocess_image(original_image, z - image).save(file_name)
        print('Completed')
Beispiel #7
0
def save_image(path, x):
    x = VGG19.postprocess(x, output_type='RGB')
    x = x.clip(0, 255).astype(np.uint8)
    Image.fromarray(x).save(path)
Beispiel #8
0
def load_image(path, image_size):
    image = Image.open(path).resize(image_size)
    x = np.asarray(image, dtype=np.float32)
    return VGG19.preprocess(x, input_type='RGB')
Beispiel #9
0
def main():
    args = parse_arg()
    iteration = args.iter
    batch_size = args.batch_size
    device_id = args.gpu
    lr = args.lr
    tv_weight = args.tv_weight
    max_image = args.max_image
    near_image_num = args.near_image
    net = VGG19()
    serializers.load_npz(args.model, net)
    if device_id >= 0:
        net.to_gpu(device_id)
    xp = net.xp

    image = load_image(args.input_image, input_image_size)
    x = xp.asarray(image)
    org_layers = feature(net, x)
    org_layers = [layer.data for layer in org_layers]

    print('Calculating source feature')
    source_image_files = list_dir_image(args.source_dir, max_image)
    if len(source_image_files) > near_image_num:
        source_image_files = rank_image(net, source_image_files,
                                        input_image_size, image,
                                        near_image_num)
    source_feature = mean_feature(net, source_image_files, input_image_size,
                                  org_layers[-1], near_image_num, batch_size)

    print('Calculating target feature')
    target_image_files = list_dir_image(args.target_dir, max_image)
    if len(target_image_files) > near_image_num:
        target_image_files = rank_image(net, target_image_files,
                                        input_image_size, image,
                                        near_image_num)
    target_feature = mean_feature(net, target_image_files, input_image_size,
                                  org_layers[-1], near_image_num, batch_size)

    attribute_vector = [
        feature_diff(s, t) for s, t in zip(source_feature, target_feature)
    ]

    base, ext = os.path.splitext(args.output_image)
    for i in six.moves.range(1, 11):
        w = i * 0.2
        print('Generating image for weight: {0:.2f}'.format(w))
        link = chainer.Link(x=x.shape)
        if device_id >= 0:
            link.to_gpu(device_id)
        link.x.data[...] = xp.random.uniform(-10, 10,
                                             x.shape).astype(np.float32)
        target_layers = [
            layer + w * a for layer, a in zip(org_layers, attribute_vector)
        ]
        optimizer = LBFGS(lr, size=5)
        optimizer.setup(link)
        for j in six.moves.range(iteration):
            losses = update(net, optimizer, link, target_layers, tv_weight)
            print(losses)
            if (j + 1) % 500 == 0:
                print('iter {} done loss:'.format(j + 1))
                save_image(
                    '{0}_{1:02d}_{2:04d}{3}'.format(base, i, j + 1, ext),
                    cuda.to_cpu(link.x.data))
        save_image('{0}_{1:02d}{2}'.format(base, i, ext),
                   cuda.to_cpu(link.x.data))
        print('Completed')
Beispiel #10
0
def preprocess_image(image, image_size):
    image = image.resize(image_size, Image.BILINEAR)
    x = np.asarray(image, dtype=np.float32)
    return VGG19.preprocess(x, input_type='RGB')