from flask import Flask, render_template, request, url_for, send_from_directory
from werkzeug. utils import secure_filename
from tensor_c_s import VGGNet, initial_result, read_img, gram_matrix
import os
from setting import vgg16_npy_pyth, content_img_path, num_steps, learning_rate, lambda_c, lambda_s, output_dir
import numpy as np
import tensorflow as tf
from PIL import Image
from flask_sqlalchemy import SQLAlchemy
import time
app= Flask( __name__)
dic= { '星月' : 'style0.jpg' ,
'国风' : 'style1.jpg' ,
'现实' : 'style2.jpg' , }
HOSTNAME= '127.0.0.1'
POST= '3306'
USERNAME= 'root'
PASSWORD= 'root'
DATABASE= 'transorfer'
DB_url= 'mysql+pymysql://{username}:{password}@{hostname}:{post}/{db}?charset=utf8' . format \
( username= USERNAME, password= PASSWORD, hostname= HOSTNAME, post= POST, db= DATABASE)
app. config[ 'SQLALCHEMY_DATABASE_URI' ] = DB_url
app. config[ 'SQLALCHEMY_TRACK_MODIFICATIONS' ] = False
db= SQLAlchemy( app)
class NEWS ( db. Model) :
__tablename__ = 'loginer'
uname = db. Column( db. Integer, primary_key= True )
pwd = db. Column( db. String( 20 ) , nullable= True )
UPLOAD_PATH = os. path. join( os. path. dirname( __file__) , 'images' )
UPLOAD_PATH1 = os. path. join( os. path. dirname( __file__) , 'result_tensor/result_01000.jpg' )
@app. route ( '/' )
def begin ( ) :
return render_template( 'login.html' )
@app. route ( '/login/' , methods= [ 'GET' , 'POST' ] )
def login ( ) :
if request. method == "GET" :
return render_template( 'login.html' )
if request. method == "POST" :
uname = request. form[ 'user' ]
pwd = request. form[ 'pwd' ]
news = NEWS. query. filter ( NEWS. uname == uname, NEWS. pwd == pwd) . all ( )
if news:
return render_template( 'upload.html' )
else :
return render_template( 'login.html' )
@app. route ( '/register/' , methods= [ 'GET' , 'POST' ] )
def register ( ) :
if request. method == "GET" :
return render_template( 'register.html' )
if request. method == "POST" :
uname = request. form[ 'uname' ]
pwd= request. form[ 'pwd' ]
word = NEWS( uname= uname, pwd= pwd)
db. session. add( word)
db. session. commit( )
return render_template( 'login.html' )
@app. route ( '/upload/' , methods= [ 'GET' , 'POST' ] )
def upload ( ) :
if request. method == 'GET' :
return render_template( 'upload.html' )
else :
name = request. form[ 'sub' ]
filedoc = request. files. get( name)
filename = secure_filename( filedoc. filename)
filedoc. save( os. path. join( UPLOAD_PATH, filename) )
if not os. path. exists( output_dir) :
os. mkdir( output_dir)
result = initial_result( ( 1 , 448 , 448 , 3 ) , 127.5 , 20 )
style_img_path = os. path. join( 'images' , dic[ name] )
content_val = read_img( content_img_path)
style_val = read_img( style_img_path)
content = tf. placeholder( tf. float32, shape= [ 1 , 448 , 448 , 3 ] )
style = tf. placeholder( tf. float32, shape= [ 1 , 448 , 448 , 3 ] )
data_dict = np. load( vgg16_npy_pyth, encoding= 'latin1' ) . item( )
vgg_for_content = VGGNet( data_dict)
vgg_for_style = VGGNet( data_dict)
vgg_for_result = VGGNet( data_dict)
vgg_for_content. build( content)
vgg_for_style. build( style)
vgg_for_result. build( result)
content_features = [
vgg_for_content. conv2_2,
vgg_for_content. conv4_2,
vgg_for_content. conv4_3,
vgg_for_content. conv5_3
]
result_content_features = [
vgg_for_result. conv2_2,
vgg_for_result. conv4_2,
vgg_for_result. conv4_3,
vgg_for_result. conv5_3
]
style_features = [
vgg_for_style. conv4_2,
vgg_for_style. conv4_3,
vgg_for_style. conv5_1,
]
style_gram = [ gram_matrix( feature) for feature in style_features]
result_style_features = [
vgg_for_result. conv4_2,
vgg_for_result. conv4_3,
vgg_for_result. conv5_1,
]
result_style_gram = [ gram_matrix( feature) for feature in result_style_features]
content_loss = tf. zeros( 1 , tf. float32)
for c, c_ in zip ( content_features, result_content_features) :
content_loss += tf. reduce_mean( ( c - c_) ** 2 , axis= [ 1 , 2 , 3 ] )
style_loss = tf. zeros( 1 , tf. float32)
for s, s_ in zip ( style_gram, result_style_gram) :
style_loss += tf. reduce_mean( ( s - s_) ** 2 , [ 1 , 2 ] )
loss = content_loss * lambda_c + style_loss * lambda_s
train_op = tf. train. AdamOptimizer( learning_rate) . minimize( loss)
init_op = tf. global_variables_initializer( )
with tf. Session( ) as sess:
sess. run( init_op)
for step in range ( num_steps) :
loss_value, content_loss_value, style_loss_value, _ = \
sess. run( [ loss, content_loss, style_loss, train_op] ,
feed_dict= {
content: content_val,
style: style_val
} )
print ( 'step: %d, loss_value: %8.4f, content_loss: %8.4f, style_loss: %8.4f' % ( step + 1 ,
loss_value[ 0 ] ,
content_loss_value[
0 ] ,
style_loss_value[ 0 ] ) )
result_img_path = os. path. join( output_dir, 'result_%05d.jpg' % ( step + 1 ) )
result_val = result. eval ( sess) [ 0 ]
result_val = np. clip( result_val, 0 , 255 )
img_arr = np. asarray( result_val, np. uint8)
img = Image. fromarray( img_arr)
img = img. resize( ( 224 , 224 ) )
img. save( result_img_path)
return render_template( 'pic.html' , val1= time. time( ) )
if __name__== '__main__' :
app. run( )
from wtforms import Form, StringField, FileField
from flask_wtf. file import FileAllowed, FileRequired
class uploadForm ( Form) :
checkFile= FileField( validators= [ FileRequired( ) , FileAllowed( [ '.jpg' , '.png' , 'gif' ] ) ] )
import os
VGG_MEAN = [ 103.939 , 116.779 , 123.68 ]
vgg16_npy_pyth = 'vgg16.npy'
content_img_path = 'images/content.jpg'
num_steps = 1000
learning_rate = 10
lambda_c = 0.8
lambda_s = 6000
output_dir = './static/result_tensor'
import os
import math
import numpy as np
import tensorflow as tf
from PIL import Image
import time
import setting
class VGGNet ( ) :
'''
创建 vgg16 网络 结构
从模型中载入参数
'''
def __init__ ( self, data_dict) :
'''
传入vgg16模型
:param data_dict: vgg16.npy (字典类型)
'''
self. data_dict = data_dict
def get_conv_filter ( self, name) :
'''
得到对应名称的卷积层
:param name: 卷积层名称
:return: 该卷积层输出
'''
return tf. constant( self. data_dict[ name] [ 0 ] , name= 'conv' )
def get_fc_weight ( self, name) :
'''
获得名字为name的全连接层权重
:param name: 连接层名称
:return: 该层权重
'''
return tf. constant( self. data_dict[ name] [ 0 ] , name= 'fc' )
def get_bias ( self, name) :
'''
获得名字为name的全连接层偏置
:param name: 连接层名称
:return: 该层偏置
'''
return tf. constant( self. data_dict[ name] [ 1 ] , name= 'bias' )
def conv_layer ( self, x, name) :
'''
创建一个卷积层
:param x:
:param name:
:return:
'''
with tf. name_scope( name) :
conv_w = self. get_conv_filter( name)
conv_b = self. get_bias( name)
h = tf. nn. conv2d( x, conv_w, strides= [ 1 , 1 , 1 , 1 ] , padding= 'SAME' )
'''
因为此刻的 w 和 b 是从外部传递进来,所以使用 tf.nn.conv2d()
tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu = None, name = None) 参数说明:
input 输入的tensor, 格式[batch, height, width, channel]
filter 卷积核 [filter_height, filter_width, in_channels, out_channels]
分别是:卷积核高,卷积核宽,输入通道数,输出通道数
strides 步长 卷积时在图像每一维度的步长,长度为4
padding 参数可选择 “SAME” “VALID”
'''
h = tf. nn. bias_add( h, conv_b)
h = tf. nn. relu( h)
return h
def pooling_layer ( self, x, name) :
'''
创建池化层
:param x: 输入的tensor
:param name: 池化层名称
:return: tensor
'''
return tf. nn. max_pool( x,
ksize= [ 1 , 2 , 2 , 1 ] ,
strides= [ 1 , 2 , 2 , 1 ] ,
padding= 'SAME' ,
name= name
)
def fc_layer ( self, x, name, activation= tf. nn. relu) :
'''
创建全连接层
:param x: 输入tensor
:param name: 全连接层名称
:param activation: 激活函数名称
:return: 输出tensor
'''
with tf. name_scope( name, activation) :
fc_w = self. get_fc_weight( name)
fc_b = self. get_bias( name)
h = tf. matmul( x, fc_w)
h = tf. nn. bias_add( h, fc_b)
if activation is None :
return h
else :
return activation( h)
def flatten_layer ( self, x, name) :
'''
展平
'''
with tf. name_scope( name) :
x_shape = x. get_shape( ) . as_list( )
dim = 1
for d in x_shape[ 1 : ] :
dim *= d
x = tf. reshape( x, [ - 1 , dim] )
return x
def build ( self, x_rgb) :
'''
创建vgg16 网络
:param x_rgb: [1, 224, 224, 3]
:return:
'''
start_time = time. time( )
print ( '模型开始创建……' )
r, g, b = tf. split( x_rgb, [ 1 , 1 , 1 ] , axis= 3 )
'''
tf.split(value, num_or_size_split, axis=0)用法:
value:输入的Tensor
num_or_size_split:有两种用法:
1.直接传入一个整数,代表会被切成几个张量,切割的维度有axis指定
2.传入一个向量,向量长度就是被切的份数。传入向量的好处在于,可以指定每一份有多少元素
axis, 指定从哪一个维度切割
因此,上一句的意思就是从第4维切分,分为3份,每一份只有1个元素
'''
x_bgr = tf. concat( [ b - setting. VGG_MEAN[ 0 ] , g - setting. VGG_MEAN[ 1 ] , r - setting. VGG_MEAN[ 2 ] ] , axis= 3 )
self. conv1_1 = self. conv_layer( x_bgr, 'conv1_1' )
self. conv1_2 = self. conv_layer( self. conv1_1, 'conv1_2' )
self. pool1 = self. pooling_layer( self. conv1_2, 'pool1' )
self. conv2_1 = self. conv_layer( self. pool1, 'conv2_1' )
self. conv2_2 = self. conv_layer( self. conv2_1, 'conv2_2' )
self. pool2 = self. pooling_layer( self. conv2_2, 'pool2' )
self. conv3_1 = self. conv_layer( self. pool2, 'conv3_1' )
self. conv3_2 = self. conv_layer( self. conv3_1, 'conv3_2' )
self. conv3_3 = self. conv_layer( self. conv3_2, 'conv3_3' )
self. pool3 = self. pooling_layer( self. conv3_3, 'pool3' )
self. conv4_1 = self. conv_layer( self. pool3, 'conv4_1' )
self. conv4_2 = self. conv_layer( self. conv4_1, 'conv4_2' )
self. conv4_3 = self. conv_layer( self. conv4_2, 'conv4_3' )
self. pool4 = self. pooling_layer( self. conv4_3, 'pool4' )
self. conv5_1 = self. conv_layer( self. pool4, 'conv5_1' )
self. conv5_2 = self. conv_layer( self. conv5_1, 'conv5_2' )
self. conv5_3 = self. conv_layer( self. conv5_2, 'conv5_3' )
self. pool5 = self. pooling_layer( self. conv5_3, 'pool5' )
''' 因为风格转换只需要 卷积层 的数据
self.flatten5 = self.flatten_layer(self.pool5, 'flatten')
self.fc6 = self.fc_layer(self.flatten5, 'fc6')
self.fc7 = self.fc_layer(self.fc6, 'fc7')
self.fc8 = self.fc_layer(self.fc7, 'fc8', activation = None)
self.prob = tf.nn.softmax(self.fc8, name = 'prob')
'''
print ( '创建模型结束:%4ds' % ( time. time( ) - start_time) )
def initial_result ( shape, mean, stddev) :
initial = tf. truncated_normal( shape, mean= mean, stddev= stddev)
'''
tf.truncated_normal(shape, mean, stddev) 生成截断的生态分布函数
如果产生的正态分布值和均值差值大于二倍的标准差,那就重新生成。
'''
return tf. Variable( initial)
def read_img ( img_name) :
'''
读取图片
'''
img = Image. open ( img_name)
img= img. resize( ( 448 , 448 ) )
np_img = np. array( img)
np_img = np. asarray( [ np_img] , dtype= np. int32)
return np_img
def gram_matrix ( x) :
'''
计算 gram 矩阵
:param x: 特征图,shape:[1, width, height, channel]
:return:
'''
b, w, h, ch = x. get_shape( ) . as_list( )
features = tf. reshape( x, [ b, h * w, ch] )
gram = tf. matmul( features, features, adjoint_a= True ) / tf. constant( ch * w * h, tf. float32)
return gram
<! DOCTYPE html >
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< title> 登录</ title>
< style>
body {
background-image : url ( "{{ url_for('static',filename='img/1.jpg' )}}" ) ;
margin : 0;
padding : 0;
background-image : url ( "{{ url_for('static',filename='img/1.jpg') }}" ) ;
background-repeat : no-repeat;
background-size : 100%, 100%;
}
.login_form {
position : absolute;
width : 300px;
height : 200px;
background-color : aliceblue;
left : 1000px;
top : 120px;
opacity : 0.8;
}
form {
margin : 30px;
}
</ style>
</ head>
< body>
< div class = " login_form" >
< form action = " /login/" method = " post" >
< table>
< tr>
< td> 账号:</ td>
< td> < input type = " text " name = " user" > </ td>
</ tr>
< tr>
< td> 密码:</ td>
< td> < input type = " password" name = " pwd" > </ td>
</ tr>
< tr style = " text-align : center" >
< td> < input type = " submit" > </ td>
< td> < a href = " {{ url_for('register') }}" > < input type = " button" value = " 注册" > </ a> </ td>
</ tr>
</ table>
</ form>
</ div>
</ body>
</ html>
<! DOCTYPE html >
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< title> 注册</ title>
< style>
body {
background-image : url ( "{{ url_for('static',filename='img/6.jpg' )}}" ) ;
background-repeat : no-repeat;
background-size : 100%, 100%;
}
.zhuce {
position : absolute;
width : 370px;
height : 450px;
background-color : aliceblue;
left : 1000px;
top : 120px;
opacity : 0.8;
}
</ style>
</ head>
< body onload = " YZM ( ) " >
< div class = " zhuce" >
< form action = " /register/" method = " post" >
< table>
< tr>
< td> 账号:</ td>
< td> < input type = " text" name = " uname" id = " uname" alt = " 账号" onblur = " checkname ( ) " >
< span id = " uname_span" > </ span>
</ td>
</ tr>
< tr>
< td> 密码:</ td>
< td> < input type = " password" name = " pwd" id = " pwd" alt = " 密码" onblur = " checkpwd ( ) " >
< span id = " pwd_span" > </ span>
</ td>
</ tr>
< tr>
< td> 性别:</ td>
< td> 男:< input type = " radio" name = " sex" id = " sex" value = " 1" >
女:< input type = " radio" name = " sex" id = " sex" value = " 0" >
< span id = " sex_span" > </ span>
</ td>
</ tr>
< tr>
< td> 爱好:</ td>
< td>
< input type = " checkbox" name = " fav" id = " fav" value = " 1" > 篮球
< input type = " checkbox" name = " fav" id = " fav" value = " 2" > 足球
< input type = " checkbox" name = " fav" id = " fav" value = " 3" > 排球
< br>
< input type = " checkbox" name = " fav" id = " fav" value = " 4" > 吉他
< input type = " checkbox" name = " fav" id = " fav" value = " 5" > 绘画
< input type = " checkbox" name = " fav" id = " fav" value = " 6" > 书法
</ td>
</ tr>
< tr>
< td> 籍贯:</ td>
< td>
< select value = " adr" name = " adr" >
< option value = " 0" > --请选择--</ option>
< option value = " 1" > 北京</ option>
< option value = " 2" > 上海</ option>
< option value = " 3" > 广州</ option>
< option value = " 4" > 深圳</ option>
</ select>
</ td>
</ tr>
< tr>
< td> 验证码:</ td>
< td> < input type = " number" name = " yzm" id = " yzm" >
< span id = " yzm_span" > </ span>
</ td>
</ tr>
< tr>
< td> 个人介绍:</ td>
< td> < textarea rows = " 8" cols = " 30" name = " intext" >
</ textarea> </ td>
</ tr>
< tr>
< td align = " center" colspan = " 2" >
< input type = " checkbox" name = " " id = " check" value = " " > 是否与本公司达成一致
</ td>
</ tr>
< tr>
< td align = " center" colspan = " 2" >
< input type = " submit" value = " 提交" >
</ td>
</ tr>
</ table>
</ form>
</ div>
</ body>
< script>
function YZM ( ) {
var num= Math. floor ( Math. random ( ) * 9000 + 1000 ) ;
var span= document. getElementById ( "yzm_span" ) ;
span. innerText= num;
span. style. backgroundColor= "greenyellow" ;
}
function check ( id, reg ) {
var name= document. getElementById ( id) ;
var val= name. value;
var alt= name. alt;
var span= document. getElementById ( id+ "_span" ) ;
if ( val== " " || val== null ) {
span. innerText= "×" + alt+ "不能为空" ;
span. style. color= "red" ;
}
else if ( reg. test ( val) ) {
span. innerText= "√" + alt+ "正确" ;
span. style. color= "green" ;
}
else {
span. innerText= "×" + alt+ "不合法" ;
span. style. color= "red" ;
}
}
function checkname ( ) {
var reg= / ^[1-9]{3,}$ / ;
check ( "uname" , reg) ;
}
function checkpwd ( ) {
var reg= / ^[a-z]{3,4}$ / ;
check ( "pwd" , reg) ;
}
</ script>
</ html>
<! DOCTYPE html >
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< title> Title</ title>
< style>
.look {
background-color : white;
position : absolute;
top : 70px;
left : 500px;
width : 500px;
height : 600px;
box-shadow : 10px 0px 15px 5px;
}
img {
width : 300px;
height : 300px;
margin : 100px;
}
</ style>
</ head>
< body>
< div class = " look" >
< img src = " {{url_for('static',filename='result_tensor/result_01000.jpg',_t=val1)}}" >
</ div>
</ body>
</ html>
<! DOCTYPE html >
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< title> Title</ title>
< style>
.one_style {
background-color : aqua;
position : absolute;
top : 70px;
left : 100px;
width : 350px;
height : 500px;
}
.two_style {
background-color : aqua;
position : absolute;
top : 70px;
left : 550px;
width : 350px;
height : 500px;
}
.three_style {
background-color : aqua;
position : absolute;
top : 70px;
left : 1000px;
width : 350px;
height : 500px;
}
img {
width : 300px;
height : 300px;
margin : 23px;
}
</ style>
</ head>
< body>
< div class = " one_style" >
< img src = " {{url_for('static',filename='img/style0.jpg')}}" >
< form action = " /upload/" method = " post" enctype = " multipart/form-data" >
< table>
< tr>
< td> < input type = " file" name = " style0.jpg" > </ td>
< td> < input type = " submit" value = " style0.jpg" name = " sub" > </ td>
</ tr>
</ table>
</ form>
</ div>
< div class = " two_style" >
< img src = " {{url_for('static',filename='img/style1.jpg ') }}" >
< form action = " /upload/" method = " post" enctype = " multipart/form-data" >
< table>
< tr>
< td> < input type = " file" name = " style1.jpg" > </ td>
< td> < input type = " submit" value = " style1.jpg" name = " sub" > </ td>
</ tr>
</ table>
</ div>
< div class = " three_style" >
< img src = " {{url_for('static',filename='img/style2.jpg ') }}" >
< form action = " /upload/" method = " post" enctype = " multipart/form-data" >
< table>
< tr>
< td> < input type = " file" name = " style2.jpg" > </ td>
< td> < input type = " submit" value = " style2.jpg" name = " sub" > </ td>
</ tr>
</ table>
</ div>
</ body>
</ html>
<! DOCTYPE html >
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< title> 主界面</ title>
< style>
.one_style {
background-color : white;
position : absolute;
top : 70px;
left : 100px;
width : 350px;
height : 500px;
box-shadow : 2px 0px 4px 2px;
}
.two_style {
background-color : white;
position : absolute;
top : 70px;
left : 550px;
width : 350px;
height : 500px;
box-shadow : 2px 0px 4px 2px;
}
.three_style {
background-color : white;
position : absolute;
top : 70px;
left : 1000px;
width : 350px;
height : 500px;
box-shadow : 2px 0px 4px 2px;
}
img {
width : 300px;
height : 300px;
margin : 23px;
}
</ style>
</ head>
< body>
< div class = " one_style" >
< img src = " {{url_for('static',filename='img/style0.jpg')}}" >
< form action = " /upload/" method = " post" enctype = " multipart/form-data" >
< table>
< tr>
< td> < input type = " file" name = " 星月" > </ td>
< td> < input type = " submit" value = " 星月" name = " sub" > </ td>
</ tr>
</ table>
</ form>
</ div>
< div class = " two_style" >
< img src = " {{url_for('static',filename='img/style1.jpg ') }}" >
< form action = " /upload/" method = " post" enctype = " multipart/form-data" >
< table>
< tr>
< td> < input type = " file" name = " 国风" > </ td>
< td> < input type = " submit" value = " 国风" name = " sub" > </ td>
</ tr>
</ table>
</ div>
< div class = " three_style" >
< img src = " {{url_for('static',filename='img/style2.jpg ') }}" >
< form action = " /upload/" method = " post" enctype = " multipart/form-data" >
< table>
< tr>
< td> < input type = " file" name = " 现实" > </ td>
< td> < input type = " submit" value = " 现实" name = " sub" > </ td>
</ tr>
</ table>
</ div>
</ body>
</ html>