首頁>Club>
10
回覆列表
  • 1 # 大國師魂系列

    人臉識別mysql資料庫起資料提供參照作用,實現多項參照,精準解析:

    需求描述

    1.將人臉特徵資訊儲存進MySQL資料庫。

    2.呼叫攝像頭識別人臉,將待識別的人物進行識別,並實時地與資料庫中的人臉特徵資訊進行比對,同時判斷出被識別者的身份。

    需求分析

    1、準備

    利用opencv、face_recognition、numpy、pymysql等Python第三方類庫,官方說法是face_recognition的人臉識別準確率高達99.6%。

    2、識別

    利用face_recognition,可以很輕易地得到人臉128維的人臉編碼,並且透過比對函式,就可以得出想要的結果。

    3、編碼

    由於face_recognition的128維的人臉編碼是一個numpy ndarray型別,即矩陣,並不能存進資料庫,要想存進資料庫,必須進行型別轉換

    思路:先將矩陣轉為列表,再將列表裡的每個元素轉為字串,再用字串拼接的方式拼成一個字串,這時就可以把特徵值存進資料庫了。

    4.譯碼

    既然是特徵值的比對,那麼從資料庫取完資料之後,就需要把字串重新轉為矩陣格式。

    思路:先透過字串切割,轉為列表,再對列表裡每個元素轉為浮點型(float),最後再轉為矩陣。

    5.輸出

    常規做法透過人臉識別後想要在影象上輸出被識別者姓名,但是opencv有自己的一套編碼規範,無法輸出中文,如果儲存的是中文,那麼就會出現亂碼的情況。

    中文文字影象顯示解決思路:透過呼叫本地已存在的字型,利用PIL進行格式轉換。


    解決方案

    資料庫設計 

    FaceSQL.py:MySQL資料庫處理相關

    import pymysql

    class FaceSQL:

    def __init__(self):

    self.conn = pymysql.connect(

    # 資料庫的IP地址

    host="xxx.xxx.xxx.xxx",

    # 資料庫使用者名稱稱

    user="******",

    # 資料庫使用者密碼

    password="******",

    # 資料庫名稱

    db="xxx",

    # 資料庫埠名稱

    port=3306,

    # 資料庫的編碼方式 注意是utf8

    charset="utf8"

    )

    def processFaceData(self, sqlstr, args=()):

    print(sqlstr)

    # 使用 cursor() 方法建立一個遊標物件 cursor

    cursor = self.conn.cursor()

    try:

    # 執行sql語句

    cursor.execute(sqlstr, args)

    # 提交到資料庫執行

    self.conn.commit()

    except Exception as e:

    # 如果發生錯誤則回滾並列印錯誤資訊

    self.conn.rollback()

    print(e)

    finally:

    # 關閉遊標

    cursor.close()

    def saveFaceData(self,id,encoding_str):

    self.processFaceData("insert into face(學號,encoding) values(%s,%s)", (id, encoding_str))

    def updateFaceData(self, id, encoding_str):

    self.processFaceData("update face set encoding = %s where 學號 = %s", (encoding_str, id))

    def execute_float_sqlstr(self, sqlstr):

    # 使用 cursor() 方法建立一個遊標物件 cursor

    cursor = self.conn.cursor()

    # SQL插入語句

    results = []

    try:

    # 執行sql語句

    cursor.execute(sqlstr)

    # 獲取所有記錄列表

    results = cursor.fetchall()

    except Exception as e:

    # 如果發生錯誤則回滾並列印錯誤資訊

    self.conn.rollback()

    print(e)

    finally:

    # 關閉遊標

    cursor.close()

    return results

    def sreachFaceData(self, id):

    return self.execute_float_sqlstr( "select * from face where 學號="+id)

    def allFaceData(self):

    return self.execute_float_sqlstr( "select * from face ")

    def sreach_Info(self,id):

    return self.execute_float_sqlstr( "select * from zstustu where 學號='" + id + "'")

    FaceTools.py: 人臉特徵資訊處理相關

    import face_recognition

    import numpy

    from os import listdir,path

    from FaceSQL import FaceSQL

    class FaceTools:

    def __init__(self):

    try:

    self.facesql=FaceSQL()

    except :

    print("資料庫連線錯誤")

    def encoding_FaceStr(self, image_face_encoding):

    # 將numpy array型別轉化為列表

    encoding__array_list = image_face_encoding.tolist()

    # 將列表裡的元素轉化為字串

    encoding_str_list = [str(i) for i in encoding__array_list]

    # 拼接列表裡的字串

    encoding_str = ','.join(encoding_str_list)

    return encoding_str

    def decoding_FaceStr(self, encoding_str):

    # print("name=%s,encoding=%s" % (name, encoding))

    # 將字串轉為numpy ndarray型別,即矩陣

    # 轉換成一個list

    dlist = encoding_str.strip(' ').split(',')

    # 將list中str轉換為float

    dfloat = list(map(float, dlist))

    face_encoding = numpy.array(dfloat)

    return face_encoding

    def add_Face(self,image_name, id):

    # 載入本地影象檔案到一個numpy ndarray型別的物件上

    image = face_recognition.load_image_file("./photo/"+image_name)

    # 返回影象中每個面的128維人臉編碼

    # 影象中可能存在多張人臉,取下標為0的人臉編碼,表示識別出來的最清晰的人臉

    image_face_encoding = face_recognition.face_encodings(image)[0]

    encoding_str =self.encoding_FaceStr(image_face_encoding)

    # 將人臉特徵編碼存進資料庫

    self.facesql.saveFaceData(id,encoding_str)

    def updata_Face(self, image_name, id):

    # 載入本地影象檔案到一個numpy ndarray型別的物件上

    image = face_recognition.load_image_file("./photo/"+image_name)

    # 返回影象中每個面的128維人臉編碼

    # 影象中可能存在多張人臉,取下標為0的人臉編碼,表示識別出來的最清晰的人臉

    image_face_encoding = face_recognition.face_encodings(image)[0]

    encoding_str = self.encoding_FaceStr(image_face_encoding)

    # 將人臉特徵編碼更新資料庫

    self.facesql.updateFaceData(id, encoding_str)

    def sreach_Face(self, id):

    face_encoding_strs = self.facesql.sreachFaceData(id)

    # 人臉特徵編碼集合

    face_encodings = []

    # 人臉特徵姓名集合

    face_names = []

    for row in face_encoding_strs:

    name = row[0]

    face_encoding_str = row[1]

    # 將從資料庫獲取出來的資訊追加到集合中

    face_encodings.append(self.decoding_FaceStr(face_encoding_str))

    face_names.append(name)

    return face_names,face_encodings

    def load_faceoffile(self):

    filepath = 'photo'

    filename_list = listdir(filepath)

    # 人臉特徵編碼集合

    face_encodings = []

    # 人臉特徵姓名集合

    face_names = []

    a = 0

    for filename in filename_list: # 依次讀入列表中的內容

    a += 1

    if filename.endswith('jpg'): # 字尾名'jpg'匹對

    face_names.append(filename[:-4]) # 把檔名字的後四位.jpg去掉獲取人名

    file_str = 'photo' + '/' + filename

    a_images = face_recognition.load_image_file(file_str)

    print(file_str)

    a_face_encoding = face_recognition.face_encodings(a_images)[0]

    face_encodings.append(a_face_encoding)

    print(face_names, a)

    return face_names,face_encodings

    def load_faceofdatabase(self):

    try:

    face_encoding_strs = self.facesql.allFaceData()

    except:

    print("資料庫連線錯誤")

    # 人臉特徵編碼集合

    face_encodings = []

    # 人臉特徵姓名集合

    face_names = []

    for row in face_encoding_strs:

    name = row[0]

    face_encoding_str = row[1]

    # 將從資料庫獲取出來的資訊追加到集合中

    face_encodings.append(self.decoding_FaceStr(face_encoding_str))

    face_names.append(name)

    return face_names, face_encodings

    def load_images_face(self,filepath):

    filename_list = listdir(filepath)

    for filename in filename_list: # 依次讀入列表中的內容

    if path.isdir(filepath+filename):

    self.load_images_face(filepath+filename+"\\")

    if filename.endswith('jpg'): # 字尾名'jpg'匹對

    file_str = filepath + filename

    a_images = face_recognition.load_image_file(file_str)

    print(file_str)

    face_encoding = face_recognition.face_encodings(a_images)

    if face_encoding != []:

    a_face_encoding = face_encoding[0]

    encoding_str = self.encoding_FaceStr(a_face_encoding)

    self.facesql.saveFaceData(filename[:-4], encoding_str)

    def load_images_faces(self, filepath):

    filename_list = listdir(filepath)

    a=0

    for filename in filename_list: # 依次讀入列表中的內容

    if filename.endswith('jpg'): # 字尾名'jpg'匹對

    file_str = filepath + filename

    a_images = face_recognition.load_image_file(file_str)

    print(file_str)

    face_encoding = face_recognition.face_encodings(a_images)

    for a_face_encoding in face_encoding:

    a += 1

    encoding_str = self.encoding_FaceStr(a_face_encoding)

    self.facesql.saveFaceData(filename[:-4] + "-" + str(a), encoding_str)

    執行結果

  • 中秋節和大豐收的關聯?
  • 介紹,尼克服?