動機

在某一次參訪台中科學園區的機器人自造基地過程中,我看到了門口有一個很特別的裝置,他們架了攝影機還有螢幕,當員工上班時就站在前面,臉部辨識打卡,瞬間科技感爆表。
這讓我想動手實作一個出來看看,順便練習自己實作python專案的能力。

這次我想要做一個可以放在學校校門口的點名系統,因為目前當有訪客進出入時仍是紙本登記,如果可以引入臉部辨識,除了可以讓資料線上化,還可以讓人流控制更方便,校園可以更安全。

過程

結構

我目前會把程式分成三個部分,臉部辨識的演算法,資料庫處理運用,前端介面設計。

臉部辨識的演算法

techable machine

臉部辨識的算法,我查到很多已經現有的套件,首先是google的techable machine,他是一個免費的臉部辨識的工具,不需要寫任何的程式,只要上傳後拖拉方塊,就可以生成結果。而且也有很多API可以直接串接到自己的程式之中。

face_recognition

他是一個在github的開源套件,雖然要寫一點code,但是已經簡化很多不必要的過程,而且還有完整的教學文件。他目前有三個主要功能功能:臉部偵測(face detection),照片臉部辨識(face recognition),即時臉部辨識(real-time face recognition)。
https://github.com/ageitgey/face_recognition/blob/master/README_Simplified_Chinese.md

比較

總結兩個套件都有一個共通點,就是方便上手簡單操作,但是techable machine 就是因為太簡單只能拖拉照片工具之類的,所以沒有太多可以修改模型的地方,當然的也不能客製化許多的東西。所以我還是會選擇face_recgonition當作我這次的主要的工具。

實作

1. 建置環境
我認為建置環境是做專案最難的地方,你會遇到很多雜七雜八的問題,版本不符,硬體不支持等等。
因為我是用windows 系統,我在按照官方教程安裝opencv和dlib套件,結果一直失敗,因為dlib一直缺東缺西出現紅字。
後來上網搜尋過後才知道,face_recgonition極度不支援windows,但還是有其他方法安裝不完整功能的教程。

windows安裝教程: http://maxlai.cc/2018/08/24/windows-python36-quickly-install-face-recognition/

測試成功!

