目录

前言

项目说明

项目结构

数据准备

魔改代码

总结


前言

根据我的另一篇文章:如何将照片美化,DPED机器学习开源项目安装使用 | 机器学习_阿良的博客-CSDN博客

发现DPED项目需要命令化执行且需要图片目录作为处理源。我还是把项目魔改了一下,简化项目结构,合并到一个python代码中。

模型文件比较大,我提供了下载地址,下载后放到项目对应目录即可。

Github仓库地址:github地址

项目说明

项目结构

看一下项目的结构,如下图:

其中模型文件下载地址:https://pan.baidu.com/s/1IUm8xz5dhh8iW_bLWfihPQ 提取码:TUAN

将imagenet-vgg-verydeep-19.mat下载后放在vgg_pretrained目录中。

环境依赖可以直接参考:Python实现替换照片人物背景,精细到头发丝(附上代码) | 机器学习_阿良的博客-CSDN博客

数据准备

我准备了一张测试图如下:

魔改代码

不废话了,上核心代码。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2021/11/27 13:48
# @Author  : 剑客阿良_ALiang
# @Site    :
# @File    : dped.py# python test_model.py model=iphone_orig dped_dir=dped/ test_subset=full
# iteration=all resolution=orig use_gpu=trueimport imageio
from PIL import Image
import numpy as np
import tensorflow as tf
import os
import sys
import scipy.stats as st
import uuid
from functools import reduce# ---------------------- hy add 2 ----------------------
def log10(x):numerator = tf.compat.v1.log(x)denominator = tf.compat.v1.log(tf.constant(10, dtype=numerator.dtype))return numerator / denominatordef _tensor_size(tensor):from operator import mulreturn reduce(mul, (d.value for d in tensor.get_shape()[1:]), 1)def gauss_kernel(kernlen=21, nsig=3, channels=1):interval = (2 * nsig + 1.) / (kernlen)x = np.linspace(-nsig - interval / 2., nsig + interval / 2., kernlen + 1)kern1d = np.diff(st.norm.cdf(x))kernel_raw = np.sqrt(np.outer(kern1d, kern1d))kernel = kernel_raw / kernel_raw.sum()out_filter = np.array(kernel, dtype=np.float32)out_filter = out_filter.reshape((kernlen, kernlen, 1, 1))out_filter = np.repeat(out_filter, channels, axis=2)return out_filterdef blur(x):kernel_var = gauss_kernel(21, 3, 3)return tf.nn.depthwise_conv2d(x, kernel_var, [1, 1, 1, 1], padding='SAME')def process_command_args(arguments):# specifying default parametersbatch_size = 50train_size = 30000learning_rate = 5e-4num_train_iters = 20000w_content = 10w_color = 0.5w_texture = 1w_tv = 2000dped_dir = 'dped/'vgg_dir = 'vgg_pretrained/imagenet-vgg-verydeep-19.mat'eval_step = 1000phone = ""for args in arguments:if args.startswith("model"):phone = args.split("=")[1]if args.startswith("batch_size"):batch_size = int(args.split("=")[1])if args.startswith("train_size"):train_size = int(args.split("=")[1])if args.startswith("learning_rate"):learning_rate = float(args.split("=")[1])if args.startswith("num_train_iters"):num_train_iters = int(args.split("=")[1])# -----------------------------------if args.startswith("w_content"):w_content = float(args.split("=")[1])if args.startswith("w_color"):w_color = float(args.split("=")[1])if args.startswith("w_texture"):w_texture = float(args.split("=")[1])if args.startswith("w_tv"):w_tv = float(args.split("=")[1])# -----------------------------------if args.startswith("dped_dir"):dped_dir = args.split("=")[1]if args.startswith("vgg_dir"):vgg_dir = args.split("=")[1]if args.startswith("eval_step"):eval_step = int(args.split("=")[1])if phone == "":print("\nPlease specify the camera model by running the script with the following parameter:\n")print("python train_model.py model={iphone,blackberry,sony}\n")sys.exit()if phone not in ["iphone", "sony", "blackberry"]:print("\nPlease specify the correct camera model:\n")print("python train_model.py model={iphone,blackberry,sony}\n")sys.exit()print("\nThe following parameters will be applied for CNN training:\n")print("Phone model:", phone)print("Batch size:", batch_size)print("Learning rate:", learning_rate)print("Training iterations:", str(num_train_iters))print()print("Content loss:", w_content)print("Color loss:", w_color)print("Texture loss:", w_texture)print("Total variation loss:", str(w_tv))print()print("Path to DPED dataset:", dped_dir)print("Path to VGG-19 network:", vgg_dir)print("Evaluation step:", str(eval_step))print()return phone, batch_size, train_size, learning_rate, num_train_iters, \w_content, w_color, w_texture, w_tv, \dped_dir, vgg_dir, eval_stepdef process_test_model_args(arguments):phone = ""dped_dir = 'dped/'test_subset = "small"iteration = "all"resolution = "orig"use_gpu = "true"for args in arguments:if args.startswith("model"):phone = args.split("=")[1]if args.startswith("dped_dir"):dped_dir = args.split("=")[1]if args.startswith("test_subset"):test_subset = args.split("=")[1]if args.startswith("iteration"):iteration = args.split("=")[1]if args.startswith("resolution"):resolution = args.split("=")[1]if args.startswith("use_gpu"):use_gpu = args.split("=")[1]if phone == "":print("\nPlease specify the model by running the script with the following parameter:\n")print("python test_model.py model={iphone,blackberry,sony,iphone_orig,blackberry_orig,sony_orig}\n")sys.exit()return phone, dped_dir, test_subset, iteration, resolution, use_gpudef get_resolutions():# IMAGE_HEIGHT, IMAGE_WIDTHres_sizes = {}res_sizes["iphone"] = [1536, 2048]res_sizes["iphone_orig"] = [1536, 2048]res_sizes["blackberry"] = [1560, 2080]res_sizes["blackberry_orig"] = [1560, 2080]res_sizes["sony"] = [1944, 2592]res_sizes["sony_orig"] = [1944, 2592]res_sizes["high"] = [1260, 1680]res_sizes["medium"] = [1024, 1366]res_sizes["small"] = [768, 1024]res_sizes["tiny"] = [600, 800]return res_sizesdef get_specified_res(res_sizes, phone, resolution):if resolution == "orig":IMAGE_HEIGHT = res_sizes[phone][0]IMAGE_WIDTH = res_sizes[phone][1]else:IMAGE_HEIGHT = res_sizes[resolution][0]IMAGE_WIDTH = res_sizes[resolution][1]IMAGE_SIZE = IMAGE_WIDTH * IMAGE_HEIGHT * 3return IMAGE_HEIGHT, IMAGE_WIDTH, IMAGE_SIZEdef extract_crop(image, resolution, phone, res_sizes):if resolution == "orig":return imageelse:x_up = int((res_sizes[phone][1] - res_sizes[resolution][1]) / 2)y_up = int((res_sizes[phone][0] - res_sizes[resolution][0]) / 2)x_down = x_up + res_sizes[resolution][1]y_down = y_up + res_sizes[resolution][0]return image[y_up: y_down, x_up: x_down, :]# ---------------------- hy add 1 ----------------------
def resnet(input_image):with tf.compat.v1.variable_scope("generator"):W1 = weight_variable([9, 9, 3, 64], name="W1")b1 = bias_variable([64], name="b1")c1 = tf.nn.relu(conv2d(input_image, W1) + b1)# residual 1W2 = weight_variable([3, 3, 64, 64], name="W2")b2 = bias_variable([64], name="b2")c2 = tf.nn.relu(_instance_norm(conv2d(c1, W2) + b2))W3 = weight_variable([3, 3, 64, 64], name="W3")b3 = bias_variable([64], name="b3")c3 = tf.nn.relu(_instance_norm(conv2d(c2, W3) + b3)) + c1# residual 2W4 = weight_variable([3, 3, 64, 64], name="W4")b4 = bias_variable([64], name="b4")c4 = tf.nn.relu(_instance_norm(conv2d(c3, W4) + b4))W5 = weight_variable([3, 3, 64, 64], name="W5")b5 = bias_variable([64], name="b5")c5 = tf.nn.relu(_instance_norm(conv2d(c4, W5) + b5)) + c3# residual 3W6 = weight_variable([3, 3, 64, 64], name="W6")b6 = bias_variable([64], name="b6")c6 = tf.nn.relu(_instance_norm(conv2d(c5, W6) + b6))W7 = weight_variable([3, 3, 64, 64], name="W7")b7 = bias_variable([64], name="b7")c7 = tf.nn.relu(_instance_norm(conv2d(c6, W7) + b7)) + c5# residual 4W8 = weight_variable([3, 3, 64, 64], name="W8")b8 = bias_variable([64], name="b8")c8 = tf.nn.relu(_instance_norm(conv2d(c7, W8) + b8))W9 = weight_variable([3, 3, 64, 64], name="W9")b9 = bias_variable([64], name="b9")c9 = tf.nn.relu(_instance_norm(conv2d(c8, W9) + b9)) + c7# ConvolutionalW10 = weight_variable([3, 3, 64, 64], name="W10")b10 = bias_variable([64], name="b10")c10 = tf.nn.relu(conv2d(c9, W10) + b10)W11 = weight_variable([3, 3, 64, 64], name="W11")b11 = bias_variable([64], name="b11")c11 = tf.nn.relu(conv2d(c10, W11) + b11)# FinalW12 = weight_variable([9, 9, 64, 3], name="W12")b12 = bias_variable([3], name="b12")enhanced = tf.nn.tanh(conv2d(c11, W12) + b12) * 0.58 + 0.5return enhanceddef adversarial(image_):with tf.compat.v1.variable_scope("discriminator"):conv1 = _conv_layer(image_, 48, 11, 4, batch_nn=False)conv2 = _conv_layer(conv1, 128, 5, 2)conv3 = _conv_layer(conv2, 192, 3, 1)conv4 = _conv_layer(conv3, 192, 3, 1)conv5 = _conv_layer(conv4, 128, 3, 2)flat_size = 128 * 7 * 7conv5_flat = tf.reshape(conv5, [-1, flat_size])W_fc = tf.Variable(tf.compat.v1.truncated_normal([flat_size, 1024], stddev=0.01))bias_fc = tf.Variable(tf.constant(0.01, shape=[1024]))fc = leaky_relu(tf.matmul(conv5_flat, W_fc) + bias_fc)W_out = tf.Variable(tf.compat.v1.truncated_normal([1024, 2], stddev=0.01))bias_out = tf.Variable(tf.constant(0.01, shape=[2]))adv_out = tf.nn.softmax(tf.matmul(fc, W_out) + bias_out)return adv_outdef weight_variable(shape, name):initial = tf.compat.v1.truncated_normal(shape, stddev=0.01)return tf.Variable(initial, name=name)def bias_variable(shape, name):initial = tf.constant(0.01, shape=shape)return tf.Variable(initial, name=name)def conv2d(x, W):return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')def leaky_relu(x, alpha=0.2):return tf.maximum(alpha * x, x)def _conv_layer(net, num_filters, filter_size, strides, batch_nn=True):weights_init = _conv_init_vars(net, num_filters, filter_size)strides_shape = [1, strides, strides, 1]bias = tf.Variable(tf.constant(0.01, shape=[num_filters]))net = tf.nn.conv2d(net, weights_init, strides_shape, padding='SAME') + biasnet = leaky_relu(net)if batch_nn:net = _instance_norm(net)return netdef _instance_norm(net):batch, rows, cols, channels = [i.value for i in net.get_shape()]var_shape = [channels]mu, sigma_sq = tf.compat.v1.nn.moments(net, [1, 2], keepdims=True)shift = tf.Variable(tf.zeros(var_shape))scale = tf.Variable(tf.ones(var_shape))epsilon = 1e-3normalized = (net - mu) / (sigma_sq + epsilon) ** (.5)return scale * normalized + shiftdef _conv_init_vars(net, out_channels, filter_size, transpose=False):_, rows, cols, in_channels = [i.value for i in net.get_shape()]if not transpose:weights_shape = [filter_size, filter_size, in_channels, out_channels]else:weights_shape = [filter_size, filter_size, out_channels, in_channels]weights_init = tf.Variable(tf.compat.v1.truncated_normal(weights_shape,stddev=0.01,seed=1),dtype=tf.float32)return weights_init# ---------------------- hy add 0 ----------------------def beautify(pic_path: str, output_dir: str, gpu='1'):tf.compat.v1.disable_v2_behavior()# process command argumentsphone = "iphone_orig"test_subset = "full"iteration = "all"resolution = "orig"# get all available image resolutionsres_sizes = get_resolutions()# get the specified image resolutionIMAGE_HEIGHT, IMAGE_WIDTH, IMAGE_SIZE = get_specified_res(res_sizes, phone, resolution)if gpu == '1':use_gpu = 'true'else:use_gpu = 'false'# disable gpu if specifiedconfig = tf.compat.v1.ConfigProto(device_count={'GPU': 0}) if use_gpu == "false" else None# create placeholders for input imagesx_ = tf.compat.v1.placeholder(tf.float32, [None, IMAGE_SIZE])x_image = tf.reshape(x_, [-1, IMAGE_HEIGHT, IMAGE_WIDTH, 3])# generate enhanced imageenhanced = resnet(x_image)with tf.compat.v1.Session(config=config) as sess:# test_dir = dped_dir + phone.replace("_orig",#                                     "") + "/test_data/full_size_test_images/"# test_photos = [f for f in os.listdir(#     test_dir) if os.path.isfile(test_dir + f)]test_photos = [pic_path]if test_subset == "small":# use five first images onlytest_photos = test_photos[0:5]if phone.endswith("_orig"):# load pre-trained modelsaver = tf.compat.v1.train.Saver()saver.restore(sess, "models_orig/" + phone)for photo in test_photos:# load training image and crop it if necessarynew_pic_name = uuid.uuid4()print("Testing original " +phone.replace("_orig","") +" model, processing image " +photo)image = np.float16(np.array(Image.fromarray(imageio.imread(photo)).resize([res_sizes[phone][1], res_sizes[phone][0]]))) / 255image_crop = extract_crop(image, resolution, phone, res_sizes)image_crop_2d = np.reshape(image_crop, [1, IMAGE_SIZE])# get enhanced imageenhanced_2d = sess.run(enhanced, feed_dict={x_: image_crop_2d})enhanced_image = np.reshape(enhanced_2d, [IMAGE_HEIGHT, IMAGE_WIDTH, 3])before_after = np.hstack((image_crop, enhanced_image))photo_name = photo.rsplit(".", 1)[0]# save the results as .png images# imageio.imwrite(#     "visual_results/" +#     phone +#     "_" +#     photo_name +#     "_enhanced.png",#     enhanced_image)imageio.imwrite(os.path.join(output_dir, '{}.png'.format(new_pic_name)), enhanced_image)# imageio.imwrite(#     "visual_results/" +#     phone +#     "_" +#     photo_name +#     "_before_after.png",#     before_after)imageio.imwrite(os.path.join(output_dir, '{}_before_after.png'.format(new_pic_name)), before_after)return os.path.join(output_dir, '{}.png'.format(new_pic_name))else:num_saved_models = int(len([f for f in os.listdir("models_orig/") if f.startswith(phone + "_iteration")]) / 2)if iteration == "all":iteration = np.arange(1, num_saved_models) * 1000else:iteration = [int(iteration)]for i in iteration:# load pre-trained modelsaver = tf.compat.v1.train.Saver()saver.restore(sess,"models_orig/" +phone +"_iteration_" +str(i) +".ckpt")for photo in test_photos:# load training image and crop it if necessarynew_pic_name = uuid.uuid4()print("iteration " + str(i) + ", processing image " + photo)image = np.float16(np.array(Image.fromarray(imageio.imread(photo)).resize([res_sizes[phone][1], res_sizes[phone][0]]))) / 255image_crop = extract_crop(image, resolution, phone, res_sizes)image_crop_2d = np.reshape(image_crop, [1, IMAGE_SIZE])# get enhanced imageenhanced_2d = sess.run(enhanced, feed_dict={x_: image_crop_2d})enhanced_image = np.reshape(enhanced_2d, [IMAGE_HEIGHT, IMAGE_WIDTH, 3])before_after = np.hstack((image_crop, enhanced_image))photo_name = photo.rsplit(".", 1)[0]# save the results as .png images# imageio.imwrite(#     "visual_results/" +#     phone +#     "_" +#     photo_name +#     "_iteration_" +#     str(i) +#     "_enhanced.png",#     enhanced_image)imageio.imwrite(os.path.join(output_dir, '{}.png'.format(new_pic_name)), enhanced_image)# imageio.imwrite(#     "visual_results/" +#     phone +#     "_" +#     photo_name +#     "_iteration_" +#     str(i) +#     "_before_after.png",#     before_after)imageio.imwrite(os.path.join(output_dir, '{}_before_after.png'.format(new_pic_name)), before_after)return os.path.join(output_dir, '{}.png'.format(new_pic_name))if __name__ == '__main__':print(beautify('C:/Users/yi/Desktop/6.jpg', 'result/'))

