diff --git a/__pycache__/app.cpython-39.pyc b/__pycache__/app.cpython-39.pyc new file mode 100644 index 0000000..369d7a6 Binary files /dev/null and b/__pycache__/app.cpython-39.pyc differ diff --git a/__pycache__/camera.cpython-39.pyc b/__pycache__/camera.cpython-39.pyc new file mode 100644 index 0000000..2188802 Binary files /dev/null and b/__pycache__/camera.cpython-39.pyc differ diff --git a/__pycache__/model.cpython-39.pyc b/__pycache__/model.cpython-39.pyc new file mode 100644 index 0000000..95a1d0f Binary files /dev/null and b/__pycache__/model.cpython-39.pyc differ diff --git a/app.py b/app.py new file mode 100644 index 0000000..14b2658 --- /dev/null +++ b/app.py @@ -0,0 +1,121 @@ +import tkinter as tk +from tkinter import simpledialog +import cv2 as cv +import os +import PIL.Image, PIL.ImageTk +import camera +import model +import sys + +sys.setrecursionlimit(3000) + +class App: + + def __init__(self, window = tk.Tk(), window_title = "Recognizer"): + + self.window = window + self.window_title = window_title + + self.counters = [1, 1] + + self.model = model.Model() + + self.autoPredict = False + + self.camera = camera.Camera() + + self.startGUI() + + self.delay = 15 + self.update() + + self.window.attributes('-topmost', True) + self.window.mainloop() + + def startGUI(self): + self.canvas = tk.Canvas(self.window, width=self.camera.width, height=self.camera.height) + self.canvas.pack(anchor=tk.CENTER, expand=True) + + self.btn_toggleauto = tk.Button(self.window, text="Auto Prediction", width=50, command=self.autoPredictToggle) + self.btn_toggleauto.pack(anchor=tk.CENTER, expand=True) + + self.classname_one = simpledialog.askstring("Classname One", "Enter the name of the first class: ", parent=self.window) + self.classname_two = simpledialog.askstring("Classname Two", "Enter the name of the second class: ", parent=self.window) + + self.btn_class_one = tk.Button(self.window, text=self.classname_one, width=50, command=lambda: self.saveForClass(1)) + self.btn_class_one.pack(anchor=tk.CENTER, expand=True) + + self.btn_class_two = tk.Button(self.window, text=self.classname_two, width=50, command=lambda: self.saveForClass(2)) + self.btn_class_two.pack(anchor=tk.CENTER, expand=True) + + self.btn_train = tk.Button(self.window, text="Train Model", width=50, command=lambda: self.model.trainModel(self.counters)) + self.btn_train.pack(anchor=tk.CENTER, expand=True) + + self.btn_predict = tk.Button(self.window, text="Predict", width=50, command=self.predict) + self.btn_predict.pack(anchor=tk.CENTER, expand=True) + + self.btn_reset = tk.Button(self.window, text="Reset", width=50, command=self.reset) + self.btn_reset.pack(anchor=tk.CENTER, expand=True) + + self.class_label = tk.Label(self.window, text="CLASS") + self.class_label.config(font=("Calibri", 20)) + self.class_label.pack(anchor=tk.CENTER, expand=True) + + + def autoPredictToggle(self): + self.autoPredict = not self.autoPredict + + def saveForClass(self, class_num): + ret, frame = self.camera.getFrame() + if not os.path.exists('class1'): + os.mkdir('class1') + if not os.path.exists('class2'): + os.mkdir('class2') + + cv.imwrite(f'class{class_num}/frame{self.counters[class_num - 1]}.jpg', cv.cvtColor(frame, cv.COLOR_RGB2GRAY)) + img = PIL.Image.open(f'class{class_num}/frame{self.counters[class_num - 1]}.jpg') + img.thumbnail((150, 150), PIL.Image.ANTIALIAS) + img.save(f'class{class_num}/frame{self.counters[class_num - 1]}.jpg') + + self.counters[class_num - 1] += 1 + + + def reset(self): + for directory in ['class1', 'class2']: + for image in os.listdir(directory): + file_path = os.path.join(directory, image) + if os.path.isfile(file_path): + os.unlink(file_path) + + self.counters = [1, 1] + self.model = model.Model() + self.class_label.config(text="CLASS") + + + def update(self): + if self.autoPredict: + self.predict() + pass + + ret, frame = self.camera.getFrame() + + if ret: + self.photo = PIL.ImageTk.PhotoImage(image=PIL.Image.fromarray(frame)) + self.canvas.create_image(0, 0, image=self.photo, anchor=tk.NW) + + print("Updating...") + self.window.after(self.delay, self.update) + + + def predict(self): + frame = self.camera.getFrame() + prediction = self.model.predict(frame) + + if prediction == 1: + self.class_label.config(text=self.classname_one) + return self.classname_one + + if prediction == 2: + self.class_label.config(text=self.classname_two) + return self.classname_two + diff --git a/brain.py b/brain.py new file mode 100644 index 0000000..d23561c --- /dev/null +++ b/brain.py @@ -0,0 +1,42 @@ +from sklearn.svm import LinearSVC +import numpy as np +import cv2 as cv +import PIL + +class Model: + + def __init__(self): + self.model = LinearSVC() + + def trainModel(self): + img_list = np.array([]) + class_list = np.array([]) + + for i in range(1, counters[0]): + img = cv.imread(f'class1/frame{i}.jpg')[:,:,0] + img = img.reshape(16800) # product of your resolutions + img_list = np.append(img_list, [img]) + class_list = np.append(class_list, 1) + + for i in range(1, counters[0]): + img = cv.imread(f'class2/frame{i}.jpg')[:,:,0] + img = img.reshape(16800) # product of your resolutions + img_list = np.append(img_list, [img]) + class_list = np.append(class_list, 2) + + img_list = img_list.reshape(counters[0] - 1 + counters[1] - 1, 16800) + self.model.fit(img_list, class_list) + print("Model Successfully Trained") + + def predict(self, frame): + frame = frame[1] + cv.imwrite('frame.jpg', cv.cvtColor(frame, cv.COLOR_RGB2GRAY)) + img = PIL.Image.open('frame.jpg') + img.thumbnail((150, 150), PIL.Image.ANTIALIAS) + img.save('frame.jpg') + + img = cv.imread(frame.jpg)[:,:,0] + img = img.reshape(16800) + prediction = self.model.predict([img]) + + return prediction[0] \ No newline at end of file diff --git a/camera.py b/camera.py new file mode 100644 index 0000000..8aa8e65 --- /dev/null +++ b/camera.py @@ -0,0 +1,29 @@ +import cv2 as cv + +class Camera: + + def __init__(self): + self.camera = cv.VideoCapture(0) + if not self.camera.isOpened(): + raise ValueError("Unable to open the camera!") + + self.width = self.camera.get(cv.CAP_PROP_FRAME_WIDTH) + self.height = self.camera.get(cv.CAP_PROP_FRAME_HEIGHT) + + + def __del__(self): + if self.camera.isOpened(): + self.camera.release() + + + def getFrame(self): + if self.camera.isOpened(): + ret, frame = self.camera.read() + + if ret: + return (ret, cv.cvtColor(frame, cv.COLOR_BGR2RGB)) + else: + return (ret, None) + else: + return None + \ No newline at end of file diff --git a/frame.jpg b/frame.jpg new file mode 100644 index 0000000..dbcbaba Binary files /dev/null and b/frame.jpg differ diff --git a/main.py b/main.py new file mode 100644 index 0000000..f8ea4ab --- /dev/null +++ b/main.py @@ -0,0 +1,10 @@ +import app +import sys + +print(sys.getrecursionlimit()) + +def main(): + app.App(window_title = "Camera Classifier") + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/model.py b/model.py new file mode 100644 index 0000000..ccad399 --- /dev/null +++ b/model.py @@ -0,0 +1,43 @@ +from sklearn.svm import LinearSVC +import numpy as np +import cv2 as cv +import PIL +# from tensorflow.keras import layers, models + +class Model: + + def __init__(self): + self.model = LinearSVC() + + def trainModel(self, counters): + img_list = np.array([]) + class_list = np.array([]) + + for i in range(1, counters[0]): + img = cv.imread(f'class1/frame{i}.jpg')[:,:,0] + img = img.reshape(150, 113) # product of your resolutions + img_list = np.append(img_list, [img]) + class_list = np.append(class_list, 1) + + for j in range(1, counters[0]): + img = cv.imread(f'class2/frame{j}.jpg')[:,:,0] + img = img.reshape(150, 113) # product of your resolutions + img_list = np.append(img_list, [img]) + class_list = np.append(class_list, 2) + + img_list = img_list.reshape(counters[0] - 1 + counters[1] - 1, 16950) + self.model.fit(img_list, class_list) + print("Model Successfully Trained") + + def predict(self, frame): + frame = frame[1] + cv.imwrite('frame.jpg', cv.cvtColor(frame, cv.COLOR_RGB2GRAY)) + img = PIL.Image.open('frame.jpg') + img.thumbnail((150, 150), PIL.Image.ANTIALIAS) + img.save('frame.jpg') + + img = cv.imread('frame.jpg')[:,:,0] + img = img.reshape(16950) + prediction = self.model.predict([img]) + + return prediction[0] \ No newline at end of file