python人臉識別


需要掌握知識python,opencv和機器學習一類的基礎

過一段時間代碼上傳github,本人菜j一個,雖然是我自己寫的,也有好多不懂,或者我這就是錯誤方向

鏈接:https://pan.baidu.com/s/15IK5RWrRAr_wNLFreuK7VQ 提取碼:ykkn

人臉識別的步驟:
人臉檢測
    haar人臉檢測,
    lbp人臉檢測
特征處理
    圖片大小尺寸統一
    彩色灰度轉換
    圖片編成一維矩陣
特征提取處理
    歸一化
    特征選擇-刪除低方差的特征
    分析進行特征降維
    訓練集與測試集以一定比例數據分割
預測與訓練
    朴素貝葉斯算法的預測
    決策樹進行預測
    K-近鄰預測    
    得出准確率

程序運行:自己安裝調用的庫

  

 camera.py 運行會調用筆記本攝像頭,鼠標右擊會保存攝像頭檢測的人臉,保存到0和1文件夾,但是保存文件的路徑需要自己手改

read_image 會調用保存兩個文件夾采集的人臉數據圖片,test_pre方法讀取的圖片路徑使用自己人臉照片(屬於上面采集兩個人臉之一)

load_face_test.py 是把倆個程序結合出來,再有人臉數據集和haarcascades和lbp(opencv自帶人臉檢測網上可下就是慢,lbp是對比用的,我這里最后沒有使用)

# camera.py 運行會調用筆記本攝像頭,鼠標右擊會保存攝像頭檢測的人臉,保存到0和1文件夾,但是保存文件的路徑需要自己手改
import cv2 as cv import time def zh_cv(string): return string.encode("gbk").decode(errors="ignore") def get_video(): capture =cv.VideoCapture(0)# VideoCapture(0) 開發默認攝像頭,如果你有多個攝像頭可以試試除0之外的其他參數 print("-----打開攝像頭--------") while(capture.isOpened()) : ret, frame=capture.read() if ret ==False : break; # print(frame) cv.flip(frame,1)# 左右變換 # print("---------haar檢測算法----------") face_detect_dome(frame) # face_lbp_dome(frame) # cv.imshow("voide",frame) # cv.imshow(zh_cv("攝像頭"),frame) c=cv.waitKey(50) if c == 27: break; def face_detect_dome(image): num =0 gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY) face_detect=cv.CascadeClassifier("./face_xml/haarcascades/haarcascade_frontalface_alt.xml") #識別出人臉數量 # facerect = face_detect.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=3, minSize=(12, 12)) faces=face_detect.detectMultiScale(gray,1.1,4) for x,y,w,h in faces: num +=1 global f while(f ==True): file_name="1"# 保存文件路徑 img_head = "zheng"# wang20200203211958 image_save = image[y:y+h, x:x+w] # 將當前幀含人臉部分保存為圖片,注意這里存的還是彩色圖片,前面檢測時灰度化是為了降低計算量;這里訪問的是從y位開始到y+h-1位 # print(resize_image(image_save,64,64)) image_save_resize=cv.resize(image_save,(64,64)) gray=cv.cvtColor(image_save_resize,cv.COLOR_BGR2GRAY)# 灰度 print(gray.shape) # cv.imshow("-----",image_save) cv.imwrite('./train_img/%s/%s%s.jpg' %(file_name,img_head,face_time()), gray) show_save =cv.imread('./train_img/%s/%s%s.jpg' %(file_name,img_head,face_time())) cv.imshow(zh_cv("save_%s%s"%(img_head,face_time())),show_save) f=False print("保存圖片","%s%s"%(img_head,face_time())) cv.rectangle(image,(x,y),(x+w,y+h),(0,0,255),2) # 原圖 位置 ,h 顏色 # cv.namedWindow("face lbp",cv.WINDOW_NORMAL) # 顯示當前捕捉到了多少人臉圖片了 font = cv.FONT_HERSHEY_SIMPLEX cv.putText(image, 'num:%d' % (num), (x + 30, y + 30), font, 1, (0, 255, 0), 2) cv.putText(image, 'name:%d' % (num), (x + 30, y -5), font, 1, (255, 0, 0), 2) # cv.namedWindow("face_haar",cv.WINDOW_NORMAL) cv.setMouseCallback('face_haar',img_save) cv.imshow("face_haar",image) def face_lbp_dome(image): gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY) face_detect=cv.CascadeClassifier("./face_xml/lbpcascades/lbpcascade_frontalface.xml") faces=face_detect.detectMultiScale(gray,1.1,4) print("---------lbp----------") for x,y,w,h in faces: cv.rectangle(image,(x,y),(x+w,y+h),(0,0,255),2) # 原圖 位置 w,h 顏色 cv.namedWindow("face_lbp",cv.WINDOW_NORMAL) cv.setMouseCallback('face_lbp',img_save) cv.imshow("face_lbp",image) def img_save(event, x, y, flags, param): global f if event == cv.EVENT_RBUTTONDOWN: f = True print(f) print("---------截取人臉----------") # cv.waitKey(0) def face_time(): # print(time.strftime("%Y%m%d%H%M%S", time.localtime())) n_time =str(time.strftime("%Y%m%d%H%M%S", time.localtime())) return n_time if __name__ == '__main__': f = False get_video()

 

