樹莓派人臉識別門禁系統的總體設計
硬體包括:樹莓派3B、電源模組、轉5V降壓模組、觸摸感應感測器模組、聲光報警模組和驅動模組。
由此設計出的人臉識別門禁系統總體結構框圖如下:
總體結構框圖
程式運行時樹莓派會將本地照片中的面部圖像發送至雲端服務進行分析, 識別出的人臉會給出face_token, 用於後續的人臉比對等操作。 觸摸感測器觸發主函數即時拍照並發送至雲服務調用Search API在Faceset中找出與目標人臉最相似的一張或多張人臉。
主流程圖
系統主要功能實現
當觸摸開關被按下LED閃爍, 接著進行一張人臉的採集。 並將此照片與已經上傳的三張照片做對比。
主要模組各自的功能如下:
主控模組。 在本設計中主要起到集中分配的作用, 不僅需要即時採集人臉圖像, 調用API處理圖像, 同時還要提供攝像頭檢測、驅動晶片、顯示幕等數位器件的工作信號。
觸發模組。 系統的輸入部分, 實現人機交互。 通過接收觸控按鍵的電平資訊, 使得樹莓派得到需要的資料。
檢測模組。 對人臉進行採集攝像的模組, 提供最原始的圖片資訊。
驅動模組。 大門開閉的程序控制的控制元件
顯示模組。 以連接一台電腦液晶顯示器即可
系統電源模組。 系統電源模組主要負責給系統提供符合要求的電流與電壓
報警模組。 系統的聲光報警模組, 利用LED燈和蜂鳴器來提示人臉即將檢測的資訊。
主控板的選型
樹莓派3B
觸發模組
觸摸開關模組
檢測模組
樹莓派攝像頭
樹莓派專用500W攝像頭提供了三個應用程式,分別為:raspistill、raspivid、raspistillyuv。其中 raspistill 和 raspistillyuv 非常相似,並且都是用於捕捉圖像,而 raspivid 用於捕捉視頻。
樹莓派上電即開機進入系統。啟動人臉識別檢測程式。程式啟動後觸摸感測器迴圈檢測是否被觸發。檢測週期時2S,當觸摸感應開關被觸發則啟動攝像頭即時拍照。照片存儲到本地之後上傳雲服務處理。之後判斷返回的處理結果是否通過。
搭建opencv環境將在下一個文章詳細介紹,此處跳過。除此之外安裝pycurl.使用apt-get的方式安裝$ sudo apt-get install python-pycurl。
流程圖
到Face++網站https://www.faceplusplus.com.cn/註冊自己的APIkey.
Sdk的facepp.py檔中包含如下底層api介面提供我們使用。
_APIS = [
'/detect',
'/detection/landmark'
'/compare',
'/search',
'/faceset/create',
'/faceset/addface',
'/faceset/removeface',
'/faceset/update',
'/faceset/getdetail',
'/faceset/delete',
'/faceset/getfacesets',
'/face/analyze',
'/face/getdetail',
'/face/setuserid'
]
輸入自己在Face++網站註冊的APIkey。
FACE++的API
Detect API
調用者提供圖片檔或者圖片URL,進行人臉檢測和人臉分析。識別出的人臉會給出face_token,用於後續的人臉比對等操作。請注意,只對人臉包圍盒面積最大的5個人臉進行分析,其他人臉可以使用Face Analyze API進行分析。如果您需要使用檢測出的人臉於後續操作,建議將對應face_token添加到FaceSet中。如果一個face_token連續72小時沒有存放在任意FaceSet中,則該face_token將會失效。如果對同一張圖片進行多次人臉檢測,同一個人臉得到的face_token是不同的。
Search API
在Faceset中找出與目標人臉最相似的一張或多張人臉。支援傳入face_token或者直接傳入圖片進行人臉搜索。使用圖片進行比對時會選取圖片中檢測到人臉尺寸最大的一個人臉。
調用正確的返回值
系統調試及運行
等待對比的照片先存儲在本地 等待代碼中上傳
程式初始設置
首先拍攝的照片上傳到本資料夾並修改圖片檔案名,然後在代碼中將三張待對比照片賦值給face_one、face_two、face_three三個變數。並設置進行對比的照片名為customer.jpg。
face_one = 'face_one.jpg'
face_two = 'face_two.jpg'
face_three = 'face_three.jpg'
face_search = 'customer.jpg'
置GPIO編碼方式為BOARD,GPIO13為輸入模式,GPIO11,12,15,16,40為輸出模式。
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
GPIO.setup(13,GPIO.IN)
GPIO.setup(11,GPIO.OUT)
GPIO.setup(12,GPIO.OUT)
GPIO.setup(15,GPIO.OUT)
GPIO.setup(16,GPIO.OUT)
GPIO.setup(40,GPIO.OUT)
在python程式中設置調用API的key和secret。
#http_url='https://api-cn.faceplusplus.com/facepp/v3/detect'
key = "XXXXXXXXXXXXXXXXXXXX"
secret = "XXXXXXXXXXXXXXXXXXXXXXXX"
api = facepp.API(key, secret)
各功能函數
蜂鳴器,前面已經初始設置GPIO12為輸出模式,此處bee()函數設置GPIO12為高電平,延時0.5s後置為低。意味著當調用bee()函數時蜂鳴器鳴叫0.5s.
def bee():
GPIO.output(12, False)
time.sleep(0.5)
GPIO.output(12, True)
步進電機,設置旋轉角度為180°,closewise=1時,步進電機順時針旋轉,closewise=0時,步進電機逆時針旋轉。步進電機驅動模組由樹莓派的GPIO35、 GPIO36、 GPIO38 、GPIO40四個GPIO驅動。
def motor_open():
steps = 180;
clockwise = 1;
arr = [0,1,2,3];
if clockwise!=1:
arr = [3,2,1,0];
ports = [40,38,36,35] # GPIO 21(Pin 40) GPIO 20(Pin 38) GPIO 16(Pin 36) GPIO 19(Pin 35)
for p in ports:
GPIO.setup(p,GPIO.OUT)
for x in range(0,steps):
for j in arr:
time.sleep(0.002)
for i in range(0,4):
if i == j:
GPIO.output(ports[i],True)
else:
GPIO.output(ports[i],False)
(3)流水燈:初始設置已經將GPIO11、GPIO15、GPIO16為輸出模式。分別把三個LED發光二極體的長引腳接到這三個GPIO上,短引腳接至負極。通過把對應的引腳置為高電平延時0.3s後置為低,迴圈點亮三個小燈。
def light():
GPIO.output(11, True)
time.sleep(0.3)
GPIO.output(11, False)
GPIO.output(15, True)
time.sleep(0.3)
GPIO.output(15, False)
GPIO.output(16, True)
time.sleep(0.3)
GPIO.output(16, False)
系統預熱好,提示做好準備 ,一段時間後進行拍照。在終端視窗輸出提示資訊。並調用light()來實現LED發光二極體的流水燈效果。並調用bee()讓蜂鳴器發出提示聲音。
def prep():
print("歡迎使用人臉識別檢測系統 請面對攝像頭 5秒鐘後進行人臉採集")
light()
print("************************5*********************")
light()
print("************************4*********************")
light()
print("************************3*********************")
light()
print("************************2*********************")
light()
print("************************1*********************")
bee()
調用拍照函數時流水燈點亮,然後使用opencv利用攝像頭採集一張照片,將照片保存為customer.jpg。
def take_photo():
light()
capture = cv2.VideoCapture(0)
if not capture.isOpened(): print('Capture failed because of camera')
ret, img = capture.read()
cv2.imwrite('customer.jpg', img)
print("***********************照片採集完畢 請稍等*************************")
print '=' * 60
函式呼叫API將本機存放區的照片進行人臉檢測和人臉分析。識別出的人臉會給出face_token,用於後續的人臉比對等操作。然後調用searchAPI在Faceset中找出與目標人臉最相似的一張或多張人臉。進行比對時會選取圖片中檢測到人臉尺寸最大的一個人臉。
觸發檢測的監測函數det(),程式運行時開始檢測觸摸開關是否被觸發。當觸摸開關被觸發時會發送高電平信號給樹莓派。當檢測GPIO13為真時,在終端輸出確定資訊,並調用主函數進行對比操作。主程序運行結束後繼續檢測是否被觸發。一直迴圈指導程式退出。
def det():
while True:
if GPIO.input(13)==True:
print "confirm"
main()
else:
print "NO BODY"
time.sleep(2)
det()
提取API.search返回結果,並將返回的資訊保存到s,並從中提取相似度的值。轉換s[0][‘configdence’]為整形變數賦值給m。當m大於70時輸出通過檢測並調用步進電機轉動。
異常處理
目的是刪除無用的人臉庫,所以新建了一個debug.py的python文件。當檢測失敗之後執行一次debug.py即可。
import facepp
#http_url='https://api-cn.faceplusplus.com/facepp/v3/detect'
key = "xzFPqqR1q_fasM1D3s4yvUdcBoTovUMX"
secret = "4GXhLafqDOmnfQRxx-6ZlEVwQpOlZoW-"
api = facepp.API(key, secret)
# 創建一個Faceset用來存儲FaceToken
# create a Faceset to save FaceToken
def main():
api.faceset.delete(outer_id='detect', check_empty=0)
#ret = api.faceset.create(outer_id='detect')
#print_result("faceset create", ret)
main()
樹莓派攝像頭
樹莓派專用500W攝像頭提供了三個應用程式,分別為:raspistill、raspivid、raspistillyuv。其中 raspistill 和 raspistillyuv 非常相似,並且都是用於捕捉圖像,而 raspivid 用於捕捉視頻。
樹莓派上電即開機進入系統。啟動人臉識別檢測程式。程式啟動後觸摸感測器迴圈檢測是否被觸發。檢測週期時2S,當觸摸感應開關被觸發則啟動攝像頭即時拍照。照片存儲到本地之後上傳雲服務處理。之後判斷返回的處理結果是否通過。
搭建opencv環境將在下一個文章詳細介紹,此處跳過。除此之外安裝pycurl.使用apt-get的方式安裝$ sudo apt-get install python-pycurl。
流程圖
到Face++網站https://www.faceplusplus.com.cn/註冊自己的APIkey.
Sdk的facepp.py檔中包含如下底層api介面提供我們使用。
_APIS = [
'/detect',
'/detection/landmark'
'/compare',
'/search',
'/faceset/create',
'/faceset/addface',
'/faceset/removeface',
'/faceset/update',
'/faceset/getdetail',
'/faceset/delete',
'/faceset/getfacesets',
'/face/analyze',
'/face/getdetail',
'/face/setuserid'
]
輸入自己在Face++網站註冊的APIkey。
FACE++的API
Detect API
調用者提供圖片檔或者圖片URL,進行人臉檢測和人臉分析。識別出的人臉會給出face_token,用於後續的人臉比對等操作。請注意,只對人臉包圍盒面積最大的5個人臉進行分析,其他人臉可以使用Face Analyze API進行分析。如果您需要使用檢測出的人臉於後續操作,建議將對應face_token添加到FaceSet中。如果一個face_token連續72小時沒有存放在任意FaceSet中,則該face_token將會失效。如果對同一張圖片進行多次人臉檢測,同一個人臉得到的face_token是不同的。
Search API
在Faceset中找出與目標人臉最相似的一張或多張人臉。支援傳入face_token或者直接傳入圖片進行人臉搜索。使用圖片進行比對時會選取圖片中檢測到人臉尺寸最大的一個人臉。
調用正確的返回值
系統調試及運行
等待對比的照片先存儲在本地 等待代碼中上傳
程式初始設置
首先拍攝的照片上傳到本資料夾並修改圖片檔案名,然後在代碼中將三張待對比照片賦值給face_one、face_two、face_three三個變數。並設置進行對比的照片名為customer.jpg。
face_one = 'face_one.jpg'
face_two = 'face_two.jpg'
face_three = 'face_three.jpg'
face_search = 'customer.jpg'
置GPIO編碼方式為BOARD,GPIO13為輸入模式,GPIO11,12,15,16,40為輸出模式。
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
GPIO.setup(13,GPIO.IN)
GPIO.setup(11,GPIO.OUT)
GPIO.setup(12,GPIO.OUT)
GPIO.setup(15,GPIO.OUT)
GPIO.setup(16,GPIO.OUT)
GPIO.setup(40,GPIO.OUT)
在python程式中設置調用API的key和secret。
#http_url='https://api-cn.faceplusplus.com/facepp/v3/detect'
key = "XXXXXXXXXXXXXXXXXXXX"
secret = "XXXXXXXXXXXXXXXXXXXXXXXX"
api = facepp.API(key, secret)
各功能函數
蜂鳴器,前面已經初始設置GPIO12為輸出模式,此處bee()函數設置GPIO12為高電平,延時0.5s後置為低。意味著當調用bee()函數時蜂鳴器鳴叫0.5s.
def bee():
GPIO.output(12, False)
time.sleep(0.5)
GPIO.output(12, True)
步進電機,設置旋轉角度為180°,closewise=1時,步進電機順時針旋轉,closewise=0時,步進電機逆時針旋轉。步進電機驅動模組由樹莓派的GPIO35、 GPIO36、 GPIO38 、GPIO40四個GPIO驅動。
def motor_open():
steps = 180;
clockwise = 1;
arr = [0,1,2,3];
if clockwise!=1:
arr = [3,2,1,0];
ports = [40,38,36,35] # GPIO 21(Pin 40) GPIO 20(Pin 38) GPIO 16(Pin 36) GPIO 19(Pin 35)
for p in ports:
GPIO.setup(p,GPIO.OUT)
for x in range(0,steps):
for j in arr:
time.sleep(0.002)
for i in range(0,4):
if i == j:
GPIO.output(ports[i],True)
else:
GPIO.output(ports[i],False)
(3)流水燈:初始設置已經將GPIO11、GPIO15、GPIO16為輸出模式。分別把三個LED發光二極體的長引腳接到這三個GPIO上,短引腳接至負極。通過把對應的引腳置為高電平延時0.3s後置為低,迴圈點亮三個小燈。
def light():
GPIO.output(11, True)
time.sleep(0.3)
GPIO.output(11, False)
GPIO.output(15, True)
time.sleep(0.3)
GPIO.output(15, False)
GPIO.output(16, True)
time.sleep(0.3)
GPIO.output(16, False)
系統預熱好,提示做好準備 ,一段時間後進行拍照。在終端視窗輸出提示資訊。並調用light()來實現LED發光二極體的流水燈效果。並調用bee()讓蜂鳴器發出提示聲音。
def prep():
print("歡迎使用人臉識別檢測系統 請面對攝像頭 5秒鐘後進行人臉採集")
light()
print("************************5*********************")
light()
print("************************4*********************")
light()
print("************************3*********************")
light()
print("************************2*********************")
light()
print("************************1*********************")
bee()
調用拍照函數時流水燈點亮,然後使用opencv利用攝像頭採集一張照片,將照片保存為customer.jpg。
def take_photo():
light()
capture = cv2.VideoCapture(0)
if not capture.isOpened(): print('Capture failed because of camera')
ret, img = capture.read()
cv2.imwrite('customer.jpg', img)
print("***********************照片採集完畢 請稍等*************************")
print '=' * 60
函式呼叫API將本機存放區的照片進行人臉檢測和人臉分析。識別出的人臉會給出face_token,用於後續的人臉比對等操作。然後調用searchAPI在Faceset中找出與目標人臉最相似的一張或多張人臉。進行比對時會選取圖片中檢測到人臉尺寸最大的一個人臉。
觸發檢測的監測函數det(),程式運行時開始檢測觸摸開關是否被觸發。當觸摸開關被觸發時會發送高電平信號給樹莓派。當檢測GPIO13為真時,在終端輸出確定資訊,並調用主函數進行對比操作。主程序運行結束後繼續檢測是否被觸發。一直迴圈指導程式退出。
def det():
while True:
if GPIO.input(13)==True:
print "confirm"
main()
else:
print "NO BODY"
time.sleep(2)
det()
提取API.search返回結果,並將返回的資訊保存到s,並從中提取相似度的值。轉換s[0][‘configdence’]為整形變數賦值給m。當m大於70時輸出通過檢測並調用步進電機轉動。
異常處理
目的是刪除無用的人臉庫,所以新建了一個debug.py的python文件。當檢測失敗之後執行一次debug.py即可。
import facepp
#http_url='https://api-cn.faceplusplus.com/facepp/v3/detect'
key = "xzFPqqR1q_fasM1D3s4yvUdcBoTovUMX"
secret = "4GXhLafqDOmnfQRxx-6ZlEVwQpOlZoW-"
api = facepp.API(key, secret)
# 創建一個Faceset用來存儲FaceToken
# create a Faceset to save FaceToken
def main():
api.faceset.delete(outer_id='detect', check_empty=0)
#ret = api.faceset.create(outer_id='detect')
#print_result("faceset create", ret)
main()