代码说明

1、beautify方法有3个参数,分别为图片地址、输出目录、是否使用gpu(默认使用)。

2、输出的图片有两张,为了文件名不重复,使用uuid作为文件名,后缀带_before_after为对比图。

3、没有对文件做校验,如果需要可以自行添加。

验证一下效果

怎么样?很炫吧。

总结

研究这个项目还是很有意思的,记录与分享又是另一种快乐。以前以为自己是个开朗的人,现在细细翻阅自己的人生,更多的是宁静与孤独。以前曾看书看马尔克斯的一句话:在变老的路上,与其抗拒孤独,不如学会享受孤独。所以孤独没什么不好的,沉浸在程序的另一个世界里,就是另一个心情。

分享:

生命从来不曾离开过孤独而独立存在。无论是我们出生、我们成长、我们相爱还是我们成功失败,直到最后的最后,孤独犹如影子一样存在于生命一隅。——《马尔克斯》

如果本文对你有用的话,请点个赞吧,谢谢!

Python实现图片美化,醉后不知天在水?(附上代码) | 机器学习相关推荐

  1. Contelec KL750-5K0/M-SE醉后不知天在水

    醉后不知天在水,满船清梦压星河 我终于又回到西溪,躺在茭芦田庄的床上,看着窗外庭院里熟悉的风景,还有枝丫上的初春. 一切都是那么美好,走在西溪的路上,吹面而来的风雨.就连空气都是温柔的. 西溪之于我, ...

  2. python做图片美化_python图片美化

    广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! 功能性是开发的第一要务每一个 python 图形界面库都有它自有的功能特性和界面 ...

  3. python做图片美化_Python实现简单的照片磨皮(照片智能磨皮) 最新免费版

    Python实现简单的照片磨皮(照片智能磨皮)是一款用python写的最好的照片磨皮软件.需要配置opencv和numpy,使用的时候地址需要加英文的引号,斜杠要用双斜杠,例如"D:\\a. ...

  4. python做图片美化_如何美化MATLAB和Python画出来的图

    如何美化MATLAB和Python画出来的图 写在前面 俗话有句叫做:字不如表,表不如图,意思就是图可以最直观最显然的表达我们想要表达的信息,其升降趋势一目了然:表其次,能够看到数值,但是想要看出变化 ...

  5. python做图片美化软件_Python大数据分析2:图形样式的美化

    图形最初显示的样式往往并非十分好看,我们可以通过大量的设置为完善图形的显示.事实上,matplotlib样式设置功能非常强大,因此在这里我们也主要结合一些最为常见的功能来做介绍. 比如我们想改变线性图 ...

  6. python获取图片坐标_python提取照片坐标信息的实例代码

    python提取照片坐标信息的代码如下所示: from PIL import Image from PIL.ExifTags import TAGS import os output="Z: ...

  7. SCU - 4572 醉后不知天在水,满船清梦压星河【思维】

    传送门 题意: 在自然数序列中 (0,1,2,3,4,5-.),求去掉所有含2,3,5,7的数字后 (0,1,4,6,8,9-)的第k个数. 思路: 这道题就很有意思啦.. 去掉后我们可以发现从小到大 ...

  8. 醉后不知天在水,满船清梦压星河。—第三十六天

  9. 醉后不知天在水 满船清梦压星河。—第二十一天

  10. 简单使用python将图片转换为字符画

    将图片转换为字符码的形式相信大家都有见过. 记得小编以前看到这些的时候是极其羡慕的,也很渴望能够实现这项功能. 然后将一副画转换为这样的字符画,发给周围的朋友炫耀. NH HN–: !;;– –;;; ...

