您的位置:首页 > 编程语言 > Python开发

30秒教会你用Python制作520表白神器

2018-05-19 17:45 435 查看

明天就是520了,不知道各位有没有都由单身dog进化为秀恩爱dog。


在我大三的时候,就有一个计算机的朋友用自己做的代码感动了一个数学系的女生。就是下面这种。(这个爱心是有运行结果的!)也不知道为什么妹子放弃了全班30多位帅哥(没错,他们班就她一个女生),而选择了头发日渐稀疏已经“六月怀胎”的我朋友。


今天,我就来教大家一下,如何用Python做一份特别的礼物送给自己的恋人。学习资料也可以加下Python扣扣裙:四八三五四六四一六自己下载学习下


当然了,如果还是单身的,也可以把这个作为表白神器,和心爱的人表白。会Python编程的人当然不用我说,就知道该如何操作,那些不懂编程的人,如果想尝试,那该怎么办呢?这里我特地制作了小程序,微信后台私信“小程序”即可获取。运行就可以了。懂编程的就看下面的吧!送上这份礼物之后,保证你明晚.....巫山云雨后,天气晚来秋啊!


01首先教大家一个初级版的。这个就比较简单,利用Python制作一个爱心。我先把代码给贴出来:import turtleimport time# 画爱心的顶部def LittleHeart:for i in range (200):turtle.right(1)turtle.forward(2)# 输入表白的语句,默认I Love youlove=input('Please enter a sentence of love, otherwise the default is "I Love you": ')#输入署名或者赠谁,没有不执行me=input('Please enter pen name, otherwise the default do not execute: ')if love=='':love='I Love you'# 窗口大小turtle.setup(width=900, height=500)# 颜色turtle.color('red','pink')# 笔粗细turtle.pensize(3)# 速度turtle.speed(1)# 提笔turtle.up# 隐藏笔turtle.hideturtle# 去到的坐标,窗口中心为0,0turtle.goto(0,-180)turtle.showturtle# 画上线turtle.downturtle.speed(1)turtle.begin_fillturtle.left(140)turtle.forward(224)#调用画爱心左边的顶部LittleHeart#调用画爱右边的顶部turtle.left(120)LittleHeart# 画下线turtle.forward(224)turtle.end_fillturtle.pensize(5)# 在心中写字 一次turtle.goto(0,0)turtle.showturtleturtle.color('#CD5C5C','pink')#在心中写字 font可以设置字体自己电脑有的都可以设 align开始写字的位置turtle.write(love,font=('gungsuh',30,),align="center")time.sleep(2)# 在心中写字 二次# 写署名if me !='':turtle.color('black', 'pink')time.sleep(2)turtle.goto(180,-180)turtle.showturtleturtle.write(me, font=(20,), align="center", move=True)#点击窗口关闭window=turtle.Screenwindow.exitonclick这个代码最终呈现效果如下,这个是比较初级简单的爱心,没有什么高难度。你也可以把代码扩充一下,整的更加高大上一些。


如果你觉得这个还不够酷炫,那我好人做到底,帮你制作一个表白爱心树:import turtleimport randomdef love(x, y): # 在(x,y)处画爱心lalalalv = turtle.Turtlelv.hideturtlelv.uplv.goto(x, y) # 定位到(x,y)def curvemove: # 画圆弧for i in range(20):lv.right(10)lv.forward(2)lv.color('red', 'pink')lv.speed(10000000)lv.pensize(1)# 开始画爱心lalalalv.downlv.begin_filllv.left(140)lv.forward(22)curvemovelv.left(120)lv.write("WM", font=("Arial", 12, "normal"), align="center") # 写上表白的人的名字lv.left(140) # 画完复位lv.end_filldef tree(branchLen, t):if branchLen > 5: # 剩余树枝太少要结束递归if branchLen < 20: # 如果树枝剩余长度较短则变绿t.color("green")t.pensize(random.uniform((branchLen + 5) / 4 - 2, (branchLen + 6) / 4 + 5))t.downt.forward(branchLen)love(t.xcor, t.ycor) # 传输现在turtle的坐标t.upt.backward(branchLen)t.color("brown")return# 以下递归ang = random.uniform(15, 45)t.right(ang)tree(branchLen - random.uniform(12, 16), t) # 随机决定减小长度t.left(2 * ang)myWin = turtle.Screent = turtle.Turtlet.hideturtlet.speed(1000)t.left(90)t.upt.backward(200)t.pensize(32)t.forward(60)tree(100, t)myWin.exitonclick图中的“WM”是可以改的!看到代码里的“WM”两个字了没?直接把这两个字母替换成你心上人的名字就好。中文英文都可以。


