python3 opencv3 實現基本的人臉檢測、識別功能


一言不和,先上碼子(純新手,莫嘲笑)

  1 # encoding: utf-8
  2 #老楊的貓,環境:PYCHARM,python3.6,opencv3
  3 
  4 import cv2,os
  5 import cv2.face as fc  #此處有坑,找不到臉,這樣引用程序可以運行,歡迎大牛指點,CV2和CV3的結構區別沒有搞清楚,應該怎么樣引用才是正確的
  6 import numpy as np
  7 from PIL import Image, ImageDraw, ImageFont  #pip install pillow
  8 
  9 #由於cv2.putText()不支持漢字,把圖像里加入需要顯示的文字,可以為漢字
 10 def cvtopil(img,posion,txt):#圖像數組,文字位置,文字內容
 11     pil_im = Image.fromarray(img)
 12     draw = ImageDraw.Draw(pil_im)
 13     font = ImageFont.truetype("simhei.ttf", 50, encoding="utf-8") # 第一個參數為字體文件路徑,第二個為字體大小
 14     draw.text(posion, txt, (0, 0, 255), font=font)  # 第一個參數為打印的坐標,第二個為打印的文本,第三個為字體顏色,第四個為字體
 15     image=cv2.cvtColor(np.array(pil_im), cv2.COLOR_RGB2BGR) #把圖像數組由RGB轉為CV2處理的BGR格式
 16     return image  #返回處理后圖像文件
 17 #臉部圖像采集模塊。采集臉部圖像,轉為200*200的大小后,存到每個人對應的文件夾下
 18 def dectface():
 19     #OPENCV3 自帶的臉部檢測XML文件
 20     #D:\Downloads...../haarcascade_frontalface_default.xml 文件所在路徑為我的電腦里文件路徑,檢測臉部,可酌情修改
 21     face_cas=cv2.CascadeClassifier('D:\Downloads\opencv-3.3.1-vc14\opencv\sources\data\haarcascades/haarcascade_frontalface_default.xml')
 22     #檢測眼睛,這里用不到
 23     eye_cas=cv2.CascadeClassifier('D:\Downloads\opencv-3.3.1-vc14\opencv\sources\data\haarcascades/haarcascade_eye.xml')
 24     cap=cv2.VideoCapture(0)#打開默認攝像頭
 25     count=0 #初始化計數器,用來生成文件名,如0.pgm,1.pgm,3.pgm.....
 26     
 27     '''
 28     C:\Users\Administrator\.PyCharm2017.2\system\python_stubs\-1184660488\cv2\CascadeClassifier.py
 29 連續讀取攝像頭圖像,檢測到臉部圖像,把臉部圖像以PGM的灰度格式格式保存在當前程序路徑里的 jm1,jm2...文件夾下
 30 采集要求:1光線適中,2臉部正直,3臉部圖像大小以剛剛露出頭發和下頜最佳,控制距離,太遠采集圖像精確度差,太近
 31 沒臉,4有效采集時間5秒左右就夠用了,太多影響運行速度。
 32     '''
 33     while True:
 34         ret,frame=cap.read()#讀取圖像,RET為判斷是否采集到圖像,FRAME為采集到的一幀圖像
 35         #此處最好判斷是否采集到圖像  if ret:do else:err  偷懶了
 36         gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) #轉為灰度圖像,用來判斷臉部用
 37         # 找臉,參數:圖像文件,壓縮率(越小檢測迭代次數越多,越慢,越詳細,此處圖像大,1.3-1.5均可),矩形個數最小值,flags不知道,最小檢測窗口大小,最大檢測窗口大小。返回一個臉部區域,左上角為(0,0)坐標系,起始x,y點,w寬,h高
 38         faces = face_cas.detectMultiScale(gray, 1.3, 5)
 39         #用方框勾畫出臉部位置
 40         for (x, y, w, h) in faces:
 41             img=cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),2) #畫矩形,位置,大小,顏色,通道
 42             #cv2.putText(img,'abc',(x,y-20),cv2.FONT_HERSHEY_SIMPLEX,1,255,2) 不能顯示漢字
 43             frame=cvtopil(img,(x,y-20),"老楊")#測試漢字用,可采集出圖像是灰的,待解決
 44             f=cv2.resize(gray[y:y+h,x:x+w],(200,200)) #從灰度圖中,扣出臉部,設置固定大小像素
 45             #保存到jm1里
 46             cv2.imwrite('F:\pytest\cvtest\detectface\jm1\ %s.pgm'%str(count),f)
 47             count+=1
 48             #眼睛檢測
 49             # eyes=eye_cas.detectMultiScale(f,1.03,5,0,(40,40))
 50             # for (ex,ey,ew,eh) in eyes:
 51             #     cv2.rectangle(img,(ex,ey),(ex+ew,ey+eh),(0,0,255),2)
 52         cv2.imshow("demo",frame) #顯示圖像
 53         # cv2.waitKey(0)
 54         if cv2.waitKey(1) & 0xFF == ord('q'):
 55             break
 56         # camera.release()
 57         # cv2.destroyAllWindows()
 58         
 59 
 60 #讀取樣本文件,並加載到一個列表里,返回值包括2部分,[文件列表,對應標簽],標簽用來對照姓名用。
 61 def read_img(path,sz=None):
 62     pr_img=[] #圖像列表
 63     pr_flg=[] #對應標簽
 64     pr_count=0 #初始化檢測到的人數
 65     for dirname,dirnames,filenames in os.walk(path):#遍歷當前程序目錄我的圖像文件保存在f:盤下
 66         #print(os.walk(path))
 67         #print(dirname,dirnames,filenames)
 68         for subdirname in dirnames: #遍歷程序文件夾下的各個目錄
 69             subject_path=os.path.join(dirname,subdirname)
 70             print(subject_path)
 71             for filename in os.listdir(subject_path): #遍歷文件夾下文件
 72                 print(filename)
 73                 try:
 74                     filepath=os.path.join(subject_path,filename)
 75                     im=cv2.imread(filepath,cv2.IMREAD_GRAYSCALE) #讀取JM文件下PGM文件
 76                     print(filepath)
 77                     #print(im.shape)
 78                     if im.shape!=(200,200): #判斷像素是否200
 79                         im=cv2.resize(im,(200,200))
 80                     pr_img.append(np.asarray(im,dtype=np.uint8)) #添加圖像
 81                     pr_flg.append(pr_count)#添加標簽
 82                 except:
 83                     print("io error")
 84             pr_count+=1 #另一個人的標簽
 85     return [pr_img,pr_flg]
 86 
 87 #學習樣本,比對樣本和實例,根據對應算法返回標簽和系數,依據標簽對照姓名,系數值提現了准確度。
 88 def face_rec():
 89     names=['BAO BAO ','BA BA BA ','Bei Bei','MMMMMMM'] #標簽對應的名字0,baobao,1,bbb,2,beibei....
 90     [x,y]=read_img("f:") #調讀取函數,返回圖像、和標簽列表
 91     y=np.asarray(y,dtype=np.int32) #轉為NUMPY的ARRAY
 92     
 93 #CV自帶的三種算法,現用LBPH算法。此處有坑,坑的我差點放棄,原來叫createLBPHFaceRecognizer,為什么我下載的這模樣
 94     #model=fc.EigenFaceRecognizer_create()
 95     #model = fc.FisherFaceRecognizer_create()
 96     model = fc.LBPHFaceRecognizer_create()
 97     
 98     # 訓練,此處應把訓練結果保存,再用到時直接讀取結果,效率更高,xml?json?pickle?
 99     model.train(np.asarray(x),np.asarray(y))