#read_image 會調用保存兩個文件夾采集的人臉數據圖片,test_pre方法讀取的圖片路徑使用自己人臉照片(屬於上面采集兩個人臉之一)
import os
from sklearn.preprocessing import MinMaxScaler, StandardScaler from sklearn.decomposition import PCA import numpy as np from sklearn.model_selection import train_test_split, GridSearchCV from sklearn.preprocessing import StandardScaler from sklearn.naive_bayes import MultinomialNB import cv2 images = [] labels = [] img_list =[] # path_name是當前工作目錄,后面會由os.getcwd()獲得 def read_path(path_name): for dir_item in os.listdir(path_name): # os.listdir() 方法用於返回指定的文件夾包含的文件或文件夾的名字的列表 # 從當前工作目錄尋找訓練集圖片的文件夾 full_path = os.path.abspath(os.path.join(path_name, dir_item)) if os.path.isdir(full_path): # 如果是文件夾,繼續遞歸調用,去讀取文件夾里的內容 read_path(full_path) else: # 如果是文件了 if dir_item.endswith('.jpg'): image = cv2.imread(full_path) if image is None: # 遇到部分數據有點問題,報錯'NoneType' object has no attribute 'shape' pass else: image_resize=cv2.resize(image,(64,64)) gray=cv2.cvtColor(image_resize,cv2.COLOR_BGR2GRAY)# 灰度 weight,height = gray.shape # 取reshape后的矩陣的第一維度數據,即所需要的數據列表 img_reshape = gray.reshape(1,weight*height)[0] # print(list(img_reshape)) # 轉換列表添加images image_list=list(img_reshape) images.append(image_list) # global labels labels.append(path_name) # 標注數據,me文件夾下是我,指定為0,其他指定為1,這里的0和1不是logistic regression二分類輸出下的0和1,而是softmax下的多分類的類別 label = np.array(["%s"%"zhaoban" if label.endswith("%d"%0) else "unknow" for label in labels]) # label = np.array([endwith(labels)]) return images,label def mm(img_mm): """ 歸一化處理 :return: NOne """ mm = MinMaxScaler(feature_range=(0,1)) data = mm.fit_transform(img_mm) print(data) print("----------歸一化處理-------------") return data def pca(img_pca): """ 主成分分析進行特征降維 :return: None """ pca = PCA(n_components=0.9) data = pca.fit_transform(img_pca) print("------------主成分分析進行特征降維---------------") # print(data) return data def stand(stand_data): """ 標准化縮放 :return: """ std = StandardScaler() data = std.fit_transform(stand_data) # print(data) return data def naviebayes(data,target): """ 朴素貝葉斯進行文本分類 :return: None,t """ # news = fetch_20newsgroups(subset='all') # 進行數據分割 x_train, x_test, y_train, y_test = train_test_split(data,target, test_size=0.25) mlt = MultinomialNB(alpha=1.0) mlt.fit(x_train, y_train) # print(x_test) # print(test_pre()) y_predict = mlt.predict(test_pre()) print("分類類別為:", y_predict) # # 得出准確率 print("准確率為:", mlt.score(x_test, y_test)) return None def test_pre(): image_test =[] image =cv2.imread("qq.jpg") image_resize=cv2.resize(image,(64,64)) gray=cv2.cvtColor(image_resize,cv2.COLOR_BGR2GRAY)# 灰度 weight,height = gray.shape # 取reshape后的矩陣的第一維度數據,即所需要的數據列表 img_reshape = gray.reshape(1,weight*height)[0] # print(list(img_reshape)) # 轉換列表添加images image_list=list(img_reshape) image_test.append(image_list) return image_test if __name__ == "__main__": # print(read_path("./train_img/")) images ,labels= read_path("./train_img/") # image_mm =mm(images) # image_stand =stand(image_mm) # image_pca=pca(image_mm) print("---------------------------------------") naviebayes(images,labels) print("-----------------")
#load_face_test.py 是把倆個程序結合出來,再有人臉數據集和haarcascades和lbp(opencv自帶人臉檢測網上可下就是慢,lbp是對比用的,我這里最后沒有使用)
import cv2 as cv
import time
import os
from sklearn.preprocessing import MinMaxScaler, StandardScaler
from sklearn.decomposition import PCA
import numpy as np
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.preprocessing import StandardScaler
from sklearn.naive_bayes import MultinomialNB

