“人像抠图”案例源码详解 (Python)

seg_gui_meet.py用于人像抠图

  1. 导入基础包作用详解
  2. 构建程序图形化类
  3. 初始化处理函数(人体抠图应用启动时首先被调用)
  4. 程序入口

打开testpose人像姿态检测案例

在VScode中进入代码编辑状态。

导入相关库

'''seg_gui_meet.py用于examples中的人体抠图''''''
导入基础包作用详解
'''
#导入包介绍开始#cvs包是Aid内置的代替cv2的包,基本上cv2支持的函数cvs一样支持,cvs包在X模式下和非X模式下一样执行
#cvs更多详细介绍查看官网文档OpenCVhttps://www.aidlearning.net/showdoc/web/#/5?page_id=45
from cvs import *#NumPy(Numerical Python) 是 Python 语言的一个扩展程序库,
#支持大量的维度数组与矩阵运算,
#此外也针对数组运算提供大量的数学函数库。
#在机器学习算法中大部分都是调用Numpy库来完成基础数值计算的。
import numpy as np# tflite_gpu,GPU加速代码由AID提供,TensorFlow Lite 支持多种硬件加速器。GPU 是设计用来完成高吞吐量的大规模并行工作的。
# 因此,它们非常适合用在包含大量运算符的神经网络上,一些输入张量可以容易的被划分为更小的工作负载且可以同时执行,通常这会导致更低的延迟。
# 在最佳情况下,用 GPU 在实时应用程序上做推理运算已经可以运行的足够快,而这在以前是不可能的
import tflite_gpu
#导入包介绍结束
##############################################################################tflite=tflite_gpu.tflite()
back_img_path=('res/dock_vbig.jpeg','res/taj_vbig.jpg','res/sunset_vbig.jpg','res/test.jpg','res/bg1.jpg','res/bg2.jpg','res/bg3.jpg','res/bg4.jpg')bgnd_mat=cv2.imread('res/dock_vbig.jpeg')
mod=0

构建程序图形化类

