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

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

5474466-162c4dbbe0fcbae7

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

5474466-8d4f3e8ec4715229

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

5474466-d931a5f9da521459

当然了,如果还是单身的,也可以把这个作为表白神器,和心爱的人表白

会Python编程的人当然不用我说,就知道该如何操作,那些不懂编程的人,如果想尝试,那该怎么办呢?

这里我特地制作了小程序,微信后台私信“小程序”即可获取。运行就可以了。

懂编程的就看下面的吧!送上这份礼物之后,保证你明晚.....巫山云雨后,天气晚来秋啊!

5474466-ab26b39eab239d2a

01

首先教大家一个初级版的。这个就比较简单,利用Python制作一个爱心。

我先把代码给贴出来:

import turtle

扫描二维码关注公众号,回复: 5247509 查看本文章

import time

# 画爱心的顶部

def LittleHeart:

for i in range (200):

turtle.right(1)

turtle.forward(2)

# 输入表白的语句,默认I Love you

love=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,0

turtle.goto(0,-180)

turtle.showturtle

# 画上线

turtle.down

turtle.speed(1)

turtle.begin_fill

turtle.left(140)

turtle.forward(224)

#调用画爱心左边的顶部

LittleHeart

#调用画爱右边的顶部

turtle.left(120)

LittleHeart

# 画下线

turtle.forward(224)

turtle.end_fill

turtle.pensize(5)

# 在心中写字 一次

turtle.goto(0,0)

turtle.showturtle

turtle.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.showturtle

turtle.write(me, font=(20,), align="center", move=True)

#点击窗口关闭

window=turtle.Screen

window.exitonclick

这个代码最终呈现效果如下,这个是比较初级简单的爱心,没有什么高难度。你也可以把代码扩充一下,整的更加高大上一些。

5474466-c86d8b3cc49d1cf9

如果你觉得这个还不够酷炫,那我好人做到底,帮你制作一个表白爱心树

import turtle

import random

def love(x, y): # 在(x,y)处画爱心lalala

lv = turtle.Turtle

lv.hideturtle

lv.up

lv.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)

# 开始画爱心lalala

lv.down

lv.begin_fill

lv.left(140)

lv.forward(22)

curvemove

lv.left(120)

lv.write("WM", font=("Arial", 12, "normal"), align="center") # 写上表白的人的名字

lv.left(140) # 画完复位

lv.end_fill

def 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.down

t.forward(branchLen)

love(t.xcor, t.ycor) # 传输现在turtle的坐标

t.up

t.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.Screen

t = turtle.Turtle

t.hideturtle

t.speed(1000)

t.left(90)

t.up

t.backward(200)

t.pensize(32)

t.forward(60)

tree(100, t)

myWin.exitonclick

图中的“WM”是可以改的!看到代码里的“WM”两个字了没?直接把这两个字母替换成你心上人的名字就好。中文英文都可以。

5474466-e9ca036793a9f023

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

5474466-64830c274b28b351

02

除了上面这个,你还可以利用Python画画啊,制作一份独一无二的画作送给自己的心上人。

这个可和美图滤镜不一样,可以利用深度学习copy世界任何名画、甚至任何图片,给你爱人制作一份独一无二的画像。

在这里,我教你两个画画的方式,各位瞧好了,看我大展身手。

5474466-45205cef0d174441

先第一个:画像重叠。

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

5474466-238a398733169590
5474466-20a921b40aedbe39

首先,第一步:

