范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

不用P图!用Python给头像加圣诞帽并制作成可执行软件

  作者:   派森酱
  来源:Python 技术
  随着圣诞节的到来,节日气氛也越来越浓厚。大街上随处可见挂满饰品的圣诞树,好多小伙伴的头上也多了一顶红色牛角的圣诞帽。
  往年在这个时候,好多 P图软件 会推出给头像加一顶圣诞帽的功能,甚至有一年大伙 @微信官方 就可以在自己的微信头像上加一顶圣诞帽。
  作为一个学习 Python 的技术人,自己可以写程序实现这个功能,做成一个软件当然是一件很酷的事情了。
  今天就给大家分享一下如何用 Python 制作一款自动给头像添加圣诞帽的软件。
  如果不想看实现,可以直接跳到文末获取软件。  思路
  我们的  头像添加圣诞帽软件  制作的大致思路如下: 要实现一个软件,我们需要制作一个 GUI 界面,供用户操作。  要实现头像戴圣诞帽功能,我们需要用户上传一张头像,我们还需要准备一顶圣诞帽子图片。  要把圣诞帽戴在头像上,我们需要识别头像中的人脸和头部特征,然后将帽子放在头顶合成一张图片。
  基于以上思路,我们制作这款软件的关键词有:  GUI 界面  圣诞帽图片  头像图片  人脸识别  打包软件  实现
  看了以上思路,相信大家脑海中已经对这个软件制作的过程有了一个大致的框架了。我们的实现主要分为:图像制作、GUI界面、打包三大块内容。  准备工作
  首先列举一下本次软件制作过程中需要用的的一些包模块:  cv2
  pip install opencv-python   os
  python 系统模块   dlib
  pip install dlib   numpy
  pip install pandas   PySimpleGUI
  pip install PySimpleGui
  温馨提示:这其中安装 dlib 会遇到很多坑以及很多困难,一般需要一边安装一边上网搜索报错,从而找到解决办法。保证安装过一次之后不想尝试第二次。  图像制作准备圣诞帽
  我们需要准备一个圣诞帽的图片,格式最好为 png ,因为 png 图片我们可以直接用  Alpha通道  作为掩膜使用。如果是 jpg 图片,需要先转换成 png 格式图片。注意这里的转换不是只改个后缀名,那样是行不通的。
  我们用到的圣诞帽如下图:
  为了能够与 RGB 通道的头像图片进行运算,我们需要把圣诞帽图像分离成 RGB 通道图像和 alpha通道图像:  r,g,b,a = cv2.split(hat_img) rgb_hat = cv2.merge((r,g,b)) cv2.imwrite("hat_alpha.jpg",a)
  分离之后,得到的 alpha通道图像如下所示:
  人脸识别
  我从我的百宝箱中选择了一张傻萌傻萌的图片作为程序的测试图片。
  大家注意,因为我们要做人脸识别,然后自动添加帽子,所以选择的图片一定要是真人的正面照片,不然识别不了人脸,也就不知道在哪添加圣诞帽。
  下面我们用 dlib 的正脸检测器进行人脸检测,用 dlib 提供的模型提取人脸的五个关键点。代码如下:  # dlib人脸关键点检测器       predictor_path = "shape_predictor_5_face_landmarks.dat"       predictor = dlib.shape_predictor(predictor_path)            # dlib正脸检测器       detector = dlib.get_frontal_face_detector()          # 正脸检测       dets = detector(img, 1)          # 如果检测到人脸       if len(dets)>0:             for d in dets:               x,y,w,h = d.left(),d.top(), d.right()-d.left(), d.bottom()-d.top()               # x,y,w,h = faceRect                 cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2,8,0)                  # 关键点检测,5个关键点               shape = predictor(img, d)               for point in shape.parts():                   cv2.circle(img,(point.x,point.y),3,color=(0,255,0))                  cv2.imshow("image",img)               cv2.waitKey()
  我们把图片打印出来的效果是这样的:
  看到这个图片是不是有点熟悉,网上好多人脸识别的图片都是这样的。  调整帽子大小
  我们选取两个眼角的点,求中心作为放置帽子的x方向的参考坐标,y 方向的坐标用人脸框上线的 y 坐标表示。
  然后我们根据人脸检测得到的人脸的大小调整帽子的大小,使得帽子大小合适。
  看到这里,你应该明白,我们头像的图片中人的脸越正面那么我们制作出来的效果越好。              # 选取左右眼眼角的点             point1 = shape.part(0)             point2 = shape.part(2)              # 求两点中心             eyes_center = ((point1.x+point2.x)//2,(point1.y+point2.y)//2)              #  根据人脸大小调整帽子大小             factor = 1.5             resized_hat_h = int(round(rgb_hat.shape[0]*w/rgb_hat.shape[1]*factor))             resized_hat_w = int(round(rgb_hat.shape[1]*w/rgb_hat.shape[1]*factor))              if resized_hat_h > y:                 resized_hat_h = y-1              # 根据人脸大小调整帽子大小             resized_hat = cv2.resize(rgb_hat,(resized_hat_w,resized_hat_h))  帽子区域处理
  我们先将帽子的 alpha通道 作为 mask掩膜:  mask = cv2.resize(a,(resized_hat_w,resized_hat_h)) mask_inv =  cv2.bitwise_not(mask)
  接着,从人像图中去除需要添加帽子的区域:              # 帽子相对与人脸框上线的偏移量               dh = 0               dw = 0               # 原图ROI               # bg_roi = img[y+dh-resized_hat_h:y+dh, x+dw:x+dw+resized_hat_w]               bg_roi = img[y+dh-resized_hat_h:y+dh,(eyes_center[0]-resized_hat_w//3):(eyes_center[0]+resized_hat_w//3*2)]                  # 原图ROI中提取放帽子的区域               bg_roi = bg_roi.astype(float)               mask_inv = cv2.merge((mask_inv,mask_inv,mask_inv))               alpha = mask_inv.astype(float)/255                  # 相乘之前保证两者大小一致(可能会由于四舍五入原因不一致)               alpha = cv2.resize(alpha,(bg_roi.shape[1],bg_roi.shape[0]))               # print("alpha size: ",alpha.shape)               # print("bg_roi size: ",bg_roi.shape)               bg = cv2.multiply(alpha, bg_roi)               bg = bg.astype("uint8")
  提取后的效果图如下:
  接下来,我们提取圣诞帽的区域:  hat = cv2.bitwise_and(resized_hat,resized_hat,mask = mask)
  提取后的效果图如下:
  盖帽
  图像处理的最后一步是盖帽了,就是把提取的圣诞帽区域和图片中提取的区域相加,然后再放到原图中去。这里需要注意的就是,相加之前resize一下保证两者大小一致                # 相加之前保证两者大小一致(可能会由于四舍五入原因不一致)               hat = cv2.resize(hat,(bg_roi.shape[1],bg_roi.shape[0]))               # 两个ROI区域相加               add_hat = cv2.add(bg,hat)               # cv2.imshow("add_hat",add_hat)                   # 把添加好帽子的区域放回原图               img[y+dh-resized_hat_h:y+dh,(eyes_center[0]-resized_hat_w//3):(eyes_center[0]+resized_hat_w//3*2)] = add_hat
  最后,我们得到的效果图如下:
  GUI界面
  我们先来看效果图:
  然后再来看这部分的实现代码:  import PySimpleGUI as sg import os.path import cv2  file_list_column = [     [sg.Submit("生成", key="Go", size=(15, 1)), sg.Cancel("退出", key="Cancel", size=(15, 1))],     [         sg.Text("图片位置(选择文件夹)"),         sg.In(size=(25, 1), enable_events=True, key="-FOLDER-"),         sg.FolderBrowse("浏览"),     ],     [         sg.Listbox(             values=[], enable_events=True, size=(40, 20), key="-FILE LIST-"         )     ] ] image_viewer_column = [     [sg.Text("从左边图片列表中选择一张图片:")],     [sg.Image(key="-IMAGE-")] ] layout = [     [         sg.Column(file_list_column),         sg.VSeperator(),         sg.Column(image_viewer_column),     ] ] window = sg.Window("人像添加圣诞帽软件", layout) filename = "" while True:     event, values = window.read()     if event == "Cancel" or event == sg.WIN_CLOSED:         break     if event == "-FOLDER-":         folder = values["-FOLDER-"]         try:             file_list = os.listdir(folder)         except:             file_list = []         fnames = [             f             for f in file_list             if os.path.isfile(os.path.join(folder, f))                and f.lower().endswith((".jpg", ".png"))         ]         window["-FILE LIST-"].update(fnames)     elif event == "-FILE LIST-":         try:             filename = os.path.join(values["-FOLDER-"], values["-FILE LIST-"][0])             if filename.endswith(".jpg"):                 im = cv2.imread(filename)                 cv2.imwrite(filename.replace("jpg", "png"), im)             window["-IMAGE-"].update(filename=filename.replace("jpg", "png"))         except Exception as e:             print(e)     elif event == "Go":         try:             # output = add_hat(filename)             # 展示效果             # cv2.imshow("output",output)             # cv2.waitKey(0)             # cv2.imwrite("output.png",output)             # print(output)             window["-IMAGE-"].update(filename="output.png")         except:             print("OMG!添加失败了!")          cv2.destroyAllWindows()
  这里我选用的是 PySimpleGUI 框架来做的,比较简单。界面分为左右两部分,左边是两个按钮(确定和取消)加一个文件夹选择器,再加一个图片文件列表;右边是一个图片展示框。
  左边选择文件夹后,会在下方列出文件夹里包含  .png  和 .jpg  的图片列表。点击图片列表中的图片,会在右边显示你所选择的图片。这个选中的图片也就是我们后面需要添加圣诞帽的图片。
  这里需要注意的是,PySimpleGUI 的图片展示默认只支持 png 格式的,所以我在展示的时候做了判断,如果是 jpg 格式的图片,我就用 cv2 将其转换成 png 格式,然后再进行展示。
  到这里,我们的关键步骤就完成了。接下来就是将我们两部分代码进行整合。其实也很简单,只需要在 GUI 界面上用户点击 "生成" 按钮时,后台接收到图片的路径,传递给我们的图片处理函数,在处理完后将图片保存在文件夹下,并更新 GUI 界面右边的展示的图片即可。
  最终的运行效果:
  打包软件
  打包软件我们还是用熟悉的 pyinstaller 模块,将代码打包成可执行的 exe 格式。
  首先下载我们所需的模块包:
  pip install pyinstaller
  接着在命令行敲下打包命令:
  pyinstaller christmashat.py
  这个  christmashat.py  就是我们所写的程序了。
  打包比较耗时,耐心等着就行。打包完成后,在我们代码的目录下会生成三个文件夹:  __pycache__  build  dist
  我们只需要关注  dist  就行。dist  文件夹下面是 christmashat  子文件夹,再进去就可以找到我们的 christmashat.exe  文件了。由于我们的程序运行有两个依赖文件,分别是我们的圣诞帽图片和我们的人脸识别训练集,所以我们需要将这两个文件放入这个 EXE 文件所在的文件夹下。
  现在双击  christmashat.exe  文件就可以正常运行了。 总结
  本文从一个实际需求出发,向大家讲解了一个头像添加圣诞帽软件的诞生过程。相对于之前的一些小应用来说,涉及的知识点较多,可能还是有点复杂的。其中有一些知识点限于篇幅原因没有详细讲解,大家可以自己私下补充。

