上次做完python实现人脸识别抓取人脸并做成熊猫头表情包之后就放了一下,因为还要好好学习Springboot毕竟这才是找工作的硬实力。但是优化这个代码心里面一直很想,借用《clean code》的话来说就是“Bad code tempts the mess to grow! ”所以优化是必要的。 
这里我优化了两个地方,第一个是掩膜的生成,第二个是表情位置的自动获取,同时也拆分一部分代码,和修改了一些注释,让代码看起来更简洁和已读。 
第一个是掩膜的生成。修改之前是这样的

#新建一个和原图一样大小的全白图片,用ImageDraw在上面勾出人脸轮廓,作为掩膜的模板
mask = np.ones(image.shape, dtype=np.uint8)*255
mask = Image.fromarray(mask)
q = ImageDraw.Draw(mask)
q.line(face_line[0], width=5, fill=(0, 0, 0))
mask.save(r"image/mask.jpg")#将图片写出是为了交给OpenCV处理
1
2
3
4
5
6
经过改动,包括让掩膜容纳更多脸以及将初始掩膜做成全黑

#新建一个和原图一样大小的全黑图片,用ImageDraw在上面勾出人脸轮廓,作为掩膜的模板
mask = np.zeros(image.shape, dtype=np.uint8)
mask = Image.fromarray(mask)
q = ImageDraw.Draw(mask)
for i in face_line:
    q.line(i, width=5, fill=(255, 255, 255))
mask.save(r"rbq/mask.jpg")#将图片写出是为了交给OpenCV处理
1
2
3
4
5
6
7
这里之所以将初始掩膜做成全黑是因为后面需要做一次水漫填充将非ROI区域变成全白,如果初始掩膜做成全白的话到提取表情的时候仍然需要再做一次水漫填充,这样子非常影响性能,本身python的运行速度就很慢。 
第二个是自动抓取表情的位置,这个相对之前的代码属于新增的功能,之前的代码需要自己手动调整截取位置以及熊猫头被替换的部分,正常来说是需要调整很多次才能得到。 
这里先定义几个函数

#获取脸部最高点
def the_top(x_list):
    return sorted(x_list, key=lambda x: x[1])

#获取脸部最低点
def the_bottom(x_list):
    return sorted(x_list, key=lambda x: x[1], reverse=True)

#获取脸部最左点
def the_left(y_list):
    return sorted(y_list, key=lambda y: y[0])

#获取脸部最右点
def the_right(y_list):
    return sorted(y_list, key=lambda y: y[0], reverse=True)

#计算正方形左上角和右下角的点
#表情位置用正方形把它截下来
def square(face_point):
    centre, top, bottom, left, right = face_point['centre'], face_point['top'], face_point['bottom'], face_point['left'], face_point['right']
    #用眉毛以及下巴作为选框参照
    # side = ((centre[1] - top[1]) if ((centre[1] - top[1]) > (bottom[1] - centre[1])) else (bottom[1] - centre[1]))
    #用左右轮廓作为选框参照
    side = ((centre[0] - left[0]) if ((centre[0] - left[0]) < (right[0] - centre[0])) else (right[0] - centre[0]))
    return (centre[0] - side, centre[1] - side), (centre[0] + side, centre[1] + side)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
这时候我在生成脸部轮廓的时候我把计算截取范围一并做了,这里我选择了鼻尖(鼻梁nose_bridge 的最后一个点)作为脸的中心

face_line = list()#用于记录脸部轮廓
face_point = list()#用于记录图片需要截取的范围
face = list()#用于记录脸

for face_landmarks in face_landmarks_list:

#找出每张脸的轮廓用于生成掩膜
    chin = face_landmarks['chin']
    left_eyebrow = face_landmarks['left_eyebrow']
    right_eyebrow = face_landmarks['right_eyebrow']
    nose_bridge = face_landmarks['nose_bridge']
    chin.reverse()
    list_all = left_eyebrow + right_eyebrow + chin + [left_eyebrow[0]]
    face_line.append(list_all)

#找到每张脸最左端点,最右端点,最高点,最低点以及中心,用于最大限度截取表情
    face_five_point = {'centre': nose_bridge[len(nose_bridge)-1],
                       'top': the_top(left_eyebrow + right_eyebrow)[0],
                       'bottom': the_bottom(chin)[0],
                       'left': the_left(chin)[0],
                       'right': the_right(chin)[0]
                       }
    start, end = square(face_five_point)
    face_point.append((start[0], start[1], end[0], end[1]))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
这时候你就会发现,如果我们将表情二值化之前把表情截取下来的话处理的python处理速度会提上去,这是因为需要处理的图片的范围小了。同时也不需要在做很多次膨胀腐蚀了,因为膨胀腐蚀的目的就是为了消除噪声,而提前截取了表情后,噪声的影响也就不太难以忍受了。 
这里为了保证表情包的效果,我添加了一个锐化图像的函数

#锐化函数
def custom_blur_demo(image):
    kernel1 = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]], np.float32) 
    dst = cv2.filter2D(image, -1, kernel=kernel1)
    return dst
1
2
3
4
5
这里放一下效果图。(掩膜和遮挡操作过后会有大片空白,可能会造成阅读不太方便,先道个歉) 
原图(用了基友的表情这次就不打码了,用这个图是因为这图里面有两个脸可以被识别,这样刚好用来做批量生产表情包)

然后是掩膜和掩膜遮挡原图得到的图(这两张图做成GIF超级有趣)

接着就是二值化,让表情变成黑白

这里就是记录图片需要截取的范围的作用了,把脸直接粗暴地截下来 
第一张 
 