print('---Please put the picture in this file-----0

img1_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.5

if percent1=='' or percent2=='':

percent1 = 0.50

percent2 = 0.50

获取图片地址:

# 获取图片的地址

img1=Image.open(img1_address)

img2=Image.open(img2_address)

然后再第三步:

# 让两张图片的显示比相加等于1

if 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')

大家可以看一下渲染效果:

5474466-c72c84c9a4f262e2

是不是特别好看,有世界名画的感觉。特别有莫奈的印象画风格。你可以利用这个代码给你心上人做一幅特别而好看的画像。这个我也是帮各位做好了小程序

第二个是图像渲染:

通过Python的深度学习算法包去训练计算机模仿世界名画的风格,然后应用到另一幅画中!

这个就没有小程序了。因为这个有几百个依赖包。

专业难度比较高一些,首先,需要安装使用的模块,pip一键搞定:

pip3 install keras

pip3 install h5py

pip3 install tensorflow

TensorFlow的安装可能不翻墙的话下载的比较慢,也可以源码安装。自己把握。(TensorFlow只能python3.5安装,所以先下载一个3.5版本的)

然后再下载VGG16模型。把代码生成py格式和需要渲染图片放在同一个文件夹。

5474466-fd3d3804fc25760b

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

5474466-514026bdc9b0d54d

我先把代码贴出来(这个代码是根据知乎大佬:杨航锋的代码修改而成):

from __future__ import print_function

from keras.preprocessing.image import load_img, img_to_array

from scipy.misc import imsave

import numpy as np

import time

import argparse

from keras.applications import vgg16

from keras import backend as K

from scipy.optimize.lbfgsb import fmin_l_bfgs_b

parser = 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_args

base_image_path = args.base_image_path

style_reference_image_path = args.style_reference_image_path

result_prefix = args.result_prefix

iterations = args.iter

# 不同损失分量的权重

total_variation_weight = args.tv_weight

style_weight = args.style_weight

content_weight = args.content_weight

# 生成图片的尺寸

width, height = load_img(base_image_path).size

img_nrows = 400

img_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.939

x[:, :, 1] += 116.779

x[:, :, 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) == 3

if 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) == 3

assert K.ndim(combination) == 3

S = gram_matrix(style)

C = gram_matrix(combination)

channels = 3

size = img_nrows * img_ncols

return 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) == 4

if 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)) * sl

loss += 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 += grads

else:

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 possible

to compute loss and gradients in one pass

while retrieving them via two separate functions,

"loss" and "grads". This is done because scipy.optimize

requires separate functions for loss and gradients,

but computing them separately would be inefficient.

这个评估器类使它成为可能。

在一个通道中计算损耗和梯度。

当通过两个不同的函数检索它们时,

“损失”和“梯度”。这是因为scipy.optimize

要求分离的函数用于损失和梯度,

但是单独计算它们将是低效的

"""

class Evaluator(object):

def __init__(self):

self.loss_value = None

self.grads_values = None

def loss(self, x):

assert self.loss_value is None

loss_value, grad_values = eval_loss_and_grads(x)

self.loss_value = loss_value

self.grad_values = grad_values

return self.loss_value

def grads(self, x):

assert self.loss_value is not None

grad_values = np.copy(self.grad_values)

self.loss_value = None

self.grad_values = None

return grad_values

evaluator = 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.time

x, 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 image

img = deprocess_image(x.copy)

fname = result_prefix + '_at_iteration_%d.png' % i

imsave(fname, img)

end_time = time.time

print('Image saved as', fname)

print('Iteration %d completed in %ds' % (i, end_time - start_time))

它会有一个不断渐进渲染的过程:

5474466-5266c91228c466e3

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

5474466-5e01749fef0444a8
5474466-d6e6946b4720f2be
5474466-090f870ccee178a4

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

5474466-9a8341915f2c6e82

但是,如果审美观比较差的,还是要问问旁边的人,以下就是我朋友用刘亦菲做的失败案例。

他是用刘亦菲照片去模仿《无名女郎》的风格,把照片糊了一片,我把照片发出来给大家笑笑......

5474466-82fe7629dec48b1a
5474466-3892be73a7da2a00

其实,只要是自己用心做出的礼物,你喜欢的人一定会非常感动。

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

5474466-1635eddd5b14225c

爱情没有性价比,没有风险控制,但只要你尽了力付出过,就不会后悔。

愿每一个渴望恋爱的人都能在520这天找到自己的心有所属。

5474466-eb7bcf2f8d367fb7

猜你喜欢

转载自blog.csdn.net/weixin_34283445/article/details/87642409