100     
101     #下面讀取攝像頭圖像,用矩形標識檢測到臉部和訓練后結果比對,打印出對應標簽所對應名字
102     camera=cv2.VideoCapture(0)
103     face_cascade=cv2.CascadeClassifier('D:\Downloads\opencv-3.3.1-vc14\opencv\sources\data\haarcascades/haarcascade_frontalface_default.xml')
104     while True:
105         read,img=camera.read()
106         faces=face_cascade.detectMultiScale(img,1.3,5)
107         for (x,y,w,h) in faces:
108             img=cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
109             gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
110             roi=gray[x:x+w,y:y+h]
111             try:
112                 roi=cv2.resize(roi,(200,200),interpolation=cv2.INTER_LINEAR)
113                 
114                 params=model.predict(roi) #predict()函數做比對,返回一個元祖格式值 (標簽,系數)。系數和算法有關,
115                 # 前2種算法值低於5000不可靠,LBPH低於50可靠,80-90不可靠,高於90純蒙
116                 #此處有文章可做,通過單位時間內檢測到的系數平均值,可以得到更准確結果
117                 print(params)
118                 #打印標簽對應名字,如cvtopil的灰度問題解決,可cvtopil函數替換
119                 cv2.putText(img,names[params[0]],(x,y-20),cv2.FONT_HERSHEY_SIMPLEX,1,255,2)
120             except:
121                 continue
122         cv2.imshow("abc",img)
123         if cv2.waitKey(1) & 0xFF == ord('q'):
124             break
125     cv2.destroyAllWindows()
126 if __name__=='__main__':
127     '''
128     1.先用dectface()采集樣本,注釋掉face_rec(),將采集樣本保存到jm文件夾里,現在每次采集不同人樣本,需要手動建立JM1,JM2.....以后應完善程序流程為,首先判斷是否有此人樣本,如沒有自動建立文件夾並保存該人的樣本。
129     2.采集完成后,注釋dectface(),用face_rec()通過比對得到是誰的結果。
130     3.names=['BAO BAO ','BBBBBBB','Bei Bei','MMMMMMM'] 名字和對應標簽應該存成文件,對應讀取
131     3.真心不會用類啊。。。咋用類實現整個流程呢??
132         4.從學PYTHON到現在也不過一個月時間,基礎很不牢,cv2,CV3從引用到使用的區別搞不清楚呢,懇求大牛各種批評指導啊!!
133     '''
134     #dectface()
135     face_rec()

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM