栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

利用python写福字【弄个不一样的五福~】

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

利用python写福字【弄个不一样的五福~】

前言:

马上到春节了,支付宝 2022集五福活动又正式开启开始啦!不出意外,这个星期你会主动找我说话。不为别的,就为了敬业福。

今天小编用python给你们展示一个不一样的五福!感兴趣的小伙伴点击这里哦!

一、头像福

这个福字是用微信好友的头像所组成。使用 itchat 和 PIL 库,详细方法和代码:

【第一步】

思路:我们自己输入汉字,根据字符串中汉字字符编码,去HZK16字库中获取点阵信息,拿到信息后根据16*16点阵每个点的数据,print 出不同字符。

#初始化16*16的点阵位置,每个汉字需要16*16=256个点来表示
rect_list = [] * 16
for i in range(16):
    rect_list.append([] * 16)
#拿“赞”字来演示
text = "赞"
#获取中文的编码
gb2312 = text.encode('gb2312')
hex_str = binascii.b2a_hex(gb2312)
result = str(hex_str, encoding='utf-8')
#根据编码计算“赞”在汉字库中的位置
area = eval('0x' + result[:2]) - 0xA0
index = eval('0x' + result[2:]) - 0xA0
offset = (94 * (area-1) + (index-1)) * 32
font_rect = None
#读取HZK16汉字库文件中“赞”字数据
with open("HZK16", "rb") as f:
    f.seek(offset)
    font_rect = f.read(32)
