人臉識別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):
# SQL插入語句
results = []
cursor.execute(sqlstr)
# 獲取所有記錄列表
results = cursor.fetchall()
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:
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):
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)
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)
def load_faceofdatabase(self):
face_encoding_strs = self.facesql.allFaceData()
except:
return face_names, face_encodings
def load_images_face(self,filepath):
if path.isdir(filepath+filename):
self.load_images_face(filepath+filename+"\\")
file_str = filepath + filename
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):
a=0
for a_face_encoding in face_encoding:
self.facesql.saveFaceData(filename[:-4] + "-" + str(a), encoding_str)
執行結果
人臉識別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)
執行結果