AidLux“人像抠图”案例源码详解 (Python)
生活随笔
收集整理的這篇文章主要介紹了
AidLux“人像抠图”案例源码详解 (Python)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
“人像摳圖”案例源碼詳解 (Python)
seg_gui_meet.py用于人像摳圖
打開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)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 水果店开在哪位置最好,水果店应开到什么位
- 下一篇: 打靶归来 - 详解upload-labs