LOLM中单战士通用出装,斗鱼灵药无数实战经验,甜食还是最好用LOLM国服准时上线了2。6A版本,众所周知除了两位新英雄凯尔和莫甘娜,以及蒙多重做之外,还有就是匹配系统再次优化。可以说国服的优化效率让人无话可说,S3也即将结束S4又是一波冲分詹姆斯连砍30湖人完败灰熊持续更新詹姆斯生涯数据今日NBA比赛,湖人主场119127灰熊队。詹姆斯本场比赛数据出场33分钟35分9篮板板7助攻0抢断0盖帽19投14中三分4投3中今日比赛詹姆斯凭借这7次助攻,生涯总助攻来到988德杯小组赛结束,外媒排出前五队伍,你最看好谁德杯小组赛打完后,八强战队出炉,虽然很多队伍的关键选手没有参赛,比如Uzitheshy等人,但大部分战队都安排了新赛季的主力选手上场,经过前几天的比赛,观众们也算是大概了解这些选手冒险恐怖游戏夜廻三新情报闭上双眼竟能躲避追兵日本一旗下恐怖动作冒险游戏夜廻系列在本月正式公开了新作夜廻三,今天日媒杂志对本作中的一些新情报进行了速报,下面让我们一起来看看吧!以下为夜廻三新情报整理主人公在森林中醒来发现失去了伊隆马斯克谈火星殖民,称SpaceX会让宇宙飞船返回SpaceX创始人兼首席工程师伊隆马斯克(ElonMusk)长期以来一直梦想着通过建造可重复使用的星际飞船舰队,让人类能够建造火星阿尔法基地(MarsBaseAlpha),这是火星作为宇宙信使的X射线01来自看不见的宇宙的信使1895年德国物理学家威尔海姆伦琴(WilhelmRntgen)发现了以他名字命名的射线,也就是我们熟知的X射线。1901年首个诺贝尔物理学奖授予了伦琴,中意合作空间天文项目极光计划揭示天体辐射区域几何信息1月,清华大学主导的中意合作空间天文项目极光计划发表最新成果。经过对吸积中子星天蝎座X1的长期观测,极光取得了显著的偏振探测,并对辐射区域位置和几何提出了严格限制。至此,极光计划已宇宙中别的星星上有人吗银河系有1000亿颗以上的恒星,它们全是炽热的气体球,表面温度达200030000,甚至更高。在这种环境下,显然不可能有任何生命存在,当然更谈不上人了。宇宙间,只有在那些不发光有固伊斯坦布尔之旅伊斯坦布尔(Istanbul)位于巴尔干半岛和安纳托利亚黑海和地中海之间的博斯普鲁斯海峡半岛(Bosphoruspeninsula),2000多年来一直与重大政治宗教和艺术事件联系艾尔登法环测试玩家发现隐藏大熊BOSS尽管宫崎英高的开放世界受苦游戏艾尔登法环将于2022年2月发售,不过已经有大神通过对游戏测试客户端的挖掘发现了不少东西,近日甚至有玩家通过邪道方法穿过游戏测试时设置的空气墙,来到新父母是孩子的引路人,而不是保姆,巴菲特对子女的忠告之四头条热榜中国式家庭教育父母不可能一辈子都在孩子身边,终有一天父母会老去,孩子们会成为新的父母,这是历史规律。孩子们的成长过程中都会有一个依赖阶段,家长要做的就是缩短这个阶段,锻炼孩
会馆里的乡约印记作者介绍袁家方历任首都经济贸易大学工商系副主任学报主编首都经济瞭望主编首都经济研究所副所长长城旅游学院副院长。中国商业史学会常务理事中国地理学会北京旅游地学会常务理事北京商业经济学紫薇温婉娴静,又是一位才女,为什么大家却偏爱小燕子?紫薇温婉娴静,又是一位才女,为什么大家更偏爱小燕子?首先,小燕子比紫薇先进宫,从此之后就搞出了稀奇古怪的事情,也带来了很多欢乐。紫薇以宫女的身份进宫,真相白后成了格格,但是大家好像郭德纲寄予厚望的窝头会馆,上演时间再次推迟,网友够呛窝头会馆是郭德纲对自己,乃至对德云社的一次挑战,话剧之难不是一般人能够驾驭的,这也是很多钢丝担心演砸了的原因。对演员来讲,话剧没有NG,如果演出出现小失误,那么只能硬着头皮演下去,旅游达人燕子,带大家游玩墨西哥我来跟大家介绍一下,引人注目的是建在金字塔上的铭文神庙。金字塔为正方形,共十层,向上逐层缩小,最低一层有梯阶九级,其余有梯阶七级,共七十二级。铭文神庙就建筑在金字塔顶平台上奇琴伊察感受北京南城变化感受变化!莫过于小区周边,现在仿佛置身于著名旅游景点,看着楼下三五成群的在油菜花中拍照!第一次来到这里大兴区瀛海,那时候也是听说有个地铁8号线的终点站瀛海站!当时也就几个地铁的高架旅游达人燕子,带大家游玩墨西哥,女人岛我来跟大家介绍一下,女人岛是在墨西哥景点的坎昆附近,距离坎昆极近的小岛,是许多坎昆观光客一日游的景点。西班牙人早年曾在此处发现许多马雅女性陶制的神像,因而得名。小岛的市中心位于岛的小燕子赵薇为何被娱乐圈除名,背后的原因,没那么简单说到赵薇,很多80后和90后肯定都不陌生,她主演还珠格格中的小燕子,曾经风靡大江南北,收获了不少粉丝,而如今却已然凉凉。有人说吴亦凡被封杀是因为强奸,张哲瀚被封杀是因为亲日,郑爽被王一梅瘦成锥子脸,粉色外套配多彩美甲,退役生活很不错女排前国手王一梅的职业生涯应该是充满遗憾的,作为她本人来说也是让人记忆深刻,毕竟像她这样特征明显的球员并不多,她的扣球总是充满力量,而且提到她的第一反应就是胖。不过现在我们或许要改春天逛逛北京带儿化音的胡同,品读历史文化韵味北京人爱说儿化音一条条胡同是老北京的根如今依然有胡同名称保留了儿字百花盛开的春天让我们一起逛逛北京城的胡同感受胡同的文化韵味还可以戴上耳机单曲循环那首北京胡同听一听老北京的回忆幽长夏季连衣裙搭配什么鞋子好看夏季连衣裙搭配什么鞋子好看呢?连衣裙作为最能体现女人味的服饰,它能很好地表现出女人的优雅与气质。但是,想要穿好连衣裙,还是需要我们在颜色选择和搭配上飞一番功夫的。小仙女们选择到适合在湖边回忆起那段往昔在深夜里,我站在湖边眺望着夜里的美景。闪烁的灯光在平静的湖面上跳跃,忽隐忽现。明亮的月亮像披着面纱的少女的脸庞,害羞地钻入薄薄的云层中若隐若现的星星也在漫漫长夜里不约而同闪烁着微弱