import cv2
images = []
labels = []
img_list =[]
# path_name是當前工作目錄,后面會由os.getcwd()獲得
def read_path(path_name):
    for dir_item in os.listdir(path_name): # os.listdir() 方法用於返回指定的文件夾包含的文件或文件夾的名字的列表
        # 從當前工作目錄尋找訓練集圖片的文件夾
        full_path = os.path.abspath(os.path.join(path_name, dir_item))
        if os.path.isdir(full_path): # 如果是文件夾,繼續遞歸調用,去讀取文件夾里的內容
            read_path(full_path)
        else: # 如果是文件了
            if dir_item.endswith('.jpg'):
                image = cv2.imread(full_path)
                if image is None: # 遇到部分數據有點問題,報錯'NoneType' object has no attribute 'shape'
                    pass
                else:
                    image_resize=cv2.resize(image,(64,64))
                    gray=cv2.cvtColor(image_resize,cv2.COLOR_BGR2GRAY)# 灰度
                    weight,height = gray.shape
                  # 取reshape后的矩陣的第一維度數據,即所需要的數據列表
                    img_reshape = gray.reshape(1,weight*height)[0]
                    # print(list(img_reshape))
                    #   轉換列表添加images
                    image_list=list(img_reshape)
                    images.append(image_list)
                    # global labels
                    labels.append(path_name)
                    # 標注數據,me文件夾下是我,指定為0,其他指定為1,這里的0和1不是logistic regression二分類輸出下的0和1,而是softmax下的多分類的類別
    # dict ={0:"",1:"long"}
    # for key in range(2):
    #     print(dict[key])
    label = np.array(["%s"%"zheng" if label.endswith("%d"%1)   else "zhaoban" for label in labels])
    # label = np.array(["%s"%dict[i] if label.endswith("%d"%(i for i in range(2))) for label in labels])
    return images,label

def mm(img_mm):
    """
    歸一化處理
    :return: NOne
    """
    mm = MinMaxScaler(feature_range=(0,1))
    data = mm.fit_transform(img_mm)
    print(data)
    print("----------歸一化處理-------------")
    return data
def pca(img_pca):
    """
    主成分分析進行特征降維
    :return: None
    """
    pca = PCA(n_components=0.9)
    data = pca.fit_transform(img_pca)
    print("------------主成分分析進行特征降維---------------")
    # print(data)
    return data
def stand(stand_data):
    """
    標准化縮放
    :return:
    """
    std = StandardScaler()
    data = std.fit_transform(stand_data)
    # print(data)
    return data
def naviebayes(data,target,test_img):
    """
    朴素貝葉斯進行文本分類
    :return: None,t
    """
    # news = fetch_20newsgroups(subset='all')
    # 進行數據分割
    x_train, x_test, y_train, y_test = train_test_split(data,target, test_size=0.25)

    mlt = MultinomialNB(alpha=1.0)
    mlt.fit(x_train, y_train)
    # print(x_test)
    # print(test_pre())
    y_predict = mlt.predict(test_img)
    print("分類類別為:", y_predict)
    # # 得出准確率
    print("准確率為:", mlt.score(x_test, y_test))
    return y_predict,mlt.score(x_test, y_test)
def test_pre(gray):
    image_test =[]
    weight,height = gray.shape
  # 取reshape后的矩陣的第一維度數據,即所需要的數據列表
    img_reshape = gray.reshape(1,weight*height)[0]
    # print(list(img_reshape))
    #   轉換列表添加images
    image_list=list(img_reshape)
    image_test.append(image_list)
    return image_test

