311 lines
9.4 KiB
Python
311 lines
9.4 KiB
Python
|
from __future__ import division
|
||
|
import os, cv2, sys, ctypes, sqlite3
|
||
|
import numpy as np
|
||
|
import pyautogui as pag
|
||
|
import pytesseract as pt
|
||
|
from tkinter import *
|
||
|
from PIL import Image
|
||
|
from tkinter.filedialog import askopenfilename
|
||
|
|
||
|
cascade = cv2.CascadeClassifier('cascades/data/haarcascade_frontalface_alt2.xml')
|
||
|
recognizer = cv2.face.LBPHFaceRecognizer_create()
|
||
|
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
||
|
|
||
|
with sqlite3.connect("database.db") as db:
|
||
|
cursor = db.cursor()
|
||
|
|
||
|
cursor.execute('''
|
||
|
CREATE TABLE IF NOT EXISTS users(
|
||
|
user_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
|
username VARCHAR(35) NOT NULL UNIQUE,
|
||
|
password VARCHAR(35) NOT NULL
|
||
|
);
|
||
|
''')
|
||
|
|
||
|
cursor.execute('SELECT * FROM users;')
|
||
|
print("Na start:",cursor.fetchall())
|
||
|
|
||
|
def start_window():
|
||
|
global window
|
||
|
window = Tk()
|
||
|
window.geometry('300x200')
|
||
|
window.title('Login')
|
||
|
Label(text = 'Login', font = ('Calibri', 12)).pack()
|
||
|
Button(text = 'Login', command = login).pack()
|
||
|
Button(text='Register', command = register).pack()
|
||
|
|
||
|
window.mainloop()
|
||
|
|
||
|
def register():
|
||
|
global reg_window
|
||
|
reg_window = Toplevel(window)
|
||
|
reg_window.title('Register')
|
||
|
reg_window.geometry('300x200')
|
||
|
|
||
|
global reg_username
|
||
|
global reg_password
|
||
|
|
||
|
reg_username = StringVar()
|
||
|
reg_password = StringVar()
|
||
|
|
||
|
Label(reg_window, text='Username:', font=('Calibri', 12)).pack()
|
||
|
Entry(reg_window, textvariable = reg_username).pack()
|
||
|
Label(reg_window, text='Password:', font=('Calibri', 12)).pack()
|
||
|
Entry(reg_window, textvariable = reg_password, show='*').pack()
|
||
|
Button(reg_window, text='Register', command = reg_conf).pack()
|
||
|
|
||
|
def reg_conf():
|
||
|
|
||
|
new_username = reg_username.get()
|
||
|
new_password = reg_password.get()
|
||
|
|
||
|
cursor.execute('SELECT * FROM users WHERE username like "'''+new_username+'''";''')
|
||
|
|
||
|
user_test = cursor.fetchone()
|
||
|
|
||
|
if len(new_username) >= 3 and len(new_password) >= 3:
|
||
|
if user_test == None:
|
||
|
reg_cam()
|
||
|
cursor.execute('''
|
||
|
INSERT INTO users(username, password)
|
||
|
VALUES ("''' + new_username + '''", "''' + new_password + '''");
|
||
|
''')
|
||
|
ctypes.windll.user32.MessageBoxW(0, "Successfully registered!", "Success!", 0)
|
||
|
reg_window.destroy()
|
||
|
else:
|
||
|
ctypes.windll.user32.MessageBoxW(0, "User exists!", "Error", 0)
|
||
|
else:
|
||
|
ctypes.windll.user32.MessageBoxW(0, "Username or password should be longer! (at least 3 characters)", "Error", 0)
|
||
|
db.commit()
|
||
|
|
||
|
def login():
|
||
|
global cam_ver
|
||
|
global log_window
|
||
|
log_window = Toplevel(window)
|
||
|
log_window.title('Login')
|
||
|
log_window.geometry('300x200')
|
||
|
|
||
|
global log_username
|
||
|
global log_password
|
||
|
|
||
|
log_username = StringVar()
|
||
|
log_password = StringVar()
|
||
|
|
||
|
Label(log_window, text='Username:', font=('Calibri', 12)).pack()
|
||
|
Entry(log_window, textvariable=log_username).pack()
|
||
|
Label(log_window, text='Password:', font=('Calibri', 12)).pack()
|
||
|
Entry(log_window, textvariable=log_password, show='*').pack()
|
||
|
Button(log_window, text='Login', command=log_conf).pack()
|
||
|
|
||
|
def log_conf():
|
||
|
global cam_ver
|
||
|
cam_ver = False
|
||
|
username = log_username.get()
|
||
|
password = log_password.get()
|
||
|
|
||
|
cursor.execute('SELECT * FROM users WHERE username like "'''+username+'''" AND password like "'''+password+'''";''')
|
||
|
|
||
|
user_test = cursor.fetchone()
|
||
|
|
||
|
print(user_test)
|
||
|
|
||
|
if user_test != None:
|
||
|
log_cam()
|
||
|
if cam_ver == True:
|
||
|
log_window.destroy()
|
||
|
window.destroy()
|
||
|
main_window()
|
||
|
else:
|
||
|
ctypes.windll.user32.MessageBoxW(0, "Incorrect login or password!", "Error", 0)
|
||
|
|
||
|
db.commit()
|
||
|
|
||
|
def main_window():
|
||
|
window = Tk()
|
||
|
window.geometry('300x200')
|
||
|
window.title('Main')
|
||
|
|
||
|
Button(text='Cursor control', command=cursor_control).pack()
|
||
|
Button(text='OCR', command=ocr).pack()
|
||
|
|
||
|
def reg_cam():
|
||
|
capture = cv2.VideoCapture(0)
|
||
|
i=0
|
||
|
os.mkdir('images/' + reg_username.get(), 777)
|
||
|
while (True):
|
||
|
ret, frame = capture.read()
|
||
|
frameGray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
|
||
|
faces = cascade.detectMultiScale(frameGray, scaleFactor=1.5, minNeighbors=5)
|
||
|
for (x, y, w,h) in faces:
|
||
|
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
|
||
|
roi_gray = frameGray[y:y + h, x:x + w]
|
||
|
image = 'images/'+reg_username.get()+'/image'+str(i)+'.png'
|
||
|
cv2.imwrite(image, roi_gray)
|
||
|
|
||
|
i=i+1
|
||
|
|
||
|
cv2.imshow('Move your head sideways, up and down (no more than 30 degrees)', frame)
|
||
|
if cv2.waitKey(27) & 0xFF == ord('\x1b'):
|
||
|
print("stop")
|
||
|
if i == 100:
|
||
|
break
|
||
|
|
||
|
capture.release()
|
||
|
cv2.destroyAllWindows()
|
||
|
current_id = 0
|
||
|
name_ids = {}
|
||
|
y_names = []
|
||
|
x_train = []
|
||
|
|
||
|
for root, dirs, files in os.walk(os.path.join(BASE_DIR, 'images/'+reg_username.get()+'/')):
|
||
|
for file in files:
|
||
|
if file.endswith('png'):
|
||
|
path = os.path.join(root, file)
|
||
|
name = os.path.basename(root)
|
||
|
print(name, path)
|
||
|
if name in name_ids:
|
||
|
pass
|
||
|
else:
|
||
|
name_ids[name] = current_id
|
||
|
current_id += 1
|
||
|
|
||
|
id_ = name_ids[name]
|
||
|
print(name_ids)
|
||
|
pil_image = Image.open(path)
|
||
|
image_array = np.array(pil_image, 'uint8')
|
||
|
faces = cascade.detectMultiScale(image_array, minNeighbors=5)
|
||
|
|
||
|
for (x, y, w, h) in faces:
|
||
|
roi = image_array[y:y + h, x:x + w]
|
||
|
x_train.append(roi)
|
||
|
y_names.append(id_)
|
||
|
|
||
|
recognizer.train(x_train, np.array(y_names))
|
||
|
recognizer.save('train/'+reg_username.get()+'.yml')
|
||
|
|
||
|
def log_cam():
|
||
|
capture = cv2.VideoCapture(0)
|
||
|
|
||
|
global cam_ver
|
||
|
|
||
|
recognizer.read('train/'+log_username.get()+'.yml')
|
||
|
|
||
|
i = 0
|
||
|
|
||
|
while (True):
|
||
|
|
||
|
ret, frame = capture.read()
|
||
|
frameGray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
|
||
|
faces = cascade.detectMultiScale(frameGray, scaleFactor=1.5, minNeighbors=5)
|
||
|
|
||
|
for (x, y, w, h) in faces:
|
||
|
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
|
||
|
cv2.rectangle(frameGray, (x, y), (x + w, y + h), (0, 255, 0), 2)
|
||
|
roi_gray = frameGray[y:y + h, x:x + w]
|
||
|
id_, conf = recognizer.predict(roi_gray)
|
||
|
if conf >= 50:
|
||
|
i += 1
|
||
|
|
||
|
cv2.imshow('Login', frame)
|
||
|
|
||
|
if cv2.waitKey(27) & 0xFF == ord('\x1b'):
|
||
|
print("stop")
|
||
|
|
||
|
if i >= 3:
|
||
|
cam_ver = True
|
||
|
print(cam_ver)
|
||
|
break
|
||
|
|
||
|
capture.release()
|
||
|
cv2.destroyAllWindows()
|
||
|
|
||
|
def cursor_control():
|
||
|
|
||
|
capture = cv2.VideoCapture(0)
|
||
|
pag.FAILSAFE = FALSE
|
||
|
|
||
|
old_cx, old_cy = pag.position()
|
||
|
|
||
|
while (True):
|
||
|
ret, frame = capture.read()
|
||
|
|
||
|
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
|
||
|
|
||
|
image_blur = cv2.GaussianBlur(frame, (7, 7), 0)
|
||
|
image_blur_hsv = cv2.cvtColor(image_blur, cv2.COLOR_RGB2HSV)
|
||
|
|
||
|
min_red = np.array([0,100,80])
|
||
|
max_red = np.array([10,256,256])
|
||
|
mask1 = cv2.inRange(image_blur_hsv, min_red, max_red)
|
||
|
|
||
|
min_red2 = np.array([170,100,80])
|
||
|
max_red2 = np.array([180, 256, 256])
|
||
|
mask2 = cv2.inRange(image_blur_hsv, min_red2, max_red2)
|
||
|
|
||
|
mask = mask1 + mask2
|
||
|
|
||
|
min_blue = np.array([110, 50, 50])
|
||
|
max_blue = np.array([130, 255, 255])
|
||
|
click_mask = cv2.inRange(image_blur_hsv, min_blue, max_blue)
|
||
|
|
||
|
contour = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (15, 15))
|
||
|
mask_closed = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, contour)
|
||
|
mask_clean = cv2.morphologyEx(mask_closed, cv2.MORPH_OPEN, contour)
|
||
|
|
||
|
contours, hierarchy = cv2.findContours(mask_clean, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
|
||
|
|
||
|
contour_blue = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (15, 15))
|
||
|
blue_closed = cv2.morphologyEx(click_mask, cv2.MORPH_CLOSE, contour_blue)
|
||
|
blue_clean = cv2.morphologyEx(blue_closed, cv2.MORPH_OPEN, contour_blue)
|
||
|
|
||
|
click_contours, click_hierarchy = cv2.findContours(blue_clean, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
|
||
|
|
||
|
contour_sizes = [(cv2.contourArea(contour), contour) for contour in contours]
|
||
|
|
||
|
if contour_sizes != []:
|
||
|
marker = max(contour_sizes, key=lambda x: x[0])[1]
|
||
|
|
||
|
M = cv2.moments(marker)
|
||
|
cx = int(M['m10'] / M['m00'])
|
||
|
cy = int(M['m01'] / M['m00'])
|
||
|
pag.move((cx-old_cx)*5, (cy-old_cy)*5, duration=0.5)
|
||
|
|
||
|
old_cx = cx
|
||
|
old_cy = cy
|
||
|
|
||
|
click_contour_sizes = [(cv2.contourArea(click_contour), click_contour) for click_contour in click_contours]
|
||
|
|
||
|
if click_contour_sizes != []:
|
||
|
pag.click()
|
||
|
|
||
|
if pag.position() == (0,0):
|
||
|
break
|
||
|
|
||
|
capture.release()
|
||
|
cv2.destroyAllWindows()
|
||
|
|
||
|
def ocr():
|
||
|
Tk().withdraw()
|
||
|
filename = askopenfilename(filetypes=[("PNG files", "*.png")])
|
||
|
|
||
|
pt.pytesseract.tesseract_cmd = r'C:\Users\Kuba\AppData\Local\Tesseract-OCR\tesseract.exe'
|
||
|
image = cv2.imread(filename)
|
||
|
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
|
||
|
|
||
|
kernel = np.ones((1, 1), np.uint8)
|
||
|
image = cv2.dilate(image, kernel)
|
||
|
image = cv2.erode(image, kernel)
|
||
|
|
||
|
image = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 65, 105)
|
||
|
|
||
|
text = pt.image_to_string(image)
|
||
|
|
||
|
file = open(filename+'.txt', 'w+')
|
||
|
file.write(text)
|
||
|
file.close()
|
||
|
|
||
|
print(text)
|
||
|
print(filename)
|
||
|
|
||
|
|
||
|
start_window()
|