想学习编程的话可以关注微信公众号:程序员大牛


02除了上面这个,你还可以利用Python画画啊,制作一份独一无二的画作送给自己的心上人。这个可和美图滤镜不一样,可以利用深度学习copy世界任何名画、甚至任何图片,给你爱人制作一份独一无二的画像。在这里,我教你两个画画的方式,各位瞧好了,看我大展身手。


先第一个:画像重叠。我们先选择两幅画,你们也可以一幅选你们心上人的画像,一幅选择风景或者其他。这个时候就看各位的审美了。这里我选择的都是风景。



首先,第一步:print('---Please put the picture in this file-----0img1_addres=input("Please enter the first picture's name plus the file suffix: ")img2_address=input("Please enter the name of the second picture plus the file suffix: ")percent1=input('Please enter the first picture to display the weight, the default is 0.5: ')percent2=input('Please enter the second picture to show the proportion, the default is 0.5: ')merge2(img1_addres,img2_address,percent1,percent2)然后自行设置显示比,如果没有输入,就会按照默认设置进行:# 如果两张图片中有一张没有输入显示比,默认设置为0.5if percent1=='' or percent2=='':percent1 = 0.50percent2 = 0.50获取图片地址:# 获取图片的地址img1=Image.open(img1_address)img2=Image.open(img2_address)然后再第三步:# 让两张图片的显示比相加等于1if percent1+percent2!=1:percent2=1-percent1再获取图片宽高:# 获取图片的最小宽高width = min(img1.size[0],img2.size[0])height = min(img1.size[1],img2.size[1])img_new = Image.new('RGB',(width,height))这时候渲染图片:# 渲染图片for x in range(width):for y in range(height):r1,g1,b1=img1.getpixel((x,y))r2,g2,b2=img2.getpixel((x,y))r=int(percent1*r1+percent2*r2)g=int(percent1*g1+percent2*g2)b=int(percent1*b1+percent2*b2)img_new.putpixel((x,y),(r,g,b))最后保存就好了!# 保存图片img_new.save('new.jpg')大家可以看一下渲染效果:


是不是特别好看,有世界名画的感觉。特别有莫奈的印象画风格。你可以利用这个代码给你心上人做一幅特别而好看的画像。这个我也是帮各位做好了小程序。第二个是图像渲染:通过Python的深度学习算法包去训练计算机模仿世界名画的风格,然后应用到另一幅画中!这个就没有小程序了。因为这个有几百个依赖包。专业难度比较高一些,首先,需要安装使用的模块,pip一键搞定:pip3 install keraspip3 install h5pypip3 install tensorflowTensorFlow的安装可能不翻墙的话下载的比较慢,也可以源码安装。自己把握。(TensorFlow只能python3.5安装,所以先下载一个3.5版本的)然后再下载VGG16模型。把代码生成py格式和需要渲染图片放在同一个文件夹。


这个是世界名画蒙娜丽莎,以这张图片为模板,让计算机去学习这张图片的风格应用到自己的这张图片上。


我先把代码贴出来(这个代码是根据知乎大佬:杨航锋的代码修改而成):from __future__ import print_functionfrom keras.preprocessing.image import load_img, img_to_arrayfrom scipy.misc import imsaveimport numpy as npimport timeimport argparsefrom keras.applications import vgg16from keras import backend as Kfrom scipy.optimize.lbfgsb import fmin_l_bfgs_bparser = argparse.ArgumentParser(description='Neural style transfer with Keras.')parser.add_argument('base_image_path', metavar='base', type=str,help='Path to the image to transform.')parser.add_argument('style_reference_image_path', metavar='ref', type=str, help='Path to the style reference image.')parser.add_argument('result_prefix', metavar='res_prefix', type=str,help='Prefix for the saved results.')parser.add_argument('--iter', type=int, default=15, required=False,help='Number of iterations to run.')parser.add_argument('--content_weight', type=float, default=0.025, required=False,help='Content weight.')parser.add_argument('--style_weight', type=float, default=1.0, required=False,help='Style weight.')parser.add_argument('--tv_weight', type=float, default=1.0, required=False,help='Total Variation weight.')args = parser.parse_argsbase_image_path = args.base_image_pathstyle_reference_image_path = args.style_reference_image_pathresult_prefix = args.result_prefixiterations = args.iter# 不同损失分量的权重total_variation_weight = args.tv_weightstyle_weight = args.style_weightcontent_weight = args.content_weight# 生成图片的尺寸width, height = load_img(base_image_path).sizeimg_nrows = 400img_ncols = int(width * img_nrows / height)# util function to open, 调整和格式化图片到适当的张量def preprocess_image(image_path):img = load_img(image_path, target_size=(img_nrows, img_ncols))img = img_to_array(img)img = np.expand_dims(img, axis=0)img = vgg16.preprocess_input(img)return img# util函数将一个张量转换成一个有效的图像def deprocess_image(x):if K.image_data_format == 'channels_first':x = x.reshape((3, img_nrows, img_ncols))x = x.transpose((1, 2, 0))else:x = x.reshape((img_nrows, img_ncols, 3))# Remove zero-center by mean pixel# 用平均像素去除零中心x[:, :, 0] += 103.939x[:, :, 1] += 116.779x[:, :, 2] += 123.68# 'BGR'->'RGB' 转换x = x[:, :, ::-1]x = np.clip(x, 0, 255).astype('uint8')return x# get tensor representations of our images# 得到图像的张量表示base_image = K.variable(preprocess_image(base_image_path))style_reference_image = K.variable(preprocess_image(style_reference_image_path))# this will contain our generated image# 包含我们生成的图片if K.image_data_format == 'channels_first':combination_image = K.placeholder((1, 3, img_nrows, img_ncols))else:combination_image = K.placeholder((1, img_nrows, img_ncols, 3))# combine the 3 images into a single Keras tensor# 将3个图像合并成一个Keras张量input_tensor = K.concatenate([base_image,style_reference_image,combination_image], axis=0)# build the VGG16 network with our 3 images as input# the model will be loaded with pre-trained ImageNet weights# 以我们的3个图像作为输入构建VGG16网络# 该模型将加载预先训练的ImageNet权重model = vgg16.VGG16(input_tensor=input_tensor,weights='imagenet', include_top=False)print('Model loaded.')# get the symbolic outputs of each "key" layer (we gave them unique names).# 获取每个“键”层的符号输出(我们给它们取了唯一的名称)outputs_dict = dict([(layer.name, layer.output) for layer in model.layers])# compute the neural style loss# 计算神经类型的损失# first we need to define 4 util functions# 首先我们需要定义是个until函数# the gram matrix of an image tensor (feature-wise outer product)# 图像张量的克矩阵def gram_matrix(x):assert K.ndim(x) == 3if K.image_data_format == 'channels_first':features = K.batch_flatten(x)else:features = K.batch_flatten(K.permute_dimensions(x, (2, 0, 1)))gram = K.dot(features, K.transpose(features))return gram# the "style loss" is designed to maintain# 风格损失”是为了维护而设计的# the style of the reference image in the generated image.# 生成图像中引用图像的样式# It is based on the gram matrices (which capture style) of feature maps from the style reference image and from the generated image# 它基于从样式引用图像和生成的图像中获取特征映射的gram矩阵(捕获样式)def style_loss(style, combination):assert K.ndim(style) == 3assert K.ndim(combination) == 3S = gram_matrix(style)C = gram_matrix(combination)channels = 3size = img_nrows * img_ncolsreturn K.sum(K.square(S - C)) / (4. * (channels ** 2) * (size ** 2))# an auxiliary loss function# 一个辅助的损失函数# designed to maintain the "content" of the base image in the generated image#设计用于维护生成图像中基本图像的“内容def content_loss(base, combination):return K.sum(K.square(combination - base))# the 3rd loss function, total variation loss,designed to keep the generated image locally coherent# 第三个损失函数,总变异损失,设计来保持生成的图像局部一致def total_variation_loss(x):assert K.ndim(x) == 4if K.image_data_format == 'channels_first':a = K.square(x[:, :, :img_nrows - 1, :img_ncols - 1] - x[:, :, 1:, :img_ncols - 1])b = K.square(x[:, :, :img_nrows - 1, :img_ncols - 1] - x[:, :, :img_nrows - 1, 1:])else:a = K.square(x[:, :img_nrows - 1, :img_ncols - 1, :] - x[:, 1:, :img_ncols - 1, :])b = K.square(x[:, :img_nrows - 1, :img_ncols - 1, :] - x[:, :img_nrows - 1, 1:, :])return K.sum(K.pow(a + b, 1.25))# combine these loss functions into a single scalar# 将这些损失函数合并成一个标量。loss = K.variable(0.)layer_features = outputs_dict['block4_conv2']base_image_features = layer_features[0, :, :, :]combination_features = layer_features[2, :, :, :]loss += content_weight * content_loss(base_image_features,combination_features)feature_layers = ['block1_conv1', 'block2_conv1','block3_conv1', 'block4_conv1','block5_conv1']for layer_name in feature_layers:layer_features = outputs_dict[layer_name]style_reference_features = layer_features[1, :, :, :]combination_features = layer_features[2, :, :, :]sl = style_loss(style_reference_features, combination_features)loss += (style_weight / len(feature_layers)) * slloss += total_variation_weight * total_variation_loss(combination_image)# get the gradients of the generated image wrt the loss# 得到所生成图像的梯度,并对损失进行wrt。grads = K.gradients(loss, combination_image)outputs = [loss]if isinstance(grads, (list, tuple)):outputs += gradselse:outputs.append(grads)f_outputs = K.function([combination_image], outputs)def eval_loss_and_grads(x):if K.image_data_format == 'channels_first':x = x.reshape((1, 3, img_nrows, img_ncols))else:x = x.reshape((1, img_nrows, img_ncols, 3))outs = f_outputs([x])loss_value = outs[0]if len(outs[1:]) == 1:grad_values = outs[1].flatten.astype('float64')else:grad_values = np.array(outs[1:]).flatten.astype('float64')return loss_value, grad_values"""this Evaluator class makes it possibleto compute loss and gradients in one passwhile retrieving them via two separate functions,"loss" and "grads". This is done because scipy.optimizerequires separate functions for loss and gradients,but computing them separately would be inefficient.这个评估器类使它成为可能。在一个通道中计算损耗和梯度。当通过两个不同的函数检索它们时,“损失”和“梯度”。这是因为scipy.optimize要求分离的函数用于损失和梯度,但是单独计算它们将是低效的"""class Evaluator(object):def __init__(self):self.loss_value = Noneself.grads_values = Nonedef loss(self, x):assert self.loss_value is Noneloss_value, grad_values = eval_loss_and_grads(x)self.loss_value = loss_valueself.grad_values = grad_valuesreturn self.loss_valuedef grads(self, x):assert self.loss_value is not Nonegrad_values = np.copy(self.grad_values)self.loss_value = Noneself.grad_values = Nonereturn grad_valuesevaluator = Evaluator# run scipy-based optimization (L-BFGS) over the pixels of the generated image# 运行 scipy-based optimization (L-BFGS) 覆盖 生成的图像的像素# so as to minimize the neural style loss# 这样可以减少神经类型的损失if K.image_data_format == 'channels_first':x = np.random.uniform(0, 255, (1, 3, img_nrows, img_ncols)) - 128.else:x = np.random.uniform(0, 255, (1, img_nrows, img_ncols, 3)) - 128.for i in range(iterations):print('Start of iteration', i)start_time = time.timex, min_val, info = fmin_l_bfgs_b(evaluator.loss, x.flatten,fprime=evaluator.grads, maxfun=20)print('Current loss value:', min_val)# save current generated imageimg = deprocess_image(x.copy)fname = result_prefix + '_at_iteration_%d.png' % iimsave(fname, img)end_time = time.timeprint('Image saved as', fname)print('Iteration %d completed in %ds' % (i, end_time - start_time))它会有一个不断渐进渲染的过程:


虽然我有老婆,而且我老婆特别好看,漂亮。但是为了不伤害到你们,我就用万门的新起点嘉园大楼渲染一下莫奈的名画。给你们具体看一下。




看起来还是非常有质感的,代码贴在这里,我相信有很多人一定会比我有创意。做出来的图一定会独一无二。比如下面这个就做的特别好看。你们可以尝试用人像渲染名画,出来的效果真心非常美丽好看而且独具个性!


但是,如果审美观比较差的,还是要问问旁边的人,以下就是我朋友用刘亦菲做的失败案例。他是用刘亦菲照片去模仿《无名女郎》的风格,把照片糊了一片,我把照片发出来给大家笑笑......



其实,只要是自己用心做出的礼物,你喜欢的人一定会非常感动。所以谁说程序员不浪漫了!只要真的喜欢一个妹子,会为她做尽温暖之事!哪怕是用自己的方式。追妹子,只要用心,她都会被感动。


爱情没有性价比,没有风险控制,但只要你尽了力付出过,就不会后悔。愿每一个渴望恋爱的人都能在520这天找到自己的心有所属。

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: