# password code - (1/2 update method3 & for lipnet check) ## for lipnet ``` python= # # 一開始開啟時要輸入密碼 # 換密碼 可以敲鍵盤 # 你輸入了幾個字,密碼是幾個字 # 如果是句子的話,錯第幾個字,數字的話就不用 # 屬空格跟數字數, # 一碰到錯的話就跳開,句子的話,從第幾個字就錯 # 輸入阿拉伯數字,儲存的時候轉成字母並無空格。比對的時候也是把空格去掉,只要有92%以上的相似率就給過 #方案們 # 1. 把正確密碼與辨認的句子分割成一個個單字,以單字為單位辨認。 # 優點:可以告訴使用者錯了哪個字 # 缺點:如果辨認出的句字單字斷在錯的地方,後面的單字也會對應錯誤 # 2. 把正確密碼與辨認出的字串個別全部combine成一個字串,一個個字母比對 # 缺點:如果差一個字後面就全錯了 # 優點:可以告訴使用者字數、錯了哪個字,但如果差一個字後面就全錯了 # Ps.可以用在純數字? # 3. 與1.相同變成一個字串,使用python-Levenshtein模組來判定兩個字串整體的相似度。 # 缺點:無法告訴使用者錯了哪個字 # 優點:如果辨識出的句子有空缺還是可以辨識兩個句子的相似度 import time import Levenshtein # import RPi.GPIO as GPIO # LED_PIN = [3] #SWITCH_PIN = [11] # GPIO.setmode(GPIO.BOARD) #GPIO.setup(SWITCH_PIN, GPIO.IN) # GPIO.setup(LED_PIN, GPIO.OUT) password=[] pushbutton=True def setpassword(): #set password if there is older passsword,user need to enter the older one,or user can't change print("setpassword()") a1 = input("please choose what kind of your pasword, 1:numbers 2:letter 3:sentence") if a1=='1': #set the number password ,turn the number to letters print("setpassword:number") s='' number_letter={'1':'one','2':'two','3':'three','4':'four','5':'five','6':'six','7':'seven','8':'eight','9':'nine','0':'zero'} if password == []: x = input("please input your password: ") for i in x: s+=(number_letter[i]+' ') password.append(s) for pas in password: print(pas) print("the type of password is : ") #test print(type(password[0])) else: y=input("please input the older password: ") if password_check1(y,password)!=0: x = input("please input new password: ") password.pop() for i in x: s+=(number_letter[i]+' ') #翻譯成英文單字後連成字串儲存 password.append(s) return 0 elif a1=='2': print("setpassword:letter") s='' if password == []: x = input("please input your password: ") for i in x: s+=(i+' ') #以字串儲存 password.append(s) for pas in password: print(pas) else: x=input("please input the older password: ") if password_check1(x,password)!=0: password.pop() x = input("please input your password: ") for i in x: #以字串儲存 s+=(i+' ') password.append(s) return 0 else: print("Wrong,plese try again") elif a1=='3': print("setpassword:sentence") if password == []: x = input("please input your password: ") password.append(x) #直接儲存輸入字串 for pas in password: print(pas) else: x=input("please input the older password: ") if password_check1(x,password)!=0: password.pop() x = input("please input new password: ") password.append(x) return 0 else: print("Wrong,plese try again") # if password == []: # x = input("please input your password") # password.append(x) # print("the type of password is : ") # print(type(password[0])) # else: # x=input("please input the order password") # for i in range(len(password)): # if x == password[i]: # x1=input("please input the new password") # password.remove(x) # password.append(x1) # return 0 # print("Wrong,plese try again") return 0 def password_check1(test,password): #分割成單字 test1=test.split(' ') password1=password[0].split(' ') print(type(password1)) print(type(test1)) diff=int(len(password1)-len(test1)) print(diff) test1.extend("" for _ in range(diff)) #如果輸入密碼太短把它補成跟原本密碼同樣長度 #test print("test is: ") print(test1) print("password1 is: ") print(password1) wrong=[] for i in range(len(password1)): # print("password[%d] is %s" %(i,password1[i])) # print("test1[%d] is %s" %(i,test1[i])) if test1[i]!=password1[i]: # print(" |%s| != |%s|" %(password1[i],test1[i])) wrong.append(str(i+1)) #把錯第幾個字存起來 if wrong: print("The password is wrong.") print("The lenth you input %d words" %(len(test.split(' ')))) #告訴user輸入了幾個字 print("The password's lenth is %d words" %(len(password1))) #正確密碼幾個字 print("No.{} word is wrong".format(" ".join(wrong))) #錯了第幾個字 # #for i in range(len(wrong)): # print(" ".join(wrong)) # print(" is wrong.") return 0 else: #GPIO.output(LED_PIN[0], GPIO.HIGH) time.sleep(1.5) #delay 1.5 seconds print("The password is right.") return 1 def password_check2(test,password): #組合成一個字串 test1=test.split(' ') s1="" test2=s1.join(test1) print(test2) #test password1=s1.join(password[0].split(' ')) print(password1) #test diff=int(len(password1)-len(test2)) print(diff) if diff<0: bigger=len(test2) password1+="0"*(-diff) else: bigger=len(password1) test2+="0"*diff wrong=[] for i in range(bigger): if test2[i]!=password1[i]: wrong.append(str(i+1)) if wrong: print("The password is wrong.") print("The lenth you input %d words" %(len(s1.join(test1)))) print("The password's lenth is %d words" %(len(s1.join(password[0].split(' '))))) print("No.{} word is wrong".format(" ".join(wrong))) #錯了第幾個字母 return 0 else: #GPIO.output(LED_PIN[0], GPIO.HIGH) time.sleep(1.5) #delay 1.5 seconds print("The password is right,you can enter.") return 1 import Levenshtein def password_check3(test,password): #組合成一個字串 test1=test.split(' ') s1="" test2=s1.join(test1) print("test2 is {}".format(test2)) #print("password is {}".format(password)) #test password1=s1.join(password[0].split(' ')) print("password1 is {}".format(password1)) print("Levenshtein.ratio is {}".format(Levenshtein.ratio(test2,password1))) ratio = Levenshtein.ratio(test2,password1) #計算萊文斯坦比。計算公式為 r = (sum - ldist) / sum, 其中sum是指str1 和 str2 字串的長度總和,ldist是類編輯距離。 if ratio < 0.7: #若相似度不夠則顯示錯誤 print("The password is wrong.") print("The lenth you input %d words" %(len(test2))) print("The password's lenth is %d words" %(len(password1))) print("The Levenshtein ratio is {}".format(ratio)) return 0 else: #GPIO.output(LED_PIN[0], GPIO.HIGH) time.sleep(1.5) #delay 1.5 seconds print("The password is right,you can enter.") return 1 try: while True: print('''\nif you want to set password,enter "1".if you want to enter,push the button''') c= input() print(type(c)) print("c is {}".format(c)) if c=='1': setpassword() if pushbutton: #之後改成 GPIO.input(SWITCH_PIN[0]) == GPIO.HIGH test=input("""please input the password,then you can open the door. """) password_check3(test,password) except KeyboardInterrupt: print("kb") #finally: #GPIO.cleanup() ``` ## method 3 - 前置作業:安裝 python-Levenshtein 模組 ``` pip install python-Levenshtein ``` - function: ```python= import Levenshtein def password_check3(test,password): #組合成一個字串 test1=test.split(' ') s1="" test2=s1.join(test1) print("test2 is {}".format(test2)) #print("password is {}".format(password)) #test password1=s1.join(password[0].split(' ')) print("password1 is {}".format(password1)) print("Levenshtein.ratio is {}".format(Levenshtein.ratio(test2,password1))) ratio = Levenshtein.ratio(test2,password1) #計算萊文斯坦比。計算公式為 r = (sum - ldist) / sum, 其中sum是指str1 和 str2 字串的長度總和,ldist是類編輯距離。 if ratio < 0.8: #若相似度不夠則顯示錯誤,可再視情況調整ratio print("The password is wrong.") print("The lenth you input %d words" %(len(test2))) print("The password's lenth is %d words" %(len(password1))) print("The Levenshtein ratio is {}".format(ratio)) return 0 else: #GPIO.output(LED_PIN[0], GPIO.HIGH) time.sleep(1.5) #delay 1.5 seconds print("The password is right,you can enter.") return 1 ``` - **python-Levenshtein introduction**: - *Levenshtein distance*:萊文斯坦距離,又稱Levenshtein距離,是編輯距離的一種。 指兩個字串之間,由一個轉成另一個所需的最少編輯操作次數。 允許的編輯操作包括將一個字元替換成另一個字元,插入一個字元,刪除一個字元。 - *ratio*:計算萊文斯坦比。計算公式為 r = (sum - ldist) / sum, 其中sum是指str1 和 str2 字串的長度總和,ldist是類編輯距離。這裡的類編輯距離不是2中所說的編輯距離,2中三種操作中每個操作+1,而在此處,刪除、插入依然+1,但是替換+2,這樣ratio(‘a’, ‘c’),sum=2,按2中計算為(2-1)/2 = 0.5,’a’,’c’沒有重合,顯然不合算,但是替換操作+2,就可以解決這個問題。 - reference: https://iter01.com/604993.html ## method1&2 ```python= # coding=utf-8 # input25.avi fps=15 # input26.avi fps=10 # input27.avi fps=5 import cv2 import time import numpy as np #import Levenshtein import RPi.GPIO as GPIO LED_PIN = [3] COUNTER_PIN = 16 GPIO.setmode(GPIO.BOARD) GPIO.setup(COUNTER_PIN, GPIO.IN) password=[] pushbutton=True # 重設密碼:數字 abc 句子 def setpassword(): #set password if there is older passsword,user need to enter the older one,or user can't change print("setpassword()") a1 = input("please choose what kind of your pasword, 1:numbers 2:letter 3:sentence") if a1=='1': #set the number password ,turn the number to letters print("setpassword:number") s='' number_letter={'1':'one','2':'two','3':'three','4':'four','5':'five','6':'six','7':'seven','8':'eight','9':'nine','0':'zero'} if password == []: x = raw_input("please input your password: ") for i in x: s+=(number_letter[i]+' ') password.append(s) for pas in password: print(pas) print("the type of password is : ") #test print(type(password[0])) else: y=input("please input the older password: ") if password_check1(y,password)!=0: x = input("please input new password: ") password.pop() for i in x: s+=(number_letter[i]+' ') #翻譯成英文單字後連成字串儲存 password.append(s) return 0 elif a1=='2': print("setpassword:letter") s='' if password == []: x = input("please input your password: ") for i in x: s+=(i+' ') #以字串儲存 password.append(s) for pas in password: print(pas) else: x=input("please input the older password: ") if password_check1(x,password)!=0: password.pop() x = input("please input your password: ") for i in x: #以字串儲存 s+=(i+' ') password.append(s) return 0 else: print("Wrong,plese try again") elif a1=='3': print("setpassword:sentence") if password == []: x = input("please input your password: ") password.append(x) #直接儲存輸入字串 for pas in password: print(pas) else: x=input("please input the older password: ") if password_check1(x,password)!=0: password.pop() x = input("please input new password: ") password.append(x) return 0 else: print("Wrong,plese try again") return 0 def password_check1(test,password): #分割成單字 test1=test.split(' ') password1=password[0].split(' ') print(type(password1)) print(type(test1)) diff=int(len(password1)-len(test1)) print(diff) test1.extend("" for _ in range(diff)) #如果輸入密碼太短把它補成跟原本密碼同樣長度 #test print("test is: ") print(test1) print("password1 is: ") print(password1) wrong=[] for i in range(len(password1)): # print("password[%d] is %s" %(i,password1[i])) # print("test1[%d] is %s" %(i,test1[i])) if test1[i]!=password1[i]: # print(" |%s| != |%s|" %(password1[i],test1[i])) wrong.append(str(i+1)) #把錯第幾個字存起來 if wrong: print("The password is wrong.") print("The lenth you input %d words" %(len(test.split(' ')))) #告訴user輸入了幾個字 print("The password's lenth is %d words" %(len(password1))) #正確密碼幾個字 print("No.{} word is wrong".format(" ".join(wrong))) #錯了第幾個字 bottom = False return bottom # return 0 else: #GPIO.output(LED_PIN[0], GPIO.HIGH) time.sleep(1.5) #delay 1.5 seconds print("The password is right.") bottom = False return bottom # return 1 def password_check2(test,password): #組合成一個字串 test1=test.split(' ') s1="" test2=s1.join(test1) print(test2) #test password1=s1.join(password[0].split(' ')) print(password1) #test diff=int(len(password1)-len(test2)) print(diff) if diff<0: bigger=len(test2) password1+="0"*(-diff) else: bigger=len(password1) test2+="0"*diff wrong=[] for i in range(bigger): if test2[i]!=password1[i]: wrong.append(str(i+1)) if wrong: print("The password is wrong.") print("The lenth you input %d words" %(len(s1.join(test1)))) print("The password's lenth is %d words" %(len(s1.join(password[0].split(' '))))) print("No.{} word is wrong".format(" ".join(wrong))) #錯了第幾個字母 return 0 else: #GPIO.output(LED_PIN[0], GPIO.HIGH) time.sleep(1.5) #delay 1.5 seconds print("The password is right,you can enter.") return 1 def detector(filename): face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') img = cv2.imread(filename) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale(gray,1.1,4) if len(faces) == 0: detect = False else: detect = True return detect def camerarecording(): # 读取设备,picamera跟webcam分別對應0跟1 cap = cv2.VideoCapture(0) # 读取摄像头FPS cap.set(cv2.CAP_PROP_FPS, 25) # set dimensions 设置分辨率 # cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640) # cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480) fourcc = cv2.VideoWriter_fourcc(*'XVID') print('get the bottom sign && start recording!') out = cv2.VideoWriter('input47(2525).avi', fourcc, 25, (100, 50)) while cap.isOpened(): ret, frame = cap.read() out.write(frame) cv2.imwrite('image.jpg', frame) detect = detector('image.jpg') print('decting') if detect != True: bottom = False content.append(bottom) print('no faces, stop recording!') out.release() cap.release() break try: content = [False] bottom = False while True: if GPIO.input(COUNTER_PIN) == GPIO.HIGH: print('''\nif you want to set password,enter "1".if you want to enter,push the button''') c=input() if c=='1': setpassword() bottom = True content.append(bottom) if content[-1] == True: bottom = False # 等待下一次按按鈕 camerarecording() # 轉檔 、丟入資料夾 # model inference # 密碼確認 password_check1(test,password) #test接inference result except KeyboardInterrupt: print('interrupt') finally: cv2.destroyAllWindows() # todo task # (1) 自動轉成.mpg # (2) 丟入modle inference # (3) output 比對 # (4) correct or back to the top ```