'''
MyApp类用于构建程序的图形化
'''
class MyApp(App):#初始化函数,self表示创建实例本身, *args传递可变参数,__init__()的第一个参数永远是selfdef __init__(self, *args):#这是对继承自父类的属性进行初始化。而且是用父类的初始化方法来初始化继承的属性。#也就是说,子类继承了父类的所有属性和方法,父类属性自然会用父类方法来进行初始化。#super() 函数是用于调用父类(超类)的一个方法。#super() 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,#但是如果使用多继承,会涉及到查找顺序(MRO)、重复调用(钻石继承)等种种问题。#MRO 就是类的方法解析顺序表, 其实也就是继承父类方法时的顺序表super(MyApp, self).__init__(*args)def idle(self):#在每次更新循环中idle函数都会被调用self.aidcam.update()def main(self):#创建一个VBox容器,使用垂直方式(还有HBox水平盒子,以及widget)#定义变量main_container,它是整个图形界面的主框架,用于包含其他APP中的控件,相当于容器#gui.VBox这段代码是在手机上画出一个宽度为360px,高度为680px的程序主框架范围。#style是它的样式,margin:0 auto;相当于margin:0 auto 0 auto;即上下是0,左右是自动。#这时main_container中的元素会水平居中main_container = VBox(width=360, height=680, style={'margin':'0px auto'})main_container.css_width = "98%"#添加摄像头控件#OpencvVideoWidget函数是在手机 画一个用于显示调用手机摄像头拍摄图像的框,宽度350px,高度400px,#将它赋值给self.aidcam,aidcam表示摄像头控件。self.aidcam = OpencvVideoWidget(self, width=350, height=400)#设置main_container的宽度为手机屏幕的宽度的98%self.aidcam.css_width = "98%"self.aidcam.style['margin'] = '10px'#给aidcam控件一个标记self.aidcam.identifier="myimage_receiver"main_container.append(self.aidcam)self.lbl = Label('点击图片选择你喜欢的虚拟背景:')main_container.append(self.lbl)#创建一个HBox容器,使用水平方式#定义变量m_container,用于包含图.宽度为360px,高度为130px#style是它的样式,margin:0 auto;相当于margin:0 auto 0 auto;即上下是0,左右是自动。#这时m_container中的元素会水平居中m_container = HBox(width=360, height=130, style={'margin':'0px auto'})m_container.css_width = "98%"self.img11 = Image('/res:'+os.getcwd()+'/'+back_img_path[4], width=80,height=80, margin='10px')#被点击则调用on_img11_clicked方法self.img11.onclick.do(self.on_img11_clicked)m_container.append(self.img11)self.img12 = Image('/res:'+os.getcwd()+'/'+back_img_path[5], width=80,height=80, margin='10px')self.img12.onclick.do(self.on_img12_clicked)m_container.append(self.img12)self.img13 = Image('/res:'+os.getcwd()+'/'+back_img_path[6],width=80, height=80, margin='10px')self.img13.onclick.do(self.on_img13_clicked)m_container.append(self.img13)self.img14 = Image('/res:'+os.getcwd()+'/'+back_img_path[7], width=80,height=80,margin='10px')self.img14.onclick.do(self.on_img14_clicked)m_container.append(self.img14)bottom_container = HBox(width=360, height=130, style={'margin':'0px auto'})bottom_container.css_width = "98%"self.img1 = Image('/res:'+os.getcwd()+'/'+back_img_path[0],  width=80,height=80, margin='10px')self.img1.onclick.do(self.on_img1_clicked)bottom_container.append(self.img1)self.img2 = Image('/res:'+os.getcwd()+'/'+back_img_path[1],  width=80,height=80, margin='10px')self.img2.onclick.do(self.on_img2_clicked)bottom_container.append(self.img2)self.img3 = Image('/res:'+os.getcwd()+'/'+back_img_path[2],  width=80,height=80, margin='10px')self.img3.onclick.do(self.on_img3_clicked)bottom_container.append(self.img3)self.img4 = Image('/res:'+os.getcwd()+'/'+back_img_path[3], height=80, width=80,margin='10px')self.img4.onclick.do(self.on_img4_clicked)bottom_container.append(self.img4)#创建一个HBox容器,使用水平方式#定义变量b_container,用于包含按钮.宽度为360px,高度为100px#style是它的样式,margin:0 auto;相当于margin:0 auto 0 auto;即上下是0,左右是自动。#这时m_container中的元素会水平居中b_container = HBox(width=360, height=100, style={'margin':'0px auto'})b_container.css_width = "98%"#按钮1,'抠图穿越',self.bt1 = Button('抠图穿越', width=100, height=30, margin='10px')#被点击则调用on_button_pressed1方法self.bt1.onclick.do(self.on_button_pressed1)self.bt3 = Button('背景虚化', width=100, height=30, margin='10px')self.bt3.onclick.do(self.on_button_pressed3) #将m_container、bottom_container装入main_containermain_container.append(m_container)main_container.append(bottom_container)#将bt1、bt3装入b_containerb_container.append(self.bt1)b_container.append(self.bt3)#将b_container装入main_containermain_container.append(b_container)return main_container'''各图的受击响应方法'''def on_img1_clicked(self, widget):global bgnd_matbgnd=cv2.imread(back_img_path[0])bgnd_mat=cv2.resize(bgnd,(512, 512))def on_img2_clicked(self, widget):global bgnd_matbgnd=cv2.imread(back_img_path[1])bgnd_mat=cv2.resize(bgnd,(512, 512))def on_img3_clicked(self, widget):global bgnd_matbgnd=cv2.imread(back_img_path[2])       bgnd_mat=cv2.resize(bgnd,(512, 512))def on_img4_clicked(self, widget):global bgnd_matbgnd=cv2.imread(back_img_path[3])       bgnd_mat=cv2.resize(bgnd,(512, 512))   def on_img11_clicked(self, widget):global bgnd_matbgnd=cv2.imread(back_img_path[4])bgnd_mat=cv2.resize(bgnd,(512, 512))def on_img12_clicked(self, widget):global bgnd_matbgnd=cv2.imread(back_img_path[5])bgnd_mat=cv2.resize(bgnd,(512, 512))def on_img13_clicked(self, widget):global bgnd_matbgnd=cv2.imread(back_img_path[6])       bgnd_mat=cv2.resize(bgnd,(512, 512))def on_img14_clicked(self, widget):global bgnd_matbgnd=cv2.imread(back_img_path[7])       bgnd_mat=cv2.resize(bgnd,(512, 512))   '''各按钮的受击响应方法'''#用于切换moddef on_button_pressed1(self, widget):global modmod=0def on_button_pressed3(self, widget):global modmod=2

初始化处理函数(人体抠图应用启动时首先被调用)