#根据读取到HZK中数据给我们的16*16点阵赋值
for k in range(len(font_rect) // 2):
    row_list = rect_list[k]
    for j in range(2):
        for i in range(8):
            asc = font_rect[k * 2 + j]
            flag = asc & KEYS[i]
            row_list.append(flag)
#根据获取到的16*16点阵信息,打印到控制台
for row in rect_list:
    for i in row:
        if i:
            #前景字符(即用来表示汉字笔画的输出字符)
            print('0', end=' ')
        else:
            #背景字符(即用来表示背景的输出字符)
            print('.', end=' ')
    print()

【第二步】

我们通过 itchat 这个开源的微信个人号接口来获取微信好友头像图片。

#通过二维码登录微信网页版
itchat.auto_login()
#获取微信好友信息列表
friendList = itchat.get_friends(update=True)
#读取好友头像
for friend in friendList:
    friend['head_img'] = itchat.get_head_img(userName=friend['UserName'])
    friend['head_img_name'] = "%s.jpg" % friend['UserName']
    #写入文件
    with open(friend['head_img_name'],'wb') as f:
        f.write(friend['head_img'])

【第三步】

有了头像之后,我们通过 PIL (Python Image Library,python的第三方图像处理库) 根据汉字点阵信息拼接头像图片。核心代码片段:

#新建画布,16*16点阵,每个图片边长100
canvas = Image.new('RGB', (1600, 1600), '#FFFFFF')
n = 0
for i in range(16*16):
    #点阵信息为1,即代表此处要显示头像来组字
    if item[i] == "1":
        # 打开图片
        img = Image.open(imgList[n])
        # 缩小图片
        img = img.resize((100, 100), Image.ANTIALIAS)
        # 拼接图片
        canvas.paste(img, ((i % 16) * 100, (i // 16) * 100))
        n += 1

综合以上三个步骤,即可用微信好友头像组成你想要的文字了。

 二、文字福

这个福字是将福字图片转成文字符号显示而组成,使用 opencv-python 库,详细方法及代码:

# coding: utf8
import cv2 as cv
import os
import time
# 替换字符列表
ascii_char = list(r"$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/|()1{}[]?-_+~<>i!lI;:,"^`'. ")
char_len = len(ascii_char)
# 加载视频
cap = cv.VideoCapture('video.mp4')
while True:
    # 读取视频每一帧
    hasframe, frame = cap.read()
    if not hasframe:
        break
    # 视频长宽
    width = frame.shape[0]
    height = frame.shape[1]
    # 转灰度图
    img_gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
    # 缩小图片并调整长宽比
    img_resize = cv.resize(img_gray, (int(width / 10), int(height / 10)))

    text = ''
    # 遍历图片中的像素
    for row in img_resize:
        for pixel in row:
            # 根据像素值,选取对应的字符
            text += ascii_char[int(pixel / 256 * char_len)]
        text += 'n'
    # 清屏
    os.system('cls')  # mac是'clear'
    # 输出生成的字符方阵
    print(text)
    # 适当暂停一下
    time.sleep(0.03)
 三、名画福

核心代码其实很短,就是 加载模型 -> 读取图片 -> 进行计算 -> 输出图片,详细方法及代码:

import cv2
# 加载模型
net = cv2.dnn.readNetFromTorch('the_scream.t7')
net.setPreferableBackend(cv2.dnn.DNN_BACKEND_OPENCV);
# 读取图片
image = cv2.imread('test.jpg')
(h, w) = image.shape[:2]
blob = cv2.dnn.blobFromImage(image, 1.0, (w, h), (103.939, 116.779, 123.680), swapRB=False, crop=False)
# 进行计算
net.setInput(blob)
out = net.forward()
out = out.reshape(3, out.shape[2], out.shape[3])
out[0] += 103.939
out[1] += 116.779
out[2] += 123.68
out /= 255
out = out.transpose(1, 2, 0)
# 输出图片
cv2.imshow('Styled image', out)
cv2.waitKey(0)
 四、变形福

 如何用 python 的图像处理功能,把一幅“福”字图片转出 5 种不同的效果?在接下来使用 opencv-python的几个方法教程中,总有一款适合你,方法及代码:

【第1步】

读取图片及展示代码:

import cv2
from matplotlib import pyplot as plt
img = cv2.imread('fu.png')
# 转换颜色模式,显示原图
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.imshow(img)
plt.show()

因为 OpenCV 和 matplotlib 的颜色模式不一样,所以需要做一次转换,如果是直接通过 cv2 展示和保存图片则不需要。

【第2步】

上面的效果分别用到了以下功能:

1、灰度福

这里没有选择直接将图片转出灰度图,因为这样会导致福字不明显。而是通过将红、绿、蓝三通道分离后,选择色差最大的红色通道。

r,g,b = cv2.split(img)

2、轮廓福

使用了 OpenCV 自带的图像轮廓提取功能。为了更好的效果,这里对红色通道进行二值化后,再查找轮廓。

_, img_bin = cv2.threshold(r, 50, 255, cv2.THRESH_BINARY)
_, contours, _ = cv2.findContours(img_bin, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
img_cont = np.zeros(img_bin.shape, np.uint8)    
cv2.drawContours(img_cont, contours, -1, 255, 3)

3、反色福

发色的实现是将每个像素值 x 转成 255-x。如果遍历像素计算会比较慢,于是用了一个小技巧:转成 numpy 的 ndarray 再进行矩阵运算。

img_i = np.asarray(img)
img_i = 255 - img_i

4、膨胀福

这里其实是“图像腐蚀”操作(与“图像膨胀”操作相反)。因为在我们选取的红色通道中,白色是背景,黑色才是福字,所以对白色的“腐蚀”也就是对黑色的“膨胀”。这也是 OpenCV 的内置功能。做完这一步,又对图像进行了切割,直接通过列表的切片操作实现。

kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(25, 25))
eroded = cv2.erode(r, kernel)
size = img.shape
eroded = eroded[int(size[1]*0.15):int(size[1]*0.7),int(size[0]*0.2):int(size[0]*0.85)]
五、福到了

OpenCV 提供了翻转操作,第二个参数是旋转轴的选取,你可以试试 0 和 1 的效果。

img_r = cv2.flip(img, -1)

经验证,以上福字皆可扫。本人已集齐

 最后,再送上一张阿里某马姓员工写的福字,据说扫它能抽到稀有福!

今天的分享就到这里,喜欢就点个赞吧!

需要完整的项目源码或者有什么不清楚的地方,欢迎截图私信我,要么点击这行蓝色字体!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/724849.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号