diff --git a/1.jpg b/1.jpg new file mode 100644 index 0000000..98b7162 Binary files /dev/null and b/1.jpg differ diff --git a/2.jpg b/2.jpg new file mode 100644 index 0000000..3a9c916 Binary files /dev/null and b/2.jpg differ diff --git a/best.py b/best.py new file mode 100644 index 0000000..f150c75 --- /dev/null +++ b/best.py @@ -0,0 +1,56 @@ +import mysql.connector + + +# det_res -> detection result +def best(det_res): + chars = ['®', '|', ' ', "'", '[', ']', ',', '\n', '\x0c', '/', '\\'] + for i in range(len(det_res)): + for char in chars: + det_res[i] = det_res[i].replace(char, '') + + for ele in det_res: + if len(ele) == 1: + det_res.remove(ele) + + while "" in det_res: + det_res.remove("") + + print(det_res) + + db = mysql.connector.connect(host="localhost", user="root", database="wtb_db") + cursor = db.cursor() + + cursor.execute('SELECT * FROM coffee') + db_results = cursor.fetchall() + + score = [] + for i in range(len(db_results)): + keywords = db_results[i][2].split(';') + score.append(0) + for res in det_res: + print(f'\n=== {db_results[i][1]} ===') + for keyword in keywords: + if res.lower() in keyword.lower(): + print(f'{res} -- {keyword}') + # dwa pierwsze to zawsze nazwa kawy, dlatego jest lepiej punktowana + if i < 2: + score[i] += 3 + else: + score[i] += 1 + if score[i] != 0: + if i != 0: + score[i] = score[i]/i + + print(score[i]) + print("=======================") + + print(score) + if score.index(max(score)) < 1: + return 'Nie wykryto kawy w bazie danych' + else: + best_index = score.index(max(score)) + + return f""" + WYKRYTO: {db_results[best_index][1]}\n + Opis: {db_results[best_index][3]} + """ diff --git a/job.py b/job.py new file mode 100644 index 0000000..0a88642 --- /dev/null +++ b/job.py @@ -0,0 +1,129 @@ +import numpy as np +import cv2 +from imutils.object_detection import non_max_suppression +import pytesseract +# from matplotlib import pyplot as plt + +from best import best + + +def job(folder): + folder = f'imgs/{folder}' + # tworzenie biblioteki argumentów (ta forma ułatwia rozróżnienie tych argumentów od innych zmiennych) + args = {"images": [f"{folder}/1.jpg", f"{folder}/2.jpg", f"{folder}/3.jpg"], + "east": "frozen_east_text_detection.pb", + "min_confidence": 0.5, + "width": 320, # wielokrotność 32 + "height": 416 # *wielokrotność 32 + } + # *uzasadnienie: + # aplikacja przeznaczona jest dla urządzeń mobilnych, dla których naturalnym ustawieniem obiektywu jest to pionowe + # (posiadające więcej px w wysokości niż szerokości). Mój telefon wykonuje zdjęcia w rodzielczości 3000x4000 px, + # zatem ich stosunek wynosi 1,(3). Domyślną wartością tutaj jest 320 px, zatem 320 * 1,3 = 416 + + images = [] + for i in range(len(args['images'])): + images.append(cv2.imread(args['images'][i])) + + # zapisywanie oryginalnych wymiarów (zdjęcia z telefonu mają takie same wymiary, więc wystarczy sprawdzenie jednego) + orig = images[0].copy() + (origH, origW) = images[0].shape[:2] + + # zdefiniowanie rozmiaru czytanego obrazka (najlepiej wielokrotność liczby 32) + (newW, newH) = (args["width"], args["height"]) + + # obliczanie stosunku wymiarów zdjęcia do poprawnego przeskalowania (r = ratio) + rW = origW / float(newW) + rH = origH / float(newH) + + # przeskalowanie zdjęć + for i in range(len(images)): + images[i] = cv2.resize(images[i], (newW, newH)) + (H, W) = images[0].shape[:2] + + # tworzenie blobów, które zostaną przekazane do modelu EAST w celu wykrycia tekstu + blob = cv2.dnn.blobFromImages(images, 1.0, (W, H), (123.68, 116.78, 103.94), swapRB=True, crop=False) + + # załadowanie modelu EAST do wykrywania tekstu + net = cv2.dnn.readNet(args["east"]) + + # zgodnie z poleceniem ze źródła wyznaczamy dwie warstwy z modelu EAST + layerNames = ["feature_fusion/Conv_7/Sigmoid", "feature_fusion/concat_3"] + + net.setInput(blob) + (scores, geometry) = net.forward(layerNames) + + def predictions(prob_score, geo): + (numR, numC) = prob_score.shape[2:4] + boxes = [] + confidence_val = [] + + for y in range(0, numR): + scoresData = prob_score[0, 0, y] + x0 = geo[0, 0, y] + x1 = geo[0, 1, y] + x2 = geo[0, 2, y] + x3 = geo[0, 3, y] + anglesData = geo[0, 4, y] + + for i in range(0, numC): + if scoresData[i] < args["min_confidence"]: + continue + + (offX, offY) = (i * 4.0, y * 4.0) + + angle = anglesData[i] + cos = np.cos(angle) + sin = np.sin(angle) + + h = x0[i] + x2[i] + w = x1[i] + x3[i] + + endX = int(offX + (cos * x1[i]) + (sin * x2[i])) + endY = int(offY - (sin * x1[i]) + (cos * x2[i])) + startX = int(endX - w) + startY = int(endY - h) + + boxes.append((startX, startY, endX, endY)) + confidence_val.append(scoresData[i]) + + return boxes, confidence_val + + (boxes, confidence_val) = predictions(scores, geometry) + boxes = non_max_suppression(np.array(boxes), probs=confidence_val) + + """ Znajdowanie i rozpoznawanie tekstu """ + + results = [] + for (startX, startY, endX, endY) in boxes: + startX = int(startX * rW) + startY = int(startY * rH) + endX = int(endX * rW) + endY = int(endY * rH) + + r = orig[startY:endY, startX:endX] + + configuration = "-l eng --oem 1 --psm 8" + text = pytesseract.image_to_string(r, config=configuration) + + results.append(((startX, startY, endX, endY), text)) + + orig_image = orig.copy() + + recognized = [] + for ((start_X, start_Y, end_X, end_Y), text) in results: + # wyświetlanie tekstu wykrytego przez Tesseract + recognized.append(format(text)) + print("{}\n".format(text)) + + text = "".join([x if ord(x) < 128 else "" for x in text]).strip() + cv2.rectangle(orig_image, (start_X, start_Y), (end_X, end_Y), (0, 0, 255), 2) + cv2.putText(orig_image, text, (start_X, start_Y - 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2) + + # plt.imshow(orig_image) + # plt.title('Output') + # plt.show() + + info = best(recognized) + + return info diff --git a/main.py b/main.py new file mode 100644 index 0000000..658632b --- /dev/null +++ b/main.py @@ -0,0 +1,181 @@ +from kivy.app import App +from kivy.uix.label import Label +from kivy.uix.gridlayout import GridLayout +from kivy.uix.textinput import TextInput +from kivy.uix.button import Button +from kivy.uix.screenmanager import ScreenManager, Screen +import mysql.connector +from job import job + + +class ConnectPage(GridLayout): + def __init__(self, **kwargs): + super().__init__(**kwargs) + + self.cols = 2 + + self.add_widget(Label(text='Name:')) + self.name = TextInput(multiline=False) + self.add_widget(self.name) + + self.add_widget(Label(text='Password:')) + self.password = TextInput(multiline=False) + self.add_widget(self.password) + + self.join = Button(text="Login") + self.join.bind(on_press=self.join_button) + self.add_widget(self.join) + + self.join = Button(text="Register") + self.join.bind(on_press=self.register_button) + self.add_widget(self.join) + + def join_button(self, instance): + name = self.name.text + password = self.password.text + + if name in names: + if password == users_res[names.index(name)][2]: + chat_app.screen_manager.current = 'Kawa' + else: + info = f"Podane hasło jest błędne" + chat_app.info_page.update_info(info) + chat_app.screen_manager.current = 'Info' + else: + info = f"Brak nazwy i hasła w takiej kombinacji" + chat_app.info_page.update_info(info) + chat_app.screen_manager.current = 'Info' + + def register_button(self, instance): + name = self.name.text + password = self.password.text + if name in names: + info = f"Name '{name}' already used" + chat_app.info_page.update_info(info) + chat_app.screen_manager.current = 'Info' + else: + cursor.execute(f""" + INSERT INTO users (Name, Password) + VALUES ('{name}', '{password}') + """) + db.commit() + + info = f"Added user '{name}' with password '{password}'" + chat_app.info_page.update_info(info) + chat_app.screen_manager.current = 'Info' + + +class InfoPage(GridLayout): + def __init__(self, **kwargs): + super().__init__(**kwargs) + + self.cols = 1 + self.message = Label(halign="center", valign="middle", font_size=30) + self.message = Label() + self.message.bind(width=self.update_text_width) + self.add_widget(self.message) + + self.join = Button(text="Back") + self.join.bind(on_press=self.back) + self.add_widget(self.join) + + def back(self, instance): + chat_app.screen_manager.current = 'Connect' + + def update_info(self, message): + self.message.text = message + + def update_text_width(self, *_): + self.message.text_size = (self.message.width * 0.9, None) + +class InfoPage2(GridLayout): + def __init__(self, **kwargs): + super().__init__(**kwargs) + + self.cols = 1 + self.message = Label(halign="center", valign="middle", font_size=30) + self.message = Label() + self.message.bind(width=self.update_text_width) + self.add_widget(self.message) + + self.join = Button(text="Back") + self.join.bind(on_press=self.back) + self.add_widget(self.join) + + def back(self, instance): + chat_app.screen_manager.current = 'Kawa' + + def update_info(self, message): + self.message.text = message + + def update_text_width(self, *_): + self.message.text_size = (self.message.width * 0.9, None) + + +def result(): + info = job('1') + chat_app.info_page.update_info(info) + chat_app.screen_manager.current = 'Info2' + + +def job_to_be_done(instance): + info = 'Przetwarzam zdjęcia' + chat_app.info_page.update_info(info) + chat_app.screen_manager.current = 'Info' + result() + + +class Kawa(GridLayout): + def __init__(self, **kwargs): + super().__init__(**kwargs) + self.cols = 1 + + self.add_widget(Label()) + self.add_widget(Label()) + self.join = Button(text="Zdjęcie") + self.join.bind(on_press=job_to_be_done) + self.add_widget(self.join) + + +class WTB(App): + def build(self): + self.screen_manager = ScreenManager() + + self.connect_page = ConnectPage() + screen = Screen(name='Connect') + screen.add_widget(self.connect_page) + self.screen_manager.add_widget(screen) + + self.info_page = InfoPage() + screen = Screen(name='Info') + screen.add_widget(self.info_page) + self.screen_manager.add_widget(screen) + + self.info_page = InfoPage2() + screen = Screen(name='Info2') + screen.add_widget(self.info_page) + self.screen_manager.add_widget(screen) + + self.kawa_page = Kawa() + screen = Screen(name='Kawa') + screen.add_widget(self.kawa_page) + self.screen_manager.add_widget(screen) + + return self.screen_manager + + def back(self): + chat_app.screen_manager.current = 'Connect' + + +if __name__ == "__main__": + db = mysql.connector.connect(host="localhost", user="root", database="wtb_db") + cursor = db.cursor() + cursor.execute('SELECT * FROM users') + + users_res = cursor.fetchall() + names = [] + for res in users_res: + names.append(res[1]) + + chat_app = WTB() + chat_app.run()