最新文章

  1. plsql 循环存储过程返回数据集合_Java基础(十五)——Collection集合、泛型 - 寒江雨
  2. Java设计模式---外观模式
  3. Python pandas
  4. 2017.4.6AM
  5. oralce 表空间解锁
  6. php实现 求int型数据在内存中存储时1的个数(函数都可自己实现)
  7. less 函数_Python中的函数式编程教程,学会用一行代码搞定所有内容
  8. Inherits、CodeFile、CodeBehind
  9. eclipse中设置svn的commit快捷键
  10. UML之用例图(use case)箭头方向
  11. pdm vault 使用_如何使用Key Vault连接器更好地保护Logic Apps中的秘密
  12. stylish和Tampermonkey样式及脚本
  13. pytorch学习笔记(三十三):梯度下降和随机梯度下降
  14. 立即生效!英特尔 CEO 从云计算巨头 VMware 卸任
  15. Delphi 小知识汇总
  16. 朱清时——物理学步入禅境:缘起性空-(技术工作者上升到哲学思维)
  17. 博朗x乐高全球限量型趣宝盒首发
  18. 502粘到手上变硬了怎么办_急手被502胶水粘住了怎么办?
  19. 【云扩RPA】Introduction
  20. Springboot部署Nginx,配合Supervisor管理Springboot进程

热门文章

  1. Android 增量编译小解
  2. mysql delete数据怎么恢复_mysql数据delete后的数据恢复
  3. 《女士品茶》读书笔记
  4. app接口开发整理(1)
  5. 将长整型IP地址转换成点分十进制
  6. element ui的el-option需要默认
  7. ADC 前端电路的五个设计步骤(转载)
  8. cass等距离等分线段的命令键_cad等分快捷键(cad等分线段快捷键命令)
  9. Micropython加速物联网开发4 - SPI驱动5110LCD屏
  10. 双层PDF—OCR文字识别系统