2. Python 多執行緒 threading
多執行緒是我第一次發現到的技術,寫了一年多的程式,原以為一個文件每次執行只能開啟一個程式,沒想到threading居然可以同時執行多個指令。
因為我想要一個畫面執行Face_recgonition時,還可以再輸入指令截圖目前畫面。
以下這三個程式可以輸入姓名及生日 然後另存。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#capture_picture.py
import cv2
import threading
def thread_job():
cam=cv2.VideoCapture(1)
while(True):
ret,frame=cam.read()
cv2.imshow("video",frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
if cv2.waitKey(1) & 0xFF == ord('x'):
cv2.imwrite('pic1.jpg',frame)
pic1=cv2.imread("pic1.jpg",0)
cv2.imshow("picture",pic1)
cam.release()
cv2.destroyAllWindows()
def main():
added_thread=threading.Thread(target=thread_job)
added_thread.start()
strcmd=input("輸入指令")
print('你輸入的指令為:'+strcmd)
if __name__ == '__main__':
main()
1
2
3
4
5
6
7
8
9
10
# cmd.py
import globals
def run_cmd(str_cmd):
if(str_cmd=='add'):
a=input("請輸入英文名字")
b=input("請輸入生日")
globals.picName=a
globals.Takepic=True
else:
print(str_cmd+' is not command')

3.開始處理臉部辨識
前面已經將自己的照片擷取下來,剩下的就是進行影像辨識。
首先我先分析官網給的範例範例程式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Load a sample picture and learn how to recognize it.
obama_image = face_recognition.load_image_file("obama.jpg")
obama_face_encoding = face_recognition.face_encodings(obama_image)[0]

# Load a second sample picture and learn how to recognize it.
biden_image = face_recognition.load_image_file("biden.jpg")
biden_face_encoding = face_recognition.face_encodings(biden_image)[0]

# Create arrays of known face encodings and their names
known_face_encodings = [
obama_face_encoding,
biden_face_encoding
]
known_face_names = [
"Barack Obama",
"Joe Biden"
]

可以看到它需要做三個步驟地處裡,首先先讀入照片,再將照片經過,編碼,最後處存以編碼過的照片。此處我們看看能不能先把資料放在資料庫裡頭,要用時把資料提取放置陣列中,最後再丟入演算法運算。

資料庫處理運用

在資料庫處理方面我會用到python中的sqlite,因為我第一次接觸這個所以花了一點時間學習如何操作資料庫。
SQLite教程:https://www.youtube.com/watch?v=pd-0G0MigUA
首先我需要把已輸入的資料存入datebase中

1
2
3
4
5
6
def save_file_to_database():
conn =sqlite3.connect('personal_file.db')
c=conn.cursor()
c.execute("INSERT INTO personal_file VALUES(?,?)",(globals.picName,globals.birthday))
conn.commit()
conn.close()

然後做出一個函式提取出資料庫的資料的Function,再把他傳回主函式中。
SQLite資料庫操作簡介:https://nkust.gitbook.io/python/sqlite-liao-cao-zuo-jie
如何從資料庫提取資料:https://hackmd.io/kORlDLMTQtuzWgOX0YKCqA

1
2
3
4
5
6
7
8
def take_data():
conn =sqlite3.connect('personal_file.db')
c=conn.cursor()
c.execute("SELECT * FROM personal_file ")
rows = c.fetchall()
for row in rows:
print(row[0])
conn.close()


測試結果成功!

最後我們結合Face_recgonition的函式吧。

從資料庫呼叫照片信息

預想結果為把兩個陣列丟進去函式裡,函式會把資料庫的值放進陣列之中。

1
2
3
4
5
6
7
8
9
10
11
def take_data_from_database(file_name,file_list_image_encoding,):
conn =sqlite3.connect('personal_file.db')
c=conn.cursor()
c.execute("SELECT * FROM personal_file ")
rows = c.fetchall()
for row in rows:
file_name.append(row[0])
temp_image_read=face_recognition.load_image_file('Database/picture/'+row[0]+'.jpg')
file_list_image_encoding.append(face_recognition.face_encodings(temp_image_read)[0])

conn.close()

測試資料結果

使用到此函式處

執行範例程式。

雖然已經完成影像辨識與資料庫的部分,但我發現了更多的潛在問題,我會在結論出提出討論。


前端介面設計

介面設計我會使用Python Tkinter,以下是草稿圖。

不過因為時間不夠所以後來沒有把作品完成。

結論

影像跑起來卡卡的

上網搜尋結果後發現我好像沒安裝好dlib

重點: 如果想要影像順一點的話,可以Resizing(我已經做過了,但是太小的話,沒辦法辨識出臉部),或者是直接打import dlib,print(dlib.DLIB_USE_CUDA),如果沒有成功輸出的話,代表沒有安裝好dlib(我安裝失敗)

現階段可能難以解決此問題,因為Window版本cmake很難用。

時間不夠

因為自主學習時間一個禮拜只有一節課的時間,所以在開發專案時遠遠不足夠,我還需要花六日的時間去補進度。雖然沒有把作品完成,但我認為透過這次的經驗,可以讓我對於估製作程式的時程有很大的幫助。

資訊安全問題

資策會科技法律研究所應用研究組組長宋佩珊說,人臉辨識屬於個人資料保護法中的「特徵」,跟名字、身分證字號是同個等級,所以有受個資法保障;同時,必須取得當事人同意,正當情況下才可蒐集利用。

從很多報導可以得知,雖然臉部辨識可以節省下每人三十秒的時間,但相反的當事人就必須要被蒐集到更多的資料,所以代表說系統也要必需做好資安的準備。因此我的作品看起來只能當模型使用,如果真的上線,想必會被其他人攻擊的很慘。
所以如果要做好一份完整的專案,除了程式本身,在資訊安全上也要下很多功夫,希望以後可以學一下有關於資安的技術。

參考資料

  1. github face_recognition : https://github.com/ageitgey/face_recognition
  2. google Techable Machine:https://teachablemachine.withgoogle.com/
  3. windows安裝教程: http://maxlai.cc/2018/08/24/windows-python36-quickly-install-face-recognition/
  4. github 範例程式:https://github.com/ageitgey/face_recognition/blob/master/examples/facerec_from_webcam_faster.py
  5. SQLite教程:https://www.youtube.com/watch?v=pd-0G0MigUA
  6. SQLite資料庫操作簡介:https://nkust.gitbook.io/python/sqlite-liao-cao-zuo-jie
  7. 如何從資料庫提取資料:https://hackmd.io/kORlDLMTQtuzWgOX0YKCqA
  8. 【辨臉時代1】校園「靠臉點名」正風行 安全vs監控兩面刃:https://tw.appledaily.com/life/20191001/AXE6S5PPTD37BGE7I3A32CYK6M/
  9. 北市府推北一女人臉辨識點名被罵,注重人權的台灣該不該跨過這條道德線?:https://buzzorange.com/techorange/2018/07/20/facial-recognition-ai-in-taiwans-school-system/
  10. 你也被鎖定了嗎?「人臉辨識」在台灣的人權爭議: https://forum.ettoday.net/news/1588461#ixzz6Ub4xvOIg