'''
用于初始化处理,人体抠图应用启动时首先被调用
'''
def process():#设置自制UIcvs.setCustomUI()#输入图的shape宽高均为512(像素)#深度学习的图片尺寸不用那么大,这里使用512*512w=512h=512input_shape=[w,h]#rgb3通道 1个float是32位也就是4字节,每个数据4个字节#输入数据数量 单位是字节inShape =[1 * w * h *3*4,]#4代表4个字节,outShape就是输出数据的数据量 单位是字节outShape= [1 * w*h*2*4,]#指定人像分割模型路径model_path="res/portrait_segmentation.tflite"#4表示4个线程,0表示gpu,-1表示cpu,1表示NNAPIprint('gpu0:',tflite.NNModel(model_path,inShape,outShape,4,0))# cvs.VideoCapture(1)是调用手机前置摄像头,如果是cvs.VideoCapture(0)就是调用手机后置摄像头。camid=1cap=cvs.VideoCapture(camid)tgt_size=512global bgnd_matbgnd_mat=cv2.resize(bgnd_mat,(tgt_size, tgt_size))fcounts=0fframes=[None,None,None,None]fmax=[0,0,0,0]while True:#循环读取摄像头捕捉到的帧frame=cvs.read()#如果没读取到帧,就进入下一次读取循环,直到读取到帧if frame is None:continue#flip()的作用是使图像进行翻转,cv2.flip(filename, flipcode) #filename:需要操作的图像,flipcode:翻转方式,1水平翻转,0垂直翻转,-1水平垂直翻转#如果是前置摄像头,需要翻转图片,想象照镜子的原理if camid==1:frame=cv2.flip(frame,1)#cv2.resize函数重定义大小img =cv2.resize(frame,(input_shape[0],input_shape[1]))frame=img# cv2.cvtColor(p1,p2) 是颜色空间转换函数,p1是需要转换的图片,p2是转换成何种格式。# cv2.COLOR_BGR2RGB 将BGR格式转换成RGB格式  # cv2.COLOR_BGR2GRAY 将BGR格式转换成灰度图片img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).astype(np.float32)#归一化img = img / 255# 由于fp16的值区间比fp32的值区间小很多,所以在计算过程中很容易出现上溢出(Overflow,>65504 )和下溢出(Underflow,<6x10^-8  )的错误,# 溢出之后就会出现“Nan”的问题# 所以我们选择fp32# 分配内存并传入数据tflite.setTensor_Fp32(img,input_shape[1],input_shape[1])# 启动tensorflow模型,使之开始运行tflite.invoke()#参数0切换tflite模型pred = tflite.getTensor_Fp32(0)pred0=(pred[::2 ]).reshape(w,h)pred1=(pred[1::2]).reshape(w,h)back=((pred0))front=((pred1))mask=front-backmask[mask>0.0]=255mask[mask<=0.0]=0        # out1 = np.invert((back > 0.5) * 255)out2 = np.invert((front > 0.5) * 255)# out1 = np.uint8(out1)out2 = np.uint8(out2)mask=np.uint8(mask)out2=cv2.resize(out2,(256,256))mask = cv2.resize(mask,(256,256))out3 = cv2.ximgproc.jointBilateralFilter(out2, mask, 8, 100, 100)       out3 = cv2.resize(out3,(512,512))# out3=mask.copy()out3=cv2.GaussianBlur(out3,(7,7),1) out3 = out3/255masksmall=cv2.erode(mask, (3,3),iterations=1);out3=cv2.merge([out3,out3,out3])# out3 = (cv2.cvtColor(out3, cv2.COLOR_GRAY2RGB))# out3 = out3/255# dst = frame*out3+(1-out3)*bgnd_mat# frame = cv2.resize(frame,(256,256))# bgnd_mat = cv2.resize(bgnd_mat,(256,256))if mod==0:dst = frame*out3+(1-out3)*bgnd_matelse :blur= cv2.GaussianBlur(frame, (27,27), 15) dst = frame*out3+(1-out3)*blur#显示图像cvs.imshow(dst)#让程序休眠#time.sleep(秒数),其中“秒数”以秒为单位,可以是小数,0.1秒则代表休眠100毫秒。sleep(1)

程序入口

'''
入口
'''
if __name__ == '__main__':#initcv用于初始化initcv(process)startcv(MyApp)
import apkneed
import apkneed
import apkneed