def zh_cv(string):
    return  string.encode("gbk").decode(errors="ignore")
def get_video():
    capture =cv.VideoCapture(0)# VideoCapture(0) 開發默認攝像頭,如果你有多個攝像頭可以試試除0之外的其他參數
    print("-----打開攝像頭--------")
    while(capture.isOpened()) :
        ret, frame=capture.read()
        if ret ==False :

            break;
        # print(frame)
        cv.flip(frame,1)# 左右變換
        # print("---------haar檢測算法----------")
        face_detect_dome(frame)

        # face_lbp_dome(frame)
        # cv.imshow("voide",frame)
        # cv.imshow(zh_cv("攝像頭"),frame)
        c=cv.waitKey(50)
        if c == 27:
            break;

def face_detect_dome(image):
    num =0
    gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY)
    face_detect=cv.CascadeClassifier("./face_xml/haarcascades/haarcascade_frontalface_alt.xml")
    #識別出人臉數量
    # facerect = face_detect.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=3, minSize=(12, 12))
    faces=face_detect.detectMultiScale(gray,1.1,4)
    for x,y,w,h in faces:
        num +=1
        image_save = image[y:y+h, x:x+w] # 將當前幀含人臉部分保存為圖片,注意這里存的還是彩色圖片,前面檢測時灰度化是為了降低計算量;這里訪問的是從y位開始到y+h-1位++
        # print(resize_image(image_save,64,64))
        image_save_resize=cv.resize(image_save,(64,64))
        gray=cv.cvtColor(image_save_resize,cv.COLOR_BGR2GRAY)# 灰度
        predict,score =naviebayes(images,labels,test_pre(gray))
        print(score)
        global f
        # while(f ==True):
        #     file_name="0"
        #     img_head = "wang"#  wang20200203211958
        #     print(gray.shape)
        #     cv.imwrite('./train_img/%s/%s%s.jpg' %(file_name,img_head,face_time()), gray)
        #     show_save =cv.imread('./train_img/%s/%s%s.jpg' %(file_name,img_head,face_time()))
        #     cv.imshow(zh_cv("save_%s%s"%(img_head,face_time())),show_save)
        #     f=False
        #     print("保存圖片","%s%s"%(img_head,face_time()))

            # image_test =cv.imread('./train_img/%s/%s%s.jpg' %(file_name,img_head,face_time()))

            # cv.imshow("-----",image_save)
        cv.rectangle(image,(x,y),(x+w,y+h),(0,0,255),2)
        #          原圖         位置  ,h         顏色
        # cv.namedWindow("face lbp",cv.WINDOW_NORMAL)

        # 顯示當前捕捉到了多少人臉圖片了
        font = cv.FONT_HERSHEY_SIMPLEX
        cv.putText(image, 'num:%d' % (num), (x + 30, y + 30), font, 1, (0, 255, 0), 2)
        cv.putText(image, 'name:%s precision:%3.2f %%' % (predict[0],score*100),(x -15, y -5), font, 0.8, (25, 0, 185), 2)
        #cv.namedWindow("face_haar",cv.WINDOW_NORMAL)
        cv.setMouseCallback('face_haar',img_save)
        cv.imshow("face_haar",image)

def face_lbp_dome(image):
    gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY)
    face_detect=cv.CascadeClassifier("./face_xml/lbpcascades/lbpcascade_frontalface.xml")
    faces=face_detect.detectMultiScale(gray,1.1,4)
    print("---------lbp----------")
    for x,y,w,h in faces:
        cv.rectangle(image,(x,y),(x+w,y+h),(0,0,255),2)
        #          原圖         位置  w,h         顏色
        cv.namedWindow("face_lbp",cv.WINDOW_NORMAL)
        cv.setMouseCallback('face_lbp',img_save)
        cv.imshow("face_lbp",image)

def img_save(event, x, y, flags, param):
    global f
    if event == cv.EVENT_RBUTTONDOWN:
        f = True
        print(f)
        print("---------截取人臉----------")
        # cv.waitKey(0)
def face_time():
    # print(time.strftime("%Y%m%d%H%M%S", time.localtime()))
    n_time =str(time.strftime("%Y%m%d%H%M%S", time.localtime()))
    return n_time

if __name__ == '__main__':
    f = False
    images ,labels= read_path("./train_img/")
    get_video()

 

 

 

 


免責聲明!

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



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