owned this note
owned this note
Published
Linked with GitHub
# Face_recognition Attendence List 臉部辨識點名系統
###### tags: `Side projects`
## **序**
在某一次的練習賽中,我來到中科機器人自造基地。
我看到了門口有一個很特別的裝置,他們架了攝影機還有螢幕,當員工上班時就站在前面,臉部辨識打卡,瞬間科技感爆表。所以想說趁這個機會,自己做出差不多的程式,順便練習python專案

圖為中科機器人自造基地
## 建置環境
我認為建置環境是做專案最難的地方,你會遇到很多很鳥的問題,版本不符,硬體不支持等等。
花在弄環境的時間遠大於寫程式Debug的時間。
## ANACONDA 學習
建置環境 `conda create --name FaceRecgnition python=3.6` 注意只能安 3.6

檢查是否 以建置環境

啟動環境

安裝Dlib(Face_recgnition要用的library)
首先要到此網站下載檔案[(dlib-19.8.1-cp36-cp36m-win_amd64.whl)](https://pypi.org/simple/dlib/)
`pip install dlib-19.8.1-cp36-cp36m-win_amd64.whl`
安裝 opencv (包含 main & contrib module)
`pip install opencv-contrib-python`
安裝 face_recognition
`pip install face_recognition`
打開Anaconda Navigator

更改已安裝好環境

打開vscode

測試成功!

### 擷取圖像
``` python=
import cv2
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()
```

### 建立sqldatabase
### 多線執行
[莫凡教學](https://www.youtube.com/watch?v=EeoFahm8FOE&list=PLXO45tsB95cKaHtKLn-jat8SOGndS3MEt&index=2)
#### 可以同時運行畫面及輸入輸出
``` python=
import cv2
#import sql_lite_demo
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()
```
### 不同檔案程式間呼叫變數
[教學網站](https://medium.com/@kweisamx0322/python-%E6%80%8E%E9%BA%BC%E5%9C%A8%E5%85%A9%E5%80%8B%E6%AA%94%E6%A1%88%E4%B9%8B%E9%96%93%E5%88%86%E4%BA%AB%E5%85%A8%E5%9F%9F%E8%AE%8A%E6%95%B8-8fced72f3550)
以下這三個程式可以輸入姓名及生日 然後另存
照片
```python=
#capture_picture.py
import cv2
import threading
import cmd
import globals
def video_show():
cam=cv2.VideoCapture(1)
while(True):
ret,frame=cam.read()
cv2.imshow("video",frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
#print(globals.Takepic)
if globals.Takepic:
print(globals.picName)
cv2.imwrite(globals.picName+'.jpg',frame)
pic=cv2.imread(globals.picName+'.jpg',1)
cv2.imshow("picture",pic)
globals.Takepic=False
cam.release()
cv2.destroyAllWindows()
def main():
globals.initialize()
added_thread=threading.Thread(target=video_show)
added_thread.start()
strcmd=input("輸入指令: ")
cmd.run_cmd(strcmd)
if __name__ == '__main__':
main()
```
```python=
# 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')
```
```python=
#globals.py
def initialize():
global Takepic,picName
Takepic=False
picName='null'
```
### 建立資料庫
這次我第一次使用Python的database,所以我速刷了這一部影片
https://www.youtube.com/watch?v=pd-0G0MigUA
首先我需要把已輸入的資料存入datebase中
```python=
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()
```
然後在剛影像辨識處呼叫檔案中全部的資料 [參考資料1](https://stackoverflow.com/questions/52815376/how-to-fetch-data-from-sqlite-using-python) [參考資料2](https://nkust.gitbook.io/python/sqlite-liao-cao-zuo-jie)
```python=
c.execute("SELECT * FROM personal_file ")
rows = c.fetchall()
for row in rows:
print(row[0])//拿第一個資料
```
我在製作出完整的函式
```python=
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()
```

測試結果成功。
最後把這函式放在儲存完照片後,執行。
## 開始處理臉部辨識
首先我們先分析範例程式 [範例程式](https://github.com/ageitgey/face_recognition/blob/master/examples/facerec_from_webcam_faster.py)
```python=
# 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"
]
```
可以看到它需要做三個步驟地處裡,首先先讀入照片,再將照片經過編碼,最後處存以編碼過的照片。此處我們看看能不能使用提取資料庫的方法尋找照片信息。
#### 實驗看看如何在array中增加新元素
https://www.runoob.com/python/att-list-append.html
```python=
arr=['Ben','John','Belly']
arr.insert(len(arr),'Benson') #讀取陣列大小後在最後面加上新元素
#或是用 arr.append('Benson') 後來才發現的
print(arr,len(arr))
```
輸出結果

#### 從資料庫呼叫照片信息
預想結果為把兩個陣列丟進去函式裡,函式會把資料庫的值放進陣列之中。
```python=
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()
```
#### 測試資料結果
使用到此函式處

執行範例程式。

### 影像跑起來卡卡的
上網搜尋結果後發現我好像沒安裝好dlib

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

現階段可能難以解決此問題,因為Window版本cmake很難用。
#### 臉部辨識主要程式
```python=
#********************************************************************************************************
small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25) #縮小原圖 幫助運算更快速
face_locations = face_recognition.face_locations(small_frame)
face_encodings = face_recognition.face_encodings(small_frame, face_locations)
face_names = []
for face_encoding in face_encodings:
matches = face_recognition.compare_faces(known_face_encodings, face_encoding,0.6)
name = "Unknown"
if True in matches:
first_match_index = matches.index(True)
name = known_face_names[first_match_index]
face_names.append(name)
#放上文字
for (top, right, bottom, left), name in zip(face_locations, face_names):
top *= 4
right *= 4
bottom *= 4
left *= 4
cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)
cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED)
font = cv2.FONT_HERSHEY_DUPLEX
cv2.putText(frame, name, (left + 6, bottom - 6), font, 1.0, (255, 255, 255), 1)
#********************************************************************************************************
```
https://blog.gtwang.org/programming/python-iterate-through-multiple-lists-in-parallel/
https://blog.csdn.net/u014291497/article/details/51059686
### 設計UI介面
第一次用Tk