第二张 
 
最后就是把表情和熊猫头的合成 
 
 
至此,用人脸识别抓取人脸然后做成表情包的第一阶段的优化就做完了,基本上实现了自动化获取表情并生成表情包的功能。现在如果想拿很多丑照批量生产表情包应该是没问题的。但是感觉图片处理得还是不太够,锐化处理也帮不了太多忙,以后再说吧,虽然《clean code》说的是“ Later equals never.”
--------------------- 
作者:QuantumEntanglement 
来源:CSDN 
原文:https://blog.csdn.net/QuantumEntanglement/article/details/81639755 
版权声明:本文为博主原创文章,转载请附上博文链接!

python实现人脸识别抓取人脸并做成熊猫头表情包(2)之优化相关推荐

  1. python实现人脸识别抓取人脸并做成熊猫头表情包

    前几天在浏览器上看到推送的文章用人脸识别做表情包.当时并不为意,没过多久就想弄一下了.无奈浏览器开了无痕找不着历史记录,上网搜也搜不到.CSDN里有过半都是简单地把两张图拼一起(你别说,经过我这么一找 ...

  2. Python:恶搞,将你朋友照片做成熊猫人表情包

    本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理 以下文章来源于腾讯云 作者:龙哥 ( 想要学习Python?Python学习交流群 ...

  3. 【CV\utils】计算机视觉:视频图像(清洗、裁剪、人脸区域抓取等)数据预处理数据集制作 | 代码合集

    [start:2023.06.15] 文章目录 1. FFmpeg 1.1. 下载 1.2. 万能观影 1.3. 拷贝视频 1.4. 裁剪视频 1.5. 横向拼接视频 2. OpenCV 2.1. 安 ...

  4. python人脸识别算法_python人脸算法

    广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! 若图片中包含多张人脸,只选取其中人脸面积最大的人脸. 支持png.jpg.jpe ...

  5. 人脸识别 “抓” 错了人,他在监狱呆了 10 天

    关注.星标公众号,直达精彩内容 来自量子位 就很离谱. 我,什么都没做,就莫名其妙被警察关了 10 天?! 这是发生在美国新泽西州的一段真实故事. 一个酒店偷窃案件,嫌疑人驾车逃逸. 警察没有验指纹. ...

  6. 人脸识别“抓”错了人,他在监狱呆了10天

    本文转载自 量子位,作者 杨净,边策 就很离谱. 我,什么都没做,就莫名其妙被警察关了10天?! 这是发生在美国新泽西州的一段真实故事. 一个酒店偷窃案件,嫌疑人驾车逃逸. 警察没有验指纹.没测DNA ...

  7. 人脸识别“抓”错了人,他在监狱呆了 10 天

    往期热门文章: 1.这四种情况下,才是考虑分库分表的时候! 2.求求你别再用offset和limit分页了 3.浅谈用不好缓存的几个受伤场景! 4.高并发下接口幂等性解决方案 5.给代码写注释时有哪些 ...

  8. 人脸识别“抓”错了人!他在监狱呆了10天

    点击上方"CVer",选择加"星标"置顶 重磅干货,第一时间送达 杨净 边策 发自 凹非寺 来源:量子位(QbitAI) 就很离谱. 我,什么都没做,就莫名其妙 ...

  9. python人脸识别对比_python 人脸对比--百度API人脸相似度识别(超简单)

    说明:这篇是写使用百度人脸识别API进行人脸相似度识别对比,如 给两个人物照片,判断是否是同一个人.简单的4步完成. 1,获取百度人脸识别API的API Key和Secret Key.(10分钟内完成 ...

最新文章

  1. Intent四个重要属性
  2. 什么是集成测试?非渐增式和渐增式有什么区别
  3. c#FileStream文件读写(转)
  4. 深入浅出Spring Boot,你和大神的差距,就只有这份文档的距离
  5. java程序设计复习题_java程序设计复习大全(100题及答案).doc
  6. jmeter正则表达式提取器多模块相互调用
  7. SQL:给查询添加一个合计行
  8. 对口高考计算机vf试题,计算机对口升学模拟答案.doc
  9. ruby array_Ruby中带有示例的Array.shuffle方法
  10. 【计算机网络】关键词汇翻译整合
  11. 接口规范 7. 按需录制相关接口
  12. guice依赖注入原理_Google Guice依赖注入示例教程
  13. 在线教育与计算机网络的融合发展,[浅谈线上教育和线下教育的融合]
  14. SQL面试题:删除表中指定字段的重复数据,只保留最大的id数据
  15. bios sgx需要开启吗_惠普HP笔记本预装win8改装成win7系统BIOS设置与安装方法
  16. JVMTM Tool Interface:JVM源码分析之javaagent原理完全解读
  17. 华硕启动vmware 虚拟机,显示Intel VT-x但Intel VT-x处于禁用状态 ,开始vt
  18. Oracle loap函数,oracle loap函数用法
  19. java正则在线转换_java正则表达式(转)
  20. 电影《在云端》经典对白翻译

热门文章

  1. python 空数组_从零开始学python之numpy
  2. c语言笔试面试大全,C语言笔试面试题大全.doc
  3. 静态页面和动态页面的区别
  4. vue从创建到完整的饿了么(12)miste.vue
  5. 关于$ORACLE_HOME/bin/oracle文件属性
  6. 正则严格验证身份证信息
  7. Java NIO与IO的区别和比较
  8. 如何解决…has been modified since the precompiled header… was built的问题
  9. FORM 中的颜色 Visual Attribute
  10. java notifier_Java学习笔记---4.Java的分支循环语句