AidLux“人像抠图”案例源码详解 (Python)相关推荐

  1. AidLux “人脸测试”案例源码详解

    "人脸检测"案例源码详解 testface.py用于进行人脸检测 构建APP框架和添加主要控件 人脸关键点识别的方法 打开人脸测试案例 1.在VScode中进入代码编辑状态. 2. ...

  2. AidLux“换脸”案例源码详解 (Python)

    "换脸"案例源码详解 (Python) faceswap_gui.py用于换脸,可与facemovie_gui.py身体互换源码(上一篇文章)对照观看 打开faceswap_gui ...

  3. AidLux“实时头发分割”案例源码详解

    "实时头发分割"案例源码详解 1. 构建APP框架和添加主要控件 2. 头发分割的方法 打开实时头发分割案例 1.在VScode中进入代码编辑状态. 2.代码存在路径在/examp ...

  4. Android开发之GPS测试完整案例源码详解之实时检测GPS的状态

    获取Android系统Location位置服务实例: /*** Get location manager system service** @return LocationManager*/publi ...

  5. 【卷积神经网络CNN 实战案例 GoogleNet 实现手写数字识别 源码详解 深度学习 Pytorch笔记 B站刘二大人 (9.5/10)】

    卷积神经网络CNN 实战案例 GoogleNet 实现手写数字识别 源码详解 深度学习 Pytorch笔记 B站刘二大人 (9.5/10) 在上一章已经完成了卷积神经网络的结构分析,并通过各个模块理解 ...

  6. 李沐d2l《动手学深度学习》第二版——风格迁移源码详解

    本文是对李沐Dive to DL<动手学深度学习>第二版13.12节风格迁移的源码详解,整体由Jupyter+VSCode完成,几乎所有重要代码均给出了注释,一看就懂.需要的同学可以在文末 ...

  7. 【 卷积神经网络CNN 数学原理分析与源码详解 深度学习 Pytorch笔记 B站刘二大人(9/10)】

    卷积神经网络CNN 数学原理分析与源码详解 深度学习 Pytorch笔记 B站刘二大人(9/10) 本章主要进行卷积神经网络的相关数学原理和pytorch的对应模块进行推导分析 代码也是通过demo实 ...

  8. Android AR开发实践之七:OpenGLES相机预览背景绘制源码详解

    Android AR开发实践之七:OpenGLES相机预览背景绘制源码详解 目录 Android AR开发实践之七:OpenGLES相机预览背景绘制源码详解 一.OpenGL ES渲染管线 1.基本处 ...

  9. Tensorflow 2.x(keras)源码详解之第九章:模型训练和预测的三种方法(fittf.GradientTapetrain_steptf.data)

      大家好,我是爱编程的喵喵.双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中.从事机器学习以及相关的前后端开发工作.曾在阿里云.科大讯飞.CCF等比赛获得多次Top名次.现 ...

最新文章

  1. 计算机网络Rip例题,计算机网络技术习题
  2. 数据类型,运算符和表达式03 - 零基础入门学习C语言04
  3. K-Means ++ 和 kmeans 区别
  4. 光磁记录实现数据冷存储
  5. MySQL基础篇(03):系统和自定义函数总结,触发器使用详解
  6. java删除文件夹或文件
  7. 使用原生js发送请求
  8. B2B、B2C、C2C、O2O分别是什么意思?
  9. 工商管理专业知识与实务(初级)【10】
  10. Redis 微博微信场景使用案例
  11. ios uri正则表达式_众果搜的博客
  12. 计算机走进画图世界课件,第一单元走进画图世界.doc
  13. 完美解决select2插件提示信息是英文的问题
  14. C++版-剑指offer 面试题6:重建二叉树(Leetcode105. Construct Binary Tree from Preorder and Inorder Traversal) 解题报告
  15. ActiveMQ 源码学习 2:从 CommandTypes 谈常量接口反模式
  16. 政务服务一网通办云平台及智慧政务大数据资源中心建设方案
  17. 【vue3 Api - watchEffect 的讲解 使用】- 侦听响应式数据执行副作用(effect)函数
  18. 大连理工大学计算机科学与技术考研科目,2021年大连理工大学计算机科学与技术(081200)考研专业目录_硕士研究生考试范围 - 学途吧...
  19. 欧盟边检AI测谎仪上线了,第一天就差点让记者进了小黑屋
  20. 居于ERP的普遍失败,再论企业管理与信息化

热门文章

  1. kaggle简单使用教程(代码查找.下载、项目建立.运行、参加比赛)
  2. 准确率、精确率、召回率、F1-score、TPR、FPR、ROC曲线、AUC
  3. NVIDIA公布2019财年财报,营收大幅下跌,利润腰斩
  4. 国林地板教您史上最全实木地板安装教程(上)
  5. 戴尔Alienware m18r1原厂win11中文系统 带F12 Support Assist OS Recovery恢复功能
  6. Ubuntu ens33网卡无ip
  7. Java—面向对象程序设计
  8. 「图文」教你微信上投票怎样刷票之如何快速微信拉票通过免费微信互投群万人群操作
  9. Python爬虫 selenium抓取企查查招投标
  10. html5表格无缝隙,【前端小白】 问关于用 BootStrap做表格之间缝隙的问题