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

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

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

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

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

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

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

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

01

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

我先把代码给贴出来:

import turtle

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

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

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

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”两个字了没?直接把这两个字母替换成你心上人的名字就好。中文英文都可以。

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

02

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

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

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

先第一个:画像重叠。

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

首先,第一步:

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

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

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

第二个是图像渲染:

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

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

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

pip3 install keras

pip3 install h5py

pip3 install tensorflow

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

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

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

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

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

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

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

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

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

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

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

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

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

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,045评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,114评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,120评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,902评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,828评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,132评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,590评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,258评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,408评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,335评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,385评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,068评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,660评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,747评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,967评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,406评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,970评论 2 341

推荐阅读更多精彩内容

  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi阅读 7,267评论 0 10
  • 那些说说和签名更新频率越来越低的朋友,我有理由相信你们已经日渐成熟 这世上有很多事,是不会给我们以准备机会的,比如...
    24e2f6668318阅读 313评论 0 0
  • kkkkpppp9990
    时空里的夹缝人阅读 576评论 0 0
  • 1. 万里长城今犹在,不见当年秦始皇。 秦始皇只是现在不见了,他以前存在过,万里长城现在都还在,以前当然也存在,它...
    jimmy吉米杨阅读 771评论 5 3
  • 我跳的很高,妈妈说我跳了一蹦三尺高。
    祉延阅读 262评论 0 1