├── Filter_images ├── ApplyFiltersCam.py ├── __init__.py └── __pycache__ │ ├── ApplyFiltersCam.cpython-39.pyc │ └── __init__.cpython-39.pyc ├── Images ├── Addfilters1.png ├── Addfilters2.png ├── Addfilters3.png ├── Count_number_of_people.png ├── Painting.png ├── astro_screen.png ├── cartoon.png ├── diver_screen.png ├── edges.png ├── pencil.png ├── style0.png └── style1.png ├── ImportScript.py ├── Landmark_detection_model ├── LandmarkDetectCam.py ├── __init__.py ├── __pycache__ │ ├── LandmarkDetectCam.cpython-39.pyc │ └── __init__.cpython-39.pyc ├── images │ ├── eyeglasses.png │ ├── hair.png │ └── nose.png └── model_train │ ├── ImageDataProcessor.py │ ├── NeuralNet.py │ └── Preprocessing.py ├── Person_detect_model ├── PersonDetectCam.py ├── __init__.py └── __pycache__ │ ├── PersonDetectCam.cpython-39.pyc │ └── __init__.cpython-39.pyc ├── README.md ├── Remove_background_model ├── HelpFunctions.py ├── RemoveBackgroundCam.py ├── __init__.py ├── __pycache__ │ ├── FaceDetectCam.cpython-39.pyc │ ├── RemoveBackgroundCam.cpython-39.pyc │ └── __init__.cpython-39.pyc ├── backgrounds │ ├── astro.png │ └── ocean.png └── model_train │ ├── HandleImagesFunction.py │ ├── ImageDataProcessor.py │ ├── datasets.yaml │ ├── detect-person.pt │ ├── train.py │ └── train_cmd.txt ├── Style_Transfer_model ├── Result_images │ ├── image_0epochs.png │ ├── image_1000epochs.png │ ├── image_2000epochs.png │ ├── image_3000epochs.png │ └── image_4000epochs.png ├── StyleTransferCam.py ├── StyleTransferFunctions.py ├── Style_images │ ├── s1.png │ ├── s2.png │ ├── s3.png │ ├── s4.png │ ├── s5.png │ └── s6.png ├── __init__.py ├── __pycache__ │ ├── StyleTransferCam.cpython-39.pyc │ └── __init__.cpython-39.pyc ├── train.py ├── train_images │ ├── base_image.jpg │ └── style_image.png └── trained_net │ ├── input_paths.json │ ├── model_architecture.json │ └── model_weights.h5 └── main.py /Filter_images/ApplyFiltersCam.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | 4 | 5 | def apply_cartoon_effect(image): 6 | gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) 7 | 8 | filtered = cv2.bilateralFilter(gray, 9, 75, 75) 9 | 10 | edges = cv2.adaptiveThreshold(filtered, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 9, 5) 11 | 12 | color = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) 13 | 14 | cartoon = cv2.bitwise_and(color, color, mask=edges) 15 | 16 | return cartoon 17 | 18 | 19 | 20 | def apply_pencil_sketch_effect(image): 21 | gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) 22 | 23 | inverted = cv2.bitwise_not(gray) 24 | 25 | blurred = cv2.GaussianBlur(inverted, (21, 21), 0) 26 | 27 | blended = cv2.divide(gray, 255 - blurred, scale=256.0) 28 | 29 | return blended 30 | 31 | 32 | 33 | def apply_sobel_edges(image): 34 | gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) 35 | 36 | sobelx = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=3) 37 | sobely = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=3) 38 | 39 | edges = cv2.addWeighted(cv2.convertScaleAbs(sobelx), 0.5, cv2.convertScaleAbs(sobely), 0.5, 0) 40 | 41 | return edges 42 | 43 | 44 | 45 | def apply_painting_effect(image): 46 | gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) 47 | 48 | blurred = cv2.medianBlur(gray, 1) 49 | 50 | _, thresholded = cv2.threshold(blurred, 100, 255, cv2.THRESH_BINARY) 51 | 52 | filtered = cv2.bilateralFilter(image, 9, 75, 75) 53 | 54 | canvas = np.zeros(image.shape, dtype=np.uint8) 55 | 56 | for c in range(image.shape[2]): 57 | canvas[:, :, c] = cv2.bitwise_and(filtered[:, :, c], thresholded) 58 | 59 | return canvas 60 | 61 | 62 | 63 | def apply_stylify_filters(filter_function, frame_name): 64 | cap = cv2.VideoCapture(0) 65 | 66 | while True: 67 | ret, frame = cap.read() 68 | 69 | new_frame = filter_function(frame) 70 | cv2.imshow(frame_name, new_frame) 71 | 72 | # Check for key press to exit 73 | if cv2.waitKey(1) & 0xFF == ord('q'): 74 | break 75 | 76 | cap.release() 77 | cv2.destroyAllWindows() -------------------------------------------------------------------------------- /Filter_images/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Filter_images/__init__.py -------------------------------------------------------------------------------- /Filter_images/__pycache__/ApplyFiltersCam.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Filter_images/__pycache__/ApplyFiltersCam.cpython-39.pyc -------------------------------------------------------------------------------- /Filter_images/__pycache__/__init__.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Filter_images/__pycache__/__init__.cpython-39.pyc -------------------------------------------------------------------------------- /Images/Addfilters1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Images/Addfilters1.png -------------------------------------------------------------------------------- /Images/Addfilters2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Images/Addfilters2.png -------------------------------------------------------------------------------- /Images/Addfilters3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Images/Addfilters3.png -------------------------------------------------------------------------------- /Images/Count_number_of_people.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Images/Count_number_of_people.png -------------------------------------------------------------------------------- /Images/Painting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Images/Painting.png -------------------------------------------------------------------------------- /Images/astro_screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Images/astro_screen.png -------------------------------------------------------------------------------- /Images/cartoon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Images/cartoon.png -------------------------------------------------------------------------------- /Images/diver_screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Images/diver_screen.png -------------------------------------------------------------------------------- /Images/edges.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Images/edges.png -------------------------------------------------------------------------------- /Images/pencil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Images/pencil.png -------------------------------------------------------------------------------- /Images/style0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Images/style0.png -------------------------------------------------------------------------------- /Images/style1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Images/style1.png -------------------------------------------------------------------------------- /ImportScript.py: -------------------------------------------------------------------------------- 1 | from colorama import Fore 2 | import tensorflow_hub 3 | import torch 4 | from Style_Transfer_model.StyleTransferCam import make_style 5 | import warnings 6 | from tensorflow.keras.models import load_model 7 | warnings.filterwarnings("ignore") 8 | 9 | def load_models(): 10 | print(Fore.LIGHTBLUE_EX, "\n\nLoading The models....") 11 | 12 | # Load Models I trained from their directories : 13 | landmark_model_path = 'Landmark_detection_model/model_train/landmark_detect_model.h5' 14 | person_detect_path = 'Remove_background_model/model_train/detect-person.pt' 15 | 16 | model = load_model(landmark_model_path) 17 | model_detect = torch.hub.load('ultralytics/yolov5', 'custom', path=person_detect_path) 18 | class_names = ['person', 'person'] 19 | 20 | # I will use pretrained model on the hub since it gives me more better images on the videos... 21 | # but you can try to use my trained modelin style transfer directroy 22 | model_t_l = tensorflow_hub.load('https://tfhub.dev/google/magenta/arbitrary-image-stylization-v1-256/2') 23 | 24 | print(Fore.LIGHTGREEN_EX, "Successfully loaded :)") 25 | 26 | return model, model_detect, model_t_l, class_names 27 | 28 | 29 | def load_style_images(): 30 | print(Fore.LIGHTBLUE_EX, "\n\nLoading styles for style transfer....") 31 | 32 | # Style Images directories : 33 | s1 = make_style(img_dir='Style_Transfer_model/Style_images/s1.png',crop=True) 34 | s2 = make_style(img_dir='Style_Transfer_model/Style_images/s2.png',crop=False) 35 | s3 = make_style(img_dir='Style_Transfer_model/Style_images/s3.png',crop=True) 36 | s4 = make_style(img_dir='Style_Transfer_model/Style_images/s4.png',crop=True) 37 | s5 = make_style(img_dir='Style_Transfer_model/Style_images/s5.png',crop=True) 38 | s6 = make_style(img_dir='Style_Transfer_model/Style_images/s6.png',crop=True) 39 | styles = [s1, s2, s3, s4, s5, s6] 40 | print(Fore.LIGHTGREEN_EX, "Successfully loaded :)") 41 | 42 | return styles 43 | 44 | 45 | def load_background_images(): 46 | print(Fore.LIGHTBLUE_EX, "\n\nLoading background images....") 47 | 48 | # images directories : 49 | astro_image_dir = 'Remove_background_model/backgrounds/astro.png' 50 | diver_image_dir = 'Remove_background_model/backgrounds/ocean.png' 51 | print(Fore.LIGHTGREEN_EX, "Successfully loaded :)") 52 | 53 | return astro_image_dir, diver_image_dir 54 | 55 | def load_add_filter_images(): 56 | print(Fore.LIGHTBLUE_EX, "\n\nLoading filter images....") 57 | 58 | # images directories : 59 | glasses_img_dir = 'Landmark_detection_model/images/eyeglasses.png' 60 | nose_img_dir = 'Landmark_detection_model/images/nose.png' 61 | hair_img_dir = 'Landmark_detection_model/images/hair.png' 62 | print(Fore.LIGHTGREEN_EX, "Successfully loaded :)") 63 | 64 | return glasses_img_dir, nose_img_dir, hair_img_dir 65 | -------------------------------------------------------------------------------- /Landmark_detection_model/LandmarkDetectCam.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | import cv2 5 | import torch 6 | from PIL import Image 7 | from tensorflow.keras.models import load_model 8 | import tkinter as tk 9 | import threading 10 | 11 | 12 | 13 | def model_landmark_outputs(model, img, x1, x2, y1, y2, update, old_preds): 14 | if x1 >= 0 and x2 >= 0 and y1 >= 0 and y2 >= 0: 15 | img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 16 | roi = img_gray[int(y1):int(y2), int(x1):int(x2)] 17 | roi_x = roi.shape[0] 18 | roi_y = roi.shape[1] 19 | img_resized = cv2.resize(roi, (96, 96)) 20 | img_normalized = img_resized / 255.0 21 | img_for_model = np.expand_dims(img_normalized, axis=0) 22 | img_for_model = np.expand_dims(img_for_model, axis=-1) 23 | 24 | if update == True: 25 | preds = model.predict(img_for_model, verbose=0) 26 | counter = 0 27 | update = False 28 | else: 29 | preds = old_preds 30 | 31 | facial_keypoints = preds.reshape(6,) 32 | x_coords = facial_keypoints[::2] 33 | y_coords = facial_keypoints[1::2] 34 | 35 | x0, y0 = x_coords[0], y_coords[0] 36 | x1, y1 = x_coords[1], y_coords[1] 37 | x2, y2 = x_coords[2], y_coords[2] 38 | 39 | x0 = (roi_x*x0)/96 40 | y0 = (roi_x*y0)/96 41 | x1 = (roi_x*x1)/96 42 | y1 = (roi_x*y1)/96 43 | x2 = (roi_x*x2)/96 44 | y2 = (roi_x*y2)/96 45 | 46 | x_coords = [x0, x1, x2] 47 | y_coords = [y0, y1, y2] 48 | flag = True 49 | 50 | return img_normalized, x_coords, y_coords, flag, update, preds 51 | else: 52 | flag = False 53 | dummy_preds = np.array([0,0,0,0,0,0]).reshape(6,) 54 | return None, None, None, flag, update, dummy_preds 55 | 56 | 57 | 58 | def landmark_detect_on_cam(model_detect, model_landmark, filters, glasses_img_dir, nose_img, hair_img): 59 | glasses_img = Image.open(glasses_img_dir) 60 | nose_img = Image.open(nose_img) 61 | hair_img = Image.open(hair_img) 62 | 63 | counter = 0 64 | update = True 65 | old_preds = np.array([0,0,0,0,0,0]).reshape(6,) 66 | 67 | capture = cv2.VideoCapture(0) 68 | while True: 69 | ret, frame = capture.read() 70 | 71 | results = model_detect(frame) 72 | 73 | objects = results.pred[0] 74 | 75 | for obj in objects: 76 | x1, y1, x2, y2, confidence, class_id = obj.tolist() 77 | x1, y1, x2, y2 = x1-10, y1-50, x2+10, y2+15 78 | 79 | 80 | img_normalized, x_coords, y_coords, flag, update, preds = model_landmark_outputs(model_landmark, frame, 81 | x1, x2, y1, y2, update, 82 | old_preds) 83 | old_preds = preds 84 | delay_time = 3 85 | if counter < delay_time: 86 | counter = counter + 1 87 | else: 88 | update = True 89 | counter = 0 90 | 91 | if flag == True : 92 | for x, y in zip(x_coords, y_coords): 93 | x = (int(x)+int(x1)-25) 94 | y = (int(y)+int(y1)+20) 95 | 96 | width, height = x1-x2,y1-y2 97 | 98 | if len(filters) == 0: 99 | pt1 = (int(x1), int(y1)) 100 | pt2 = (int(x2), int(y2)) 101 | thickness = 2 102 | color = (255, 0, 0) 103 | cv2.rectangle(frame, pt1, pt2, color, thickness) 104 | 105 | text = "No filters chosen" 106 | text_position = (int(x1), int(y1 - 10)) 107 | font = cv2.FONT_HERSHEY_SIMPLEX 108 | font_scale = 0.8 109 | cv2.putText(frame, text, text_position, font, font_scale, color, thickness, cv2.LINE_AA) 110 | 111 | frame_pil = Image.fromarray(frame) 112 | if 0 in filters: 113 | width_g, height_g = int((x2-x1)*1), int((y2-y1)/3) 114 | glasses_img = glasses_img.resize((width_g, height_g)) 115 | l_eye_x = int(x_coords[0])+int(x1)-25 116 | l_eye_y = int(y_coords[0])+int(y1)+20 117 | r_eye_x = int(x_coords[1])+int(x1)-25 118 | r_eye_y = int(y_coords[1])+int(y1)+20 119 | glasses_x = ((l_eye_x + r_eye_x)/2) - width_g / 2 - 10 120 | glasses_y = (l_eye_y + r_eye_y)/2 - height_g / 2 - 5 121 | frame_pil = Image.fromarray(frame) 122 | frame_pil.paste(glasses_img, (int(glasses_x), int(glasses_y)), mask=glasses_img) 123 | 124 | if 1 in filters: 125 | width_n, height_n = int((x2-x1)/1), int((y2-y1)/3) 126 | nose_img = nose_img.resize((width_n, height_n)) 127 | nose_x = int(x_coords[2]+int(x1)-25) - width_n / 2 - 10 128 | nose_y = int(y_coords[2]+int(y1)+20) - height_n / 2 - 34 129 | frame_pil.paste(nose_img, (int(nose_x), int(nose_y)), mask=nose_img) 130 | 131 | if 2 in filters: 132 | width_h, height_h = int((x2-x1)*1.15), int((y2-y1)*0.6) 133 | hair_img = hair_img.resize((width_h, height_h)) 134 | hair_x = (x1+x2)/2 - width_h / 2 135 | hair_y = (y1+20) - height_h / 4 - 10 136 | frame_pil.paste(hair_img, (int(hair_x), int(hair_y)), mask=hair_img) 137 | 138 | if len(filters) != 0: 139 | frame = np.array(frame_pil) 140 | 141 | 142 | cv2.imshow('Object Detection', frame) 143 | if cv2.waitKey(1) == ord('q'): 144 | break 145 | 146 | capture.release() 147 | cv2.destroyAllWindows() 148 | 149 | 150 | def select_filters(checkbox1_var,checkbox2_var,checkbox3_var): 151 | selected_items = [] 152 | if checkbox1_var.get(): 153 | selected_items.append(0) 154 | if checkbox2_var.get(): 155 | selected_items.append(1) 156 | if checkbox3_var.get(): 157 | selected_items.append(2) 158 | 159 | return selected_items 160 | 161 | def run_landmark_detection(model_detect,model_landmark,glasses_img_dir,nose_img,hair_img,checkbox1_var,checkbox2_var,checkbox3_var): 162 | selected_filters = select_filters(checkbox1_var,checkbox2_var,checkbox3_var) 163 | landmark_detect_on_cam(model_detect, model_landmark, selected_filters, glasses_img_dir, nose_img, hair_img) 164 | 165 | 166 | 167 | def run_final_filters(root,checkbox1_var,checkbox2_var,checkbox3_var,model_detect,model_landmark,glasses_img_dir,nose_img,hair_img): 168 | 169 | button_width = 15 170 | button_height = 2 171 | 172 | # Create checkboxes 173 | checkbox1 = tk.Checkbutton(root, text="Eye glasses", variable=checkbox1_var, 174 | font=("Arial", 12), width=button_width, height=button_height, anchor="w") 175 | checkbox1.pack(pady=5, anchor="w") 176 | 177 | checkbox2 = tk.Checkbutton(root, text="Nose", variable=checkbox2_var, 178 | font=("Arial", 12), width=button_width, height=button_height, anchor="w") 179 | checkbox2.pack(pady=5, anchor="w") 180 | 181 | checkbox3 = tk.Checkbutton(root, text="Hair", variable=checkbox3_var, 182 | font=("Arial", 12), width=button_width, height=button_height, anchor="w") 183 | checkbox3.pack(pady=5, anchor="w") 184 | 185 | # Create a button to show the selection 186 | show_button = tk.Button(root, text="Show Selection", 187 | command=lambda: run_landmark_detection(model_detect, model_landmark, glasses_img_dir, nose_img, hair_img, 188 | checkbox1_var,checkbox2_var,checkbox3_var), 189 | font=("Arial", 12), bg='blue') 190 | show_button.pack(pady=10) 191 | 192 | # Run the GUI main loop 193 | root.mainloop() 194 | 195 | -------------------------------------------------------------------------------- /Landmark_detection_model/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Landmark_detection_model/__init__.py -------------------------------------------------------------------------------- /Landmark_detection_model/__pycache__/LandmarkDetectCam.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Landmark_detection_model/__pycache__/LandmarkDetectCam.cpython-39.pyc -------------------------------------------------------------------------------- /Landmark_detection_model/__pycache__/__init__.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Landmark_detection_model/__pycache__/__init__.cpython-39.pyc -------------------------------------------------------------------------------- /Landmark_detection_model/images/eyeglasses.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Landmark_detection_model/images/eyeglasses.png -------------------------------------------------------------------------------- /Landmark_detection_model/images/hair.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Landmark_detection_model/images/hair.png -------------------------------------------------------------------------------- /Landmark_detection_model/images/nose.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Landmark_detection_model/images/nose.png -------------------------------------------------------------------------------- /Landmark_detection_model/model_train/ImageDataProcessor.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | import numpy as np 3 | import seaborn as sns 4 | import os 5 | import random 6 | import zipfile 7 | import shutil 8 | import tensorflow as tf 9 | from sklearn.model_selection import train_test_split 10 | from tensorflow.keras.preprocessing.image import ImageDataGenerator, load_img, img_to_array, array_to_img 11 | 12 | class ImageDataHandler: 13 | """ 14 | A utility class for handling image data, including downloading, splitting into train and test sets, 15 | and augmenting data using Keras' ImageDataGenerator. 16 | 17 | Parameters: 18 | ----------- 19 | url : str 20 | URL to the data zip file to be downloaded. 21 | cache_dir : str, optional 22 | Directory to cache the downloaded data, defaults to current working directory. 23 | 24 | Methods: 25 | -------- 26 | download_data(): 27 | Downloads the data zip file from the given URL and extracts it into a 'datasets' folder. 28 | 29 | split_data(data_dir: str, train_dir: str, test_dir: str, test_size: float): 30 | Splits the data in the `data_dir` directory into training and testing sets, and saves them in `train_dir` 31 | and `test_dir` directories respectively. `test_size` is the proportion of data to be used for testing, 32 | defaults to 0.2. 33 | 34 | data_augment(train_dir: str, rotation_range: int, width_shift_range: float, height_shift_range: float, 35 | shear_range: float, zoom_range: float): 36 | Augments the training data in the `train_dir` directory using Keras' ImageDataGenerator. `rotation_range`, 37 | `width_shift_range`, `height_shift_range`, `shear_range`, and `zoom_range` are the ranges for random image 38 | transformations, as defined by Keras' ImageDataGenerator. 39 | 40 | delete_folder(folder_path: str): 41 | Deletes the folder at the given `folder_path`. 42 | """ 43 | def __init__(self, url, cache_dir='.'): 44 | 45 | self.url = url 46 | self.cache_dir = cache_dir 47 | 48 | def download_data(self): 49 | 50 | data_path = tf.keras.utils.get_file("data.zip", self.url, cache_dir=self.cache_dir) 51 | with zipfile.ZipFile(data_path, 'r') as zip_ref: 52 | zip_ref.extractall('datasets') 53 | 54 | def split_data(self, data_dir, train_dir, test_dir, test_size=0.2): 55 | 56 | for class_name in os.listdir(data_dir): 57 | class_dir = os.path.join(data_dir, class_name) 58 | 59 | train_class_dir = os.path.join(train_dir, class_name) 60 | test_class_dir = os.path.join(test_dir, class_name) 61 | 62 | # Create the class folders in the new data directories 63 | os.makedirs(train_class_dir, exist_ok=True) 64 | os.makedirs(test_class_dir, exist_ok=True) 65 | 66 | # Loop through the images in the class folder 67 | image_paths = [os.path.join(class_dir, img_name) for img_name in os.listdir(class_dir)] 68 | train_paths, test_paths = train_test_split(image_paths, test_size=test_size, random_state=42) 69 | 70 | # Copy the training images to the training directory 71 | for path in train_paths: 72 | filename = os.path.basename(path) 73 | dest_path = os.path.join(train_class_dir, filename) 74 | shutil.copy2(path, dest_path) 75 | 76 | # Copy the testing images to the testing directory 77 | for path in test_paths: 78 | filename = os.path.basename(path) 79 | dest_path = os.path.join(test_class_dir, filename) 80 | shutil.copy2(path, dest_path) 81 | 82 | def data_augment(self, train_dir, rotation_range=40, width_shift_range=0.2, height_shift_range=0.2, shear_range=0.2, zoom_range=0.2): 83 | 84 | class_names = os.listdir(train_dir) 85 | num_images = {} 86 | for class_name in class_names: 87 | num_images[class_name] = len(os.listdir(os.path.join(train_dir, class_name))) 88 | print(f'Number of images in each class: {num_images}') 89 | 90 | # Set the target number of images for each class 91 | target_num = max(num_images.values()) 92 | 93 | # Define an ImageDataGenerator for data augmentation 94 | data_gen = ImageDataGenerator( 95 | rotation_range=rotation_range, 96 | width_shift_range=width_shift_range, 97 | height_shift_range=height_shift_range, 98 | shear_range=shear_range, 99 | zoom_range=zoom_range, 100 | horizontal_flip=True, 101 | fill_mode='nearest') 102 | 103 | # Loop through each class and augment the images 104 | for class_name in class_names: 105 | # Calculate the number of images to generate 106 | num_to_generate = target_num - num_images[class_name] 107 | if num_to_generate <= 0: 108 | continue 109 | print('Number of Images needed to be generated : ',num_to_generate) 110 | 111 | # Set the path to the images in the current class 112 | class_path = os.path.join(train_dir, class_name) 113 | print('images needs to be generated in : ',class_path) 114 | 115 | # Loop through the images in the current class and generate new images 116 | for i, img_name in enumerate(os.listdir(class_path)): 117 | # Load the image and convert it to a numpy array 118 | img_path = os.path.join(class_path, img_name) 119 | img = load_img(img_path, target_size=(224, 224)) 120 | x = img_to_array(img) 121 | 122 | # Generate new images 123 | for j in range(num_to_generate): 124 | # Apply random transformations to the image 125 | params = data_gen.get_random_transform(x.shape) 126 | x_aug = data_gen.apply_transform(x, params) 127 | 128 | # Save the new image 129 | new_img_name = f'{class_name}_{i}_{j}.JPG' 130 | new_img_path = os.path.join(class_path, new_img_name) 131 | img = array_to_img(x_aug) 132 | img.save(new_img_path) 133 | 134 | # Update the number of images in the current class 135 | num_images[class_name] += num_to_generate 136 | break 137 | 138 | print(f'Number of images in each class after data augmentation: {num_images}') 139 | 140 | def delete_folder(self, folder_path): 141 | 142 | shutil.rmtree(folder_path) 143 | 144 | 145 | class ImageGenerator: 146 | """A class for creating image data generators using Keras ImageDataGenerator. 147 | 148 | Attributes: 149 | train_dir (str): Path to the directory containing the training images. 150 | test_dir (str): Path to the directory containing the testing images. 151 | img_height (int): The desired height of the input images. 152 | img_width (int): The desired width of the input images. 153 | batch_size (int): The batch size to use for training and testing. 154 | 155 | Methods: 156 | 157 | create_train_generator(self): 158 | Returns the data generator for training images. 159 | 160 | create_val_generator(self): 161 | Returns the data generator for validation images. 162 | 163 | create_test_generator(self): 164 | Returns the data generator for testing images. 165 | """ 166 | def __init__(self, train_dir, test_dir, img_height=224, img_width=224, batch_size=32): 167 | self.train_dir = train_dir 168 | self.test_dir = test_dir 169 | self.img_height = img_height 170 | self.img_width = img_width 171 | self.batch_size = batch_size 172 | 173 | def create_data_generators(self): 174 | datagen = ImageDataGenerator(rescale=1./255, validation_split=0.2) 175 | 176 | # create train and test data generators 177 | train_datagen = ImageDataGenerator(rescale=1./255) 178 | test_datagen = ImageDataGenerator(rescale=1./255) 179 | 180 | train_generator = train_datagen.flow_from_directory( 181 | self.train_dir, 182 | target_size=(self.img_height, self.img_width), 183 | batch_size=self.batch_size, 184 | class_mode='binary') 185 | 186 | val_generator = datagen.flow_from_directory( 187 | self.train_dir, 188 | target_size=(self.img_height, self.img_width), 189 | batch_size=self.batch_size, 190 | class_mode='binary', 191 | subset='validation') 192 | 193 | test_generator = test_datagen.flow_from_directory( 194 | self.test_dir, 195 | target_size=(self.img_height, self.img_width), 196 | batch_size=self.batch_size, 197 | class_mode='binary') 198 | 199 | return train_generator, val_generator, test_generator 200 | 201 | 202 | class ImagePlotter: 203 | """ 204 | Attributes: 205 | generator: An instance of `tf.keras.preprocessing.image.ImageDataGenerator` used 206 | for generating batches of images. 207 | Methods: 208 | show_images(num_images): Displays a batch of `num_images` images 209 | and 210 | their corresponding labels. 211 | """ 212 | def __init__(self, train_generator): 213 | self.train_generator = train_generator 214 | self.class_names = list(train_generator.class_indices.keys()) 215 | 216 | def plot_images(self): 217 | # Get a batch of images and their corresponding labels from the generator 218 | images, labels = next(self.train_generator) 219 | 220 | # Plot the images and their corresponding labels 221 | fig, axes = plt.subplots(6, 5, figsize=(20, 20)) 222 | axes = axes.ravel() 223 | for i in np.arange(0, 30): 224 | axes[i].imshow(images[i]) 225 | axes[i].set_title(self.class_names[int(labels[i])], color='r') 226 | axes[i].axis('off') 227 | 228 | plt.subplots_adjust(wspace=0.01) 229 | plt.show() -------------------------------------------------------------------------------- /Landmark_detection_model/model_train/NeuralNet.py: -------------------------------------------------------------------------------- 1 | from tensorflow.keras.models import Model 2 | from tensorflow.keras.layers import Input, Conv2D, MaxPooling2D, Dropout, Flatten, Dense, BatchNormalization 3 | from tensorflow.keras.optimizers import Adam 4 | from tensorflow.keras.callbacks import ModelCheckpoint 5 | from tensorflow.keras.initializers import glorot_uniform 6 | from tensorflow.keras.activations import LeakyReLU 7 | 8 | 9 | def create_and_train_model(X_train, y_train, X_test, y_test): 10 | inputs = Input(shape=(96, 96, 1)) 11 | x = BatchNormalization()(inputs) 12 | x = Conv2D(128, (3,3), padding="same", kernel_initializer=glorot_uniform(), activation=LeakyReLU(0.1))(x) 13 | x = MaxPooling2D(pool_size=(2, 2))(x) 14 | x = Dropout(0.25)(x) 15 | 16 | x = BatchNormalization()(x) 17 | x = Conv2D(256, (3,3), padding="same", kernel_initializer=glorot_uniform(), activation=LeakyReLU(0.1))(x) 18 | x = MaxPooling2D(pool_size=(2, 2))(x) 19 | x = Dropout(0.25)(x) 20 | 21 | x = BatchNormalization()(x) 22 | x = Conv2D(256, (3,3), padding="same", kernel_initializer=glorot_uniform(), activation=LeakyReLU(0.1))(x) 23 | x = MaxPooling2D(pool_size=(2, 2))(x) 24 | x = Dropout(0.25)(x) 25 | 26 | x = BatchNormalization()(x) 27 | x = Conv2D(512, (3,3), padding="same", kernel_initializer=glorot_uniform(), activation=LeakyReLU(0.1))(x) 28 | x = MaxPooling2D(pool_size=(2, 2))(x) 29 | x = Dropout(0.25)(x) 30 | 31 | x = Flatten()(x) 32 | x = Dense(1028, kernel_initializer=glorot_uniform(), activation=LeakyReLU(0.1))(x) 33 | x = Dropout(0.5)(x) 34 | x = Dense(64, kernel_initializer=glorot_uniform(), activation=LeakyReLU(0.1))(x) 35 | x = Dense(6, kernel_initializer=glorot_uniform())(x) 36 | 37 | model = Model(inputs=inputs, outputs=x) 38 | 39 | model.compile(loss='mean_squared_error', optimizer=Adam(learning_rate=7.1365e-06), metrics=['mean_squared_error']) 40 | 41 | checkpoint_filepath = 'landmark_detect_model.h5' 42 | 43 | checkpoint_callback = ModelCheckpoint( 44 | checkpoint_filepath, 45 | monitor='val_loss', 46 | save_best_only=True, 47 | mode='min', 48 | verbose=1 49 | ) 50 | 51 | history = model.fit( 52 | X_train, y_train, 53 | batch_size=128, 54 | epochs=200, 55 | validation_data=(X_test, y_test), 56 | callbacks=[checkpoint_callback] 57 | ) 58 | 59 | return model, history 60 | -------------------------------------------------------------------------------- /Landmark_detection_model/model_train/Preprocessing.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | import seaborn as sns 5 | import cv2 6 | from sklearn.model_selection import train_test_split 7 | from ImageDataProcessor import ImageDataHandler 8 | 9 | 10 | url = 'https://storage.googleapis.com/kaggle-data-sets/2598/4327/bundle/archive.zip?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=gcp-kaggle-com%40kaggle-161607.iam.gserviceaccount.com%2F20230526%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20230526T031831Z&X-Goog-Expires=259200&X-Goog-SignedHeaders=host&X-Goog-Signature=3e9ffc227bc790fd9b1c9fe9a22fef19523bde5a71646c0d13ec5fb8dd74a4b5f321c24edc6d67ced0509089b40a4c656c421ebc74147f36faacb87a6c25e824fcc7c3bca6ba4cbb472d46be585455bf29c2c44fc7d5cb8b50350ec4365bbc2490bd692027e58c85445298d036642041620f8b949b6edf025e15093cb2f293c40f3b622ed7eb11180c8d10f20ad03b8d69a9c0cf62d4b3362e034537675f7f066d713eadceb79f957d594fde896e6b43b6d207ec2519ee76b43201a956217fe75656a9b1aac179e9ffa7ab7e0a9ea7d09b698b8d3df19e2905c8c6ed3216e8798fff12b39dba9087df0889ca8111c4334d2eff85cfc8a5049752d1b28d29f8e3' 11 | 12 | data_processor = ImageDataHandler(url=url) 13 | data_processor.download_data() 14 | 15 | 16 | data = np.load('/content/datasets/face_images.npz', allow_pickle=True) 17 | images = data['face_images'] 18 | keypoints = pd.read_csv('/content/datasets/facial_keypoints.csv') 19 | 20 | data.close() 21 | 22 | keypoints = keypoints[['left_eye_center_x','left_eye_center_y', 'right_eye_center_x', 'right_eye_center_y', 23 | 'nose_tip_x', 'nose_tip_y']] 24 | 25 | 26 | images = np.swapaxes(np.swapaxes(images, 1, 2), 0, 1) 27 | images = images/255.0 28 | 29 | keypoints.fillna(keypoints.mean(),inplace=True) 30 | keypoints = np.array(keypoints) 31 | 32 | images = images.reshape(7049, 96, 96, 1) 33 | keypoints = keypoints.reshape(-1, 6) 34 | 35 | 36 | X_train, X_test, y_train, y_test = train_test_split(images, keypoints, test_size=0.2, random_state=42) 37 | X_train = tf.convert_to_tensor(X_train, dtype=tf.float32) 38 | y_train = tf.convert_to_tensor(y_train, dtype=tf.float32) 39 | X_test = tf.convert_to_tensor(X_test, dtype=tf.float32) 40 | y_test = tf.convert_to_tensor(y_test, dtype=tf.float32) -------------------------------------------------------------------------------- /Person_detect_model/PersonDetectCam.py: -------------------------------------------------------------------------------- 1 | import torch 2 | import cv2 3 | import numpy as np 4 | import tkinter as tk 5 | from threading import Thread 6 | 7 | 8 | def count_people(model, class_names): 9 | try: 10 | capture = cv2.VideoCapture(0) 11 | 12 | while True: 13 | ret, frame = capture.read() 14 | 15 | results = model(frame) 16 | 17 | objects = results.pred[0] 18 | 19 | num_people = sum(objects[:, -1] == 1) + sum(objects[:, -1] == 0) 20 | 21 | for obj in objects: 22 | x1, y1, x2, y2, confidence, class_id = obj.tolist() 23 | pt1 = (int(x1), int(y1)) 24 | pt2 = (int(x2), int(y2)) 25 | thickness = 2 26 | color = (0, 255, 0) 27 | label = class_names[int(class_id)] 28 | label_position = (int(x1), int(y1) - 10) 29 | font = cv2.FONT_HERSHEY_SIMPLEX 30 | font_scale = 0.5 31 | cv2.putText(frame, label, label_position, font, font_scale, color, thickness) 32 | cv2.rectangle(frame, pt1, pt2, color, thickness) 33 | 34 | # Display the number of people on the screen 35 | cv2.putText(frame, f"Number of people : {num_people}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1.25, (0, 255, 0), 3) 36 | 37 | cv2.imshow('Object Detection', frame) 38 | if cv2.waitKey(1) == ord('q'): 39 | break 40 | 41 | capture.release() 42 | cv2.destroyAllWindows() 43 | 44 | 45 | except Exception as e: 46 | print("An error occurred:", str(e)) 47 | -------------------------------------------------------------------------------- /Person_detect_model/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Person_detect_model/__init__.py -------------------------------------------------------------------------------- /Person_detect_model/__pycache__/PersonDetectCam.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Person_detect_model/__pycache__/PersonDetectCam.cpython-39.pyc -------------------------------------------------------------------------------- /Person_detect_model/__pycache__/__init__.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Person_detect_model/__pycache__/__init__.cpython-39.pyc -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Computer-Vision-Filters 2 | 3 | ## In this projects I made many fun filters to play with, by training neural nets and using image processing. 4 | 5 | ### In this project there is 5 filters to choose from which are : 6 | > - Count Number of people
7 | > - Neural Style Transfer
8 | > - Remove Background
9 | > - Add Filters
10 | > - Apply Stylish Filters
11 | 12 | ## Count Number of people : 13 | ### This is an object detection task that counts number of people infront of the Cam `I trained this model using yolov5` 14 | 15 | Image Description 16 | 17 | ## Neural style Transfer : 18 | ### Here I trained a neural net for style transfer, and this was it's outputs on the images: 19 |
20 | Image Description 21 | Image Description 22 | Image Description 23 | Image Description 24 | Image Description 25 |
26 | 27 | ### But I didn't like it on video cam so I used Pretrained model on tensorflow hub for the video cam and I made it work with openCV cam to give this outputs: 28 |
29 | Image Description 30 | Image Description 31 |
32 | 33 | ## Remove Background : 34 | ### Just a fun filter which uses `object detection with a model I trained using yolov5` where it detects face and removes background behind 35 |
36 | Image Description 37 | Image Description 38 |
39 | 40 | ## Add Filters : 41 | ### Here `I made a regression Conv. network used for landmark detection` where data in this networks expects 96,96 frame and 1 channel, and needs image be only the person's face so I made a pipeline of models where it first makes object detection and detect human face then image processing pipeline to make the image ready for the landmark detection model... after that it predicts keypoint on the `face using the model Landmark detection model that I made`
And here is the outputs : 42 | 43 |
44 | Image Description 45 | Image Description 46 | Image Description 47 |
48 | 49 | ## Apply Stylish Filters : 50 | ### This is Image processing filters that I made using `OpenCV`, here is the outputs : 51 | 52 |
53 | Image Description 54 | Image Description 55 | Image Description 56 | Image Description 57 |
58 | 59 | 60 | # More will be added.... 61 | -------------------------------------------------------------------------------- /Remove_background_model/HelpFunctions.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | 3 | def get_coordinates(image): 4 | """ 5 | function used to get coordinates from image, 6 | it was useful while choosing coordinates. 7 | """ 8 | cv2.imshow("Image", image) 9 | points = [] 10 | 11 | def mouse_callback(event, x, y, flags, param): 12 | if event == cv2.EVENT_LBUTTONDOWN: 13 | points.append((x, y)) 14 | cv2.circle(image, (x, y), 2, (0, 0, 255), -1) 15 | cv2.imshow("Image", image) 16 | 17 | cv2.namedWindow("Image") 18 | cv2.setMouseCallback("Image", mouse_callback) 19 | 20 | while True: 21 | cv2.imshow("Image", image) 22 | key = cv2.waitKey(1) & 0xFF 23 | 24 | if key == ord("r"): 25 | image = image.copy() 26 | points = [] 27 | elif key == ord("q"): 28 | break 29 | 30 | cv2.destroyAllWindows() 31 | return points 32 | -------------------------------------------------------------------------------- /Remove_background_model/RemoveBackgroundCam.py: -------------------------------------------------------------------------------- 1 | import torch 2 | import cv2 3 | import numpy as np 4 | import tkinter as tk 5 | from threading import Thread 6 | 7 | 8 | def astronut_filter_function(model, image_dir): 9 | """ 10 | Function for the astronut filter 11 | """ 12 | try: 13 | capture = cv2.VideoCapture(0) 14 | background_image = cv2.imread(image_dir) 15 | background_image = cv2.resize(background_image, (1000, 800)) 16 | 17 | mask0 = np.zeros_like(background_image) 18 | center = (720 + 60, 65 + 60) 19 | axes = (50, 80) # Semi-major and semi-minor axes lengths 20 | angle = 0 # Rotation angle of the ellipse 21 | color = (255, 255, 255) # Color of the ellipse 22 | thickness = -1 # Thickness (-1 to fill the ellipse) 23 | 24 | cv2.ellipse(mask0, center, axes, angle, 0, 360, color, thickness) 25 | mask0 = cv2.bitwise_not(mask0) 26 | background_image = cv2.bitwise_and(background_image, mask0) 27 | 28 | while True: 29 | ret, frame = capture.read() 30 | 31 | if not ret: 32 | break 33 | 34 | results = model(frame) 35 | 36 | objects = results.pred[0] 37 | 38 | new_image = np.zeros_like(background_image) 39 | 40 | for obj in objects: 41 | class_id = int(obj[-1]) 42 | x1, y1, x2, y2, _, _ = obj.tolist() 43 | x1, y1, x2, y2 = int(x1), int(y1), int(x2), int(y2) 44 | 45 | # Get the face region from the frame 46 | face = frame[y1-20:y2+8, x1:x2] 47 | 48 | # Resize the face to a maximum size of 120x120 pixels 49 | face = cv2.resize(face, (120, 120)) 50 | 51 | # Create an elliptical mask 52 | mask = np.zeros_like(face) 53 | center = (face.shape[1] // 2, face.shape[0] // 2) 54 | axes = (50, 80) # Semi-major and semi-minor axes lengths 55 | angle = 0 # Rotation angle of the ellipse 56 | color = (255, 255, 255) # Color of the ellipse 57 | thickness = -1 # Thickness (-1 to fill the ellipse) 58 | cv2.ellipse(mask, center, axes, angle, 0, 360, color, thickness) 59 | 60 | # Apply the mask to the face region 61 | face = cv2.bitwise_and(face, mask) 62 | 63 | new_image[65:65 + face.shape[0], 720:720 + face.shape[1]] = face 64 | 65 | # Combine the new image with the background image 66 | result = cv2.add(background_image, new_image) 67 | 68 | cv2.imshow('real', frame) 69 | cv2.imshow('filter', result) 70 | if cv2.waitKey(1) == ord('q'): 71 | break 72 | 73 | capture.release() 74 | cv2.destroyAllWindows() 75 | 76 | 77 | except Exception as e: 78 | print("An error occurred:", str(e)) 79 | 80 | 81 | 82 | def diver_filter_function(model, image_dir): 83 | """ 84 | Function for the diver filter 85 | """ 86 | try: 87 | capture = cv2.VideoCapture(0) 88 | background_image = cv2.imread(image_dir) 89 | background_image = cv2.resize(background_image, (1000, 800)) 90 | 91 | mask0 = np.zeros_like(background_image) 92 | center = (430 + 60, 190 + 60) 93 | axes = (80, 50) # Semi-major and semi-minor axes lengths 94 | angle = 0 # Rotation angle of the ellipse 95 | color = (255, 255, 255) # Color of the ellipse 96 | thickness = -1 # Thickness (-1 to fill the ellipse) 97 | 98 | cv2.ellipse(mask0, center, axes, angle, 0, 360, color, thickness) 99 | mask0 = cv2.bitwise_not(mask0) 100 | background_image = cv2.bitwise_and(background_image, mask0) 101 | 102 | while True: 103 | ret, frame = capture.read() 104 | 105 | if not ret: 106 | break 107 | 108 | results = model(frame) 109 | 110 | objects = results.pred[0] 111 | 112 | new_image = np.zeros_like(background_image) 113 | 114 | for obj in objects: 115 | class_id = int(obj[-1]) 116 | x1, y1, x2, y2, _, _ = obj.tolist() 117 | x1, y1, x2, y2 = int(x1), int(y1), int(x2), int(y2) 118 | 119 | # Get the face region from the frame 120 | face = frame[y1-20:y2+8, x1:x2] 121 | 122 | # Resize the face to a maximum size of 120x120 pixels 123 | face = cv2.resize(face, (120, 120)) 124 | 125 | # Create an elliptical mask 126 | mask = np.zeros_like(face) 127 | center = (face.shape[1] // 2, face.shape[0] // 2) 128 | axes = (80, 50) # Semi-major and semi-minor axes lengths 129 | angle = 0 # Rotation angle of the ellipse 130 | color = (255, 255, 255) # Color of the ellipse 131 | thickness = -1 # Thickness (-1 to fill the ellipse) 132 | cv2.ellipse(mask, center, axes, angle, 0, 360, color, thickness) 133 | 134 | # Apply the mask to the face region 135 | face = cv2.bitwise_and(face, mask) 136 | 137 | new_image[190:190 + face.shape[0], 430:430 + face.shape[1]] = face 138 | 139 | # Combine the new image with the background image 140 | result = cv2.add(background_image, new_image) 141 | 142 | cv2.imshow('real', frame) 143 | cv2.imshow('filter', result) 144 | if cv2.waitKey(1) == ord('q'): 145 | break 146 | 147 | capture.release() 148 | cv2.destroyAllWindows() 149 | 150 | 151 | except Exception as e: 152 | print("An error occurred:", str(e)) 153 | 154 | 155 | 156 | # def start_astro(): 157 | # thread = Thread(target=astronut_filter_function) 158 | # thread.start() 159 | 160 | # def start_diver(): 161 | # thread = Thread(target=diver_filter_function) 162 | # thread.start() 163 | 164 | # def create_buttons(): 165 | # window = tk.Tk() 166 | # window.geometry("600x600") 167 | # button_width = 20 168 | 169 | 170 | # start_button1 = tk.Button(window, text="Use Astronaut filter", command=start_astro, 171 | # font=("Arial", 30), width=button_width, bg="blue", fg="white") 172 | # start_button1.pack() 173 | 174 | # start_button2 = tk.Button(window, text="Use Diver filter", command=start_diver, 175 | # font=("Arial", 30), width=button_width, bg="blue", fg="white") 176 | # start_button2.pack() 177 | 178 | # instructions = tk.Label(window, text="Click on a button to start the corresponding filter.", font=("Arial", 14)) 179 | # instructions.pack(pady=150) 180 | 181 | # window.mainloop() 182 | 183 | # create_buttons() -------------------------------------------------------------------------------- /Remove_background_model/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Remove_background_model/__init__.py -------------------------------------------------------------------------------- /Remove_background_model/__pycache__/FaceDetectCam.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Remove_background_model/__pycache__/FaceDetectCam.cpython-39.pyc -------------------------------------------------------------------------------- /Remove_background_model/__pycache__/RemoveBackgroundCam.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Remove_background_model/__pycache__/RemoveBackgroundCam.cpython-39.pyc -------------------------------------------------------------------------------- /Remove_background_model/__pycache__/__init__.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Remove_background_model/__pycache__/__init__.cpython-39.pyc -------------------------------------------------------------------------------- /Remove_background_model/backgrounds/astro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Remove_background_model/backgrounds/astro.png -------------------------------------------------------------------------------- /Remove_background_model/backgrounds/ocean.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Remove_background_model/backgrounds/ocean.png -------------------------------------------------------------------------------- /Remove_background_model/model_train/HandleImagesFunction.py: -------------------------------------------------------------------------------- 1 | from PIL import Image 2 | import csv 3 | import os 4 | 5 | def get_image_dimensions(image_path): 6 | image = Image.open(image_path) 7 | width, height = image.size 8 | return width, height 9 | 10 | 11 | def convert_labels_to_yolo(csv_file, output_dir, img_dir): 12 | with open(csv_file, 'r') as file: 13 | reader = csv.reader(file) 14 | next(reader) # Skip header row if present 15 | 16 | for row in reader: 17 | image_name, h, w, xmin, ymin, xmax, ymax = row 18 | 19 | # Calculate normalized bounding box coordinates 20 | file_path = os.path.join(img_dir, image_name) 21 | img_width, img_height = get_image_dimensions(file_path) 22 | x_center = (float(xmin) + float(xmax)) / 2 / img_width 23 | y_center = (float(ymin) + float(ymax)) / 2 / img_height 24 | width = (float(xmax) - float(xmin)) / img_width 25 | height = (float(ymax) - float(ymin)) / img_height 26 | 27 | # Write label in YOLO format 28 | label_content = f"0 {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}" 29 | 30 | # Save the label file 31 | image_name_without_ext = os.path.splitext(image_name)[0] 32 | label_file = os.path.join(output_dir, f"{image_name_without_ext}.txt") 33 | 34 | if os.path.exists(label_file): 35 | with open(label_file, 'a') as f: 36 | f.write('\n' + label_content) 37 | else: 38 | with open(label_file, 'w') as f: 39 | f.write(label_content) 40 | 41 | 42 | def delete_last_line(folder_path): 43 | for filename in os.listdir(folder_path): 44 | if filename.endswith('.txt'): # Process only text files 45 | file_path = os.path.join(folder_path, filename) 46 | with open(file_path, 'r') as f: 47 | lines = f.readlines() 48 | 49 | # Remove the last line 50 | lines = lines[:-1] 51 | 52 | with open(file_path, 'w') as f: 53 | f.writelines(lines) -------------------------------------------------------------------------------- /Remove_background_model/model_train/ImageDataProcessor.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | import numpy as np 3 | import seaborn as sns 4 | import os 5 | import random 6 | import zipfile 7 | import shutil 8 | import tensorflow as tf 9 | from sklearn.model_selection import train_test_split 10 | from tensorflow.keras.preprocessing.image import ImageDataGenerator, load_img, img_to_array, array_to_img 11 | 12 | class ImageDataHandler: 13 | """ 14 | A utility class for handling image data, including downloading, splitting into train and test sets, 15 | and augmenting data using Keras' ImageDataGenerator. 16 | 17 | Parameters: 18 | ----------- 19 | url : str 20 | URL to the data zip file to be downloaded. 21 | cache_dir : str, optional 22 | Directory to cache the downloaded data, defaults to current working directory. 23 | 24 | Methods: 25 | -------- 26 | download_data(): 27 | Downloads the data zip file from the given URL and extracts it into a 'datasets' folder. 28 | 29 | split_data(data_dir: str, train_dir: str, test_dir: str, test_size: float): 30 | Splits the data in the `data_dir` directory into training and testing sets, and saves them in `train_dir` 31 | and `test_dir` directories respectively. `test_size` is the proportion of data to be used for testing, 32 | defaults to 0.2. 33 | 34 | data_augment(train_dir: str, rotation_range: int, width_shift_range: float, height_shift_range: float, 35 | shear_range: float, zoom_range: float): 36 | Augments the training data in the `train_dir` directory using Keras' ImageDataGenerator. `rotation_range`, 37 | `width_shift_range`, `height_shift_range`, `shear_range`, and `zoom_range` are the ranges for random image 38 | transformations, as defined by Keras' ImageDataGenerator. 39 | 40 | delete_folder(folder_path: str): 41 | Deletes the folder at the given `folder_path`. 42 | """ 43 | def __init__(self, url, cache_dir='.'): 44 | 45 | self.url = url 46 | self.cache_dir = cache_dir 47 | 48 | def download_data(self): 49 | 50 | data_path = tf.keras.utils.get_file("data.zip", self.url, cache_dir=self.cache_dir) 51 | with zipfile.ZipFile(data_path, 'r') as zip_ref: 52 | zip_ref.extractall('datasets') 53 | 54 | def split_data(self, data_dir, train_dir, test_dir, test_size=0.2): 55 | 56 | for class_name in os.listdir(data_dir): 57 | class_dir = os.path.join(data_dir, class_name) 58 | 59 | train_class_dir = os.path.join(train_dir, class_name) 60 | test_class_dir = os.path.join(test_dir, class_name) 61 | 62 | # Create the class folders in the new data directories 63 | os.makedirs(train_class_dir, exist_ok=True) 64 | os.makedirs(test_class_dir, exist_ok=True) 65 | 66 | # Loop through the images in the class folder 67 | image_paths = [os.path.join(class_dir, img_name) for img_name in os.listdir(class_dir)] 68 | train_paths, test_paths = train_test_split(image_paths, test_size=test_size, random_state=42) 69 | 70 | # Copy the training images to the training directory 71 | for path in train_paths: 72 | filename = os.path.basename(path) 73 | dest_path = os.path.join(train_class_dir, filename) 74 | shutil.copy2(path, dest_path) 75 | 76 | # Copy the testing images to the testing directory 77 | for path in test_paths: 78 | filename = os.path.basename(path) 79 | dest_path = os.path.join(test_class_dir, filename) 80 | shutil.copy2(path, dest_path) 81 | 82 | def data_augment(self, train_dir, rotation_range=40, width_shift_range=0.2, height_shift_range=0.2, shear_range=0.2, zoom_range=0.2): 83 | 84 | class_names = os.listdir(train_dir) 85 | num_images = {} 86 | for class_name in class_names: 87 | num_images[class_name] = len(os.listdir(os.path.join(train_dir, class_name))) 88 | print(f'Number of images in each class: {num_images}') 89 | 90 | # Set the target number of images for each class 91 | target_num = max(num_images.values()) 92 | 93 | # Define an ImageDataGenerator for data augmentation 94 | data_gen = ImageDataGenerator( 95 | rotation_range=rotation_range, 96 | width_shift_range=width_shift_range, 97 | height_shift_range=height_shift_range, 98 | shear_range=shear_range, 99 | zoom_range=zoom_range, 100 | horizontal_flip=True, 101 | fill_mode='nearest') 102 | 103 | # Loop through each class and augment the images 104 | for class_name in class_names: 105 | # Calculate the number of images to generate 106 | num_to_generate = target_num - num_images[class_name] 107 | if num_to_generate <= 0: 108 | continue 109 | print('Number of Images needed to be generated : ',num_to_generate) 110 | 111 | # Set the path to the images in the current class 112 | class_path = os.path.join(train_dir, class_name) 113 | print('images needs to be generated in : ',class_path) 114 | 115 | # Loop through the images in the current class and generate new images 116 | for i, img_name in enumerate(os.listdir(class_path)): 117 | # Load the image and convert it to a numpy array 118 | img_path = os.path.join(class_path, img_name) 119 | img = load_img(img_path, target_size=(224, 224)) 120 | x = img_to_array(img) 121 | 122 | # Generate new images 123 | for j in range(num_to_generate): 124 | # Apply random transformations to the image 125 | params = data_gen.get_random_transform(x.shape) 126 | x_aug = data_gen.apply_transform(x, params) 127 | 128 | # Save the new image 129 | new_img_name = f'{class_name}_{i}_{j}.JPG' 130 | new_img_path = os.path.join(class_path, new_img_name) 131 | img = array_to_img(x_aug) 132 | img.save(new_img_path) 133 | 134 | # Update the number of images in the current class 135 | num_images[class_name] += num_to_generate 136 | break 137 | 138 | print(f'Number of images in each class after data augmentation: {num_images}') 139 | 140 | def delete_folder(self, folder_path): 141 | 142 | shutil.rmtree(folder_path) 143 | 144 | 145 | class ImageGenerator: 146 | """A class for creating image data generators using Keras ImageDataGenerator. 147 | 148 | Attributes: 149 | train_dir (str): Path to the directory containing the training images. 150 | test_dir (str): Path to the directory containing the testing images. 151 | img_height (int): The desired height of the input images. 152 | img_width (int): The desired width of the input images. 153 | batch_size (int): The batch size to use for training and testing. 154 | 155 | Methods: 156 | 157 | create_train_generator(self): 158 | Returns the data generator for training images. 159 | 160 | create_val_generator(self): 161 | Returns the data generator for validation images. 162 | 163 | create_test_generator(self): 164 | Returns the data generator for testing images. 165 | """ 166 | def __init__(self, train_dir, test_dir, img_height=224, img_width=224, batch_size=32): 167 | self.train_dir = train_dir 168 | self.test_dir = test_dir 169 | self.img_height = img_height 170 | self.img_width = img_width 171 | self.batch_size = batch_size 172 | 173 | def create_data_generators(self): 174 | datagen = ImageDataGenerator(rescale=1./255, validation_split=0.2) 175 | 176 | # create train and test data generators 177 | train_datagen = ImageDataGenerator(rescale=1./255) 178 | test_datagen = ImageDataGenerator(rescale=1./255) 179 | 180 | train_generator = train_datagen.flow_from_directory( 181 | self.train_dir, 182 | target_size=(self.img_height, self.img_width), 183 | batch_size=self.batch_size, 184 | class_mode='binary') 185 | 186 | val_generator = datagen.flow_from_directory( 187 | self.train_dir, 188 | target_size=(self.img_height, self.img_width), 189 | batch_size=self.batch_size, 190 | class_mode='binary', 191 | subset='validation') 192 | 193 | test_generator = test_datagen.flow_from_directory( 194 | self.test_dir, 195 | target_size=(self.img_height, self.img_width), 196 | batch_size=self.batch_size, 197 | class_mode='binary') 198 | 199 | return train_generator, val_generator, test_generator 200 | 201 | 202 | class ImagePlotter: 203 | """ 204 | Attributes: 205 | generator: An instance of `tf.keras.preprocessing.image.ImageDataGenerator` used 206 | for generating batches of images. 207 | Methods: 208 | show_images(num_images): Displays a batch of `num_images` images 209 | and 210 | their corresponding labels. 211 | """ 212 | def __init__(self, train_generator): 213 | self.train_generator = train_generator 214 | self.class_names = list(train_generator.class_indices.keys()) 215 | 216 | def plot_images(self): 217 | # Get a batch of images and their corresponding labels from the generator 218 | images, labels = next(self.train_generator) 219 | 220 | # Plot the images and their corresponding labels 221 | fig, axes = plt.subplots(6, 5, figsize=(20, 20)) 222 | axes = axes.ravel() 223 | for i in np.arange(0, 30): 224 | axes[i].imshow(images[i]) 225 | axes[i].set_title(self.class_names[int(labels[i])], color='r') 226 | axes[i].axis('off') 227 | 228 | plt.subplots_adjust(wspace=0.01) 229 | plt.show() -------------------------------------------------------------------------------- /Remove_background_model/model_train/datasets.yaml: -------------------------------------------------------------------------------- 1 | train: /content/datasets/People/data/train/images 2 | val: /content/datasets/People/data/val/images 3 | 4 | nc: 2 5 | names: ['background', 'person'] -------------------------------------------------------------------------------- /Remove_background_model/model_train/detect-person.pt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Remove_background_model/model_train/detect-person.pt -------------------------------------------------------------------------------- /Remove_background_model/model_train/train.py: -------------------------------------------------------------------------------- 1 | from ImageDataProcessor import ImageDataHandler 2 | from HandleImagesFunctions import * 3 | 4 | url = 'https://storage.googleapis.com/kaggle-data-sets/3145890/5442439/bundle/archive.zip?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=gcp-kaggle-com%40kaggle-161607.iam.gserviceaccount.com%2F20230522%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20230522T183243Z&X-Goog-Expires=259200&X-Goog-SignedHeaders=host&X-Goog-Signature=a7980ef172d30c9f39a2b6836a763795842ee19534d544e51bb358fe824060f082e74f82ffef74e2c7b61e286149bac5fcafe24c3cdcae9c42f715d215b53ef34f15ee39740c1880e8e8f6a6df23464a3ce242a70700236485d0f9ca0a68b08024c502ac841b0292375884d35ce4a987a976531a29544ffa3167647c1d67df3091cb6f900bf08502b70d16d4d3816e49f72d7ae71a3930d570edc40303c572389f4d02a6c4be3605d0c4a7a84a6af3bbe714e43fcf7e2384897c0db6636ccbeae4504f94657327d1f45b903ed966fb380d60fb379a4296fb647f897d4fef0273d7182370f94becd7cefbab31826ff72a941275ad7f55755f7f82dc83e0b92314' 5 | 6 | 7 | 8 | data_processor = ImageDataHandler(url=url) 9 | data_processor.download_data() 10 | 11 | json_file_path = '/content/datasets/People/annotations/instances.json' 12 | output_folder = '/content/datasets/People/labels' 13 | 14 | 15 | convert_annotations(json_file_path, output_folder) 16 | 17 | import os 18 | 19 | # Directory containing the images 20 | image_dir = '/content/datasets/People/images' 21 | 22 | for filename in os.listdir(image_dir): 23 | if filename.endswith(('.png', '.jpeg')): 24 | new_filename = os.path.splitext(filename)[0] + '.jpg' 25 | os.rename(os.path.join(image_dir, filename), os.path.join(image_dir, new_filename)) 26 | 27 | image_dir = '/content/datasets/People/images' 28 | 29 | extensions = set() 30 | for filename in os.listdir(image_dir): 31 | if os.path.isfile(os.path.join(image_dir, filename)): 32 | ext = os.path.splitext(filename)[1].lower() 33 | if ext.startswith('.'): 34 | ext = ext[1:] 35 | extensions.add(ext) 36 | 37 | # Print unique extensions 38 | print("Unique image extensions:") 39 | for ext in extensions: 40 | print(ext) 41 | 42 | labels_dir = '/content/datasets/People/labels' # Directory containing label files 43 | images_dir = '/content/datasets/People/images' # Directory containing image files 44 | 45 | normalize_label_coordinates(labels_dir, images_dir) 46 | 47 | image_folder = '/content/datasets/People/images' 48 | label_folder = '/content/datasets/People/labels' 49 | output_folder = '/content/datasets/People/data' 50 | train_ratio = 0.8 51 | 52 | split_data(image_folder, label_folder, train_ratio, output_folder) 53 | 54 | train_dir = '/content/datasets/People/data/train/images' 55 | val_dir = '/content/datasets/People/data/val/images' 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Remove_background_model/model_train/train_cmd.txt: -------------------------------------------------------------------------------- 1 | git clone https://github.com/ultralytics/yolov5.git 2 | 3 | %cd yolov5/ 4 | 5 | pip install -r requirements.txt 6 | 7 | wget https://github.com/ultralytics/yolov5/releases/download/v6.0/yolov5s.pt 8 | 9 | python train.py --img 416 --batch 8 --epochs 50 --data /content/datasets/People/data/datasets.yaml --weights /content/yolov5/yolov5s.pt -------------------------------------------------------------------------------- /Style_Transfer_model/Result_images/image_0epochs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Style_Transfer_model/Result_images/image_0epochs.png -------------------------------------------------------------------------------- /Style_Transfer_model/Result_images/image_1000epochs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Style_Transfer_model/Result_images/image_1000epochs.png -------------------------------------------------------------------------------- /Style_Transfer_model/Result_images/image_2000epochs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Style_Transfer_model/Result_images/image_2000epochs.png -------------------------------------------------------------------------------- /Style_Transfer_model/Result_images/image_3000epochs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Style_Transfer_model/Result_images/image_3000epochs.png -------------------------------------------------------------------------------- /Style_Transfer_model/Result_images/image_4000epochs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Style_Transfer_model/Result_images/image_4000epochs.png -------------------------------------------------------------------------------- /Style_Transfer_model/StyleTransferCam.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import tensorflow_hub 3 | import tensorflow as tf 4 | import matplotlib.pyplot as plt 5 | import numpy as np 6 | from PIL import Image 7 | import tkinter as tk 8 | from threading import Thread 9 | 10 | 11 | def image_load(image_path, resize=(224,224), rotate=0): 12 | image = Image.open(image_path) 13 | if image.format != 'PNG': 14 | new_image_path = image_path.split('.')[0] + '.PNG' 15 | image.save(new_image_path, format='PNG') 16 | image = Image.open(new_image_path) 17 | image = image.convert('RGB') 18 | image = image.resize(resize) 19 | image = image.rotate(rotate) 20 | return image 21 | 22 | def image_process(image): 23 | image = np.array(image) 24 | image = image.astype('float32') / 255.0 25 | image = np.expand_dims(image, axis=0) 26 | return image 27 | 28 | def make_style(img_dir, crop=True, result_dims=(300,300), num_copies=4): 29 | img = Image.open(img_dir) 30 | img = img.resize((100, 100)) 31 | 32 | result_width = result_dims[0] 33 | result_height = result_dims[1] 34 | result = Image.new('RGB', (result_width, result_height)) 35 | 36 | width, height = result.size 37 | new_size = (int(width/2), int(height/2)) 38 | 39 | for i in range(num_copies): 40 | for j in range(num_copies): 41 | result.paste(img, (i * 100, j * 100)) 42 | 43 | if crop==True: 44 | crop_size = (140, 140) 45 | left = int(new_size[0]/2 - crop_size[0]/2) 46 | right = int(new_size[0]/2 + crop_size[0]/2) 47 | top = int(new_size[1]/2 - crop_size[1]/2) 48 | bottom = int(new_size[1]/2 + crop_size[1]/2) 49 | result = result.crop((left, top, right, bottom)) 50 | result = result.resize((120,120)) 51 | style = image_process(result) 52 | return style 53 | 54 | else: 55 | style = image_process(result) 56 | return style 57 | 58 | 59 | stylize = 0 60 | def mouse_callback(event, x, y, flags, param): 61 | global stylize 62 | if event == cv2.EVENT_LBUTTONDOWN: 63 | if 20 <= x <= 50: 64 | stylize = (y - 20) // 40 + 1 65 | if stylize > 6: 66 | stylize = 0 67 | else: 68 | stylize = 0 69 | 70 | def run_style_transfer(model, styles): 71 | # Create a named window and set the mouse callback function 72 | cv2.namedWindow('Style Transfer Options') 73 | cv2.setMouseCallback('Style Transfer Options', mouse_callback) 74 | capture = cv2.VideoCapture(0) 75 | 76 | while True: 77 | ret, frame = capture.read() 78 | 79 | if frame is None or not ret: 80 | capture.release() 81 | capture = cv2.VideoCapture(0) 82 | continue 83 | 84 | # Draw a colored square in the options window 85 | options_window = np.ones((400, 400, 3), dtype=np.uint8) * 255 86 | options = [ 87 | ((60, 35), 'Blue curves style', (168, 113, 50)), 88 | ((60, 75), 'Van gogh painting style', (120, 53, 32)), 89 | ((60, 115), 'Waves style', (222, 196, 27)), 90 | ((60, 155), 'Red edges style', (16, 25, 148)), 91 | ((60, 195), 'Flowers style', (186, 25, 145)), 92 | ((60, 235), 'Yellow flow style', (19, 162, 214)) 93 | ] 94 | for i, ((x, y), text, color) in enumerate(options): 95 | options_window[20 + i * 40:50 + i * 40, 20:50] = color 96 | cv2.putText(options_window, text, (x, y), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2) 97 | 98 | instruction1 = """Choose any style by clicking on the color""" 99 | instruction2 = """infront of it.....""" 100 | instruction3 = """if you want to clear the style,""" 101 | instruction4 = """just press in any place on the white screan""" 102 | cv2.putText(options_window, instruction1, (20, 300), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,0,0), 1) 103 | cv2.putText(options_window, instruction2, (20, 320), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,0,0), 1) 104 | cv2.putText(options_window, instruction3, (20, 340), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,0,0), 1) 105 | cv2.putText(options_window, instruction4, (20, 360), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,0,0), 1) 106 | cv2.rectangle(options_window, (10, 280), (390, 380), (0, 0, 0), 2) 107 | cv2.imshow('Style Transfer Options', options_window) 108 | 109 | resized_frame = cv2.resize(frame, (400, 400)) 110 | resized_frame = tf.convert_to_tensor(resized_frame, dtype=tf.float32) / 255.0 111 | resized_frame = tf.expand_dims(resized_frame, axis=0) 112 | 113 | if stylize != 0: 114 | stylized_image1 = model(resized_frame, tf.constant(styles[stylize - 1]))[0] 115 | stylized_image = (1 * stylized_image1 + 150 * image_process(resized_frame)) 116 | stylized_image_rgb = cv2.cvtColor(np.squeeze(stylized_image), cv2.COLOR_BGR2RGB) 117 | cv2.imshow('styled', cv2.flip(stylized_image_rgb,1)) 118 | else: 119 | cv2.imshow('styled', cv2.flip(frame,1)) 120 | 121 | cv2.imshow('real', cv2.flip(frame,1)) 122 | if cv2.waitKey(1) == ord('q'): 123 | break 124 | 125 | capture.release() 126 | cv2.destroyAllWindows() -------------------------------------------------------------------------------- /Style_Transfer_model/StyleTransferFunctions.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import tensorflow as tf 3 | from tensorflow import keras 4 | from tensorflow.keras.applications import vgg19 5 | from keras.preprocessing import image as keras_image 6 | from PIL import Image 7 | from keras.models import Model 8 | import json 9 | from tensorflow.keras.layers import Input 10 | 11 | 12 | width, height = keras.utils.load_img('/content/base_image.jpg').size 13 | img_nrows = 400 14 | img_ncols = int(width * img_nrows / height) 15 | 16 | 17 | 18 | def preprocess_image(image_path): 19 | # Util function to open, resize and format pictures into appropriate tensors 20 | img = keras.utils.load_img( 21 | image_path, target_size=(img_nrows, img_ncols) 22 | ) 23 | img = keras.utils.img_to_array(img) 24 | img = np.expand_dims(img, axis=0) 25 | img = vgg19.preprocess_input(img) 26 | return tf.convert_to_tensor(img) 27 | 28 | 29 | def deprocess_image(x): 30 | # Util function to convert a tensor into a valid image 31 | x = x.reshape((img_nrows, img_ncols, 3)) 32 | # Remove zero-center by mean pixel 33 | x[:, :, 0] += 103.939 34 | x[:, :, 1] += 116.779 35 | x[:, :, 2] += 123.68 36 | # 'BGR'->'RGB' 37 | x = x[:, :, ::-1] 38 | x = np.clip(x, 0, 255).astype("uint8") 39 | return x 40 | 41 | def gram_matrix(x): 42 | x = tf.transpose(x, (2, 0, 1)) 43 | features = tf.reshape(x, (tf.shape(x)[0], -1)) 44 | gram = tf.matmul(features, tf.transpose(features)) 45 | return gram 46 | 47 | def style_loss(style, combination): 48 | S = gram_matrix(style) 49 | C = gram_matrix(combination) 50 | channels = 3 51 | size = img_nrows * img_ncols 52 | return tf.reduce_sum(tf.square(S - C)) / (4.0 * (channels**2) * (size**2)) 53 | 54 | 55 | def content_loss(base, combination): 56 | return tf.reduce_sum(tf.square(combination - base)) 57 | 58 | 59 | def total_variation_loss(x): 60 | a = tf.square( 61 | x[:, : img_nrows - 1, : img_ncols - 1, :] - x[:, 1:, : img_ncols - 1, :] 62 | ) 63 | b = tf.square( 64 | x[:, : img_nrows - 1, : img_ncols - 1, :] - x[:, : img_nrows - 1, 1:, :] 65 | ) 66 | return tf.reduce_sum(tf.pow(a + b, 1.25)) 67 | 68 | 69 | def compute_loss(combination_image, base_image, style_reference_image): 70 | input_tensor = tf.concat( 71 | [base_image, style_reference_image, combination_image], axis=0 72 | ) 73 | features = feature_extractor(input_tensor) 74 | 75 | # Initialize the loss 76 | loss = tf.zeros(shape=()) 77 | 78 | # Add content loss 79 | layer_features = features[content_layer_name] 80 | base_image_features = layer_features[0, :, :, :] 81 | combination_features = layer_features[2, :, :, :] 82 | loss = loss + content_weight * content_loss( 83 | base_image_features, combination_features 84 | ) 85 | # Add style loss 86 | for layer_name in style_layer_names: 87 | layer_features = features[layer_name] 88 | style_reference_features = layer_features[1, :, :, :] 89 | combination_features = layer_features[2, :, :, :] 90 | sl = style_loss(style_reference_features, combination_features) 91 | loss += (style_weight / len(style_layer_names)) * sl 92 | 93 | # Add total variation loss 94 | loss += total_variation_weight * total_variation_loss(combination_image) 95 | return loss 96 | 97 | 98 | @tf.function 99 | def compute_loss_and_grads(combination_image, base_image, style_reference_image): 100 | with tf.GradientTape() as tape: 101 | loss = compute_loss(combination_image, base_image, style_reference_image) 102 | grads = tape.gradient(loss, combination_image) 103 | return loss, grads 104 | 105 | 106 | -------------------------------------------------------------------------------- /Style_Transfer_model/Style_images/s1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Style_Transfer_model/Style_images/s1.png -------------------------------------------------------------------------------- /Style_Transfer_model/Style_images/s2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Style_Transfer_model/Style_images/s2.png -------------------------------------------------------------------------------- /Style_Transfer_model/Style_images/s3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Style_Transfer_model/Style_images/s3.png -------------------------------------------------------------------------------- /Style_Transfer_model/Style_images/s4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Style_Transfer_model/Style_images/s4.png -------------------------------------------------------------------------------- /Style_Transfer_model/Style_images/s5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Style_Transfer_model/Style_images/s5.png -------------------------------------------------------------------------------- /Style_Transfer_model/Style_images/s6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Style_Transfer_model/Style_images/s6.png -------------------------------------------------------------------------------- /Style_Transfer_model/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Style_Transfer_model/__init__.py -------------------------------------------------------------------------------- /Style_Transfer_model/__pycache__/StyleTransferCam.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Style_Transfer_model/__pycache__/StyleTransferCam.cpython-39.pyc -------------------------------------------------------------------------------- /Style_Transfer_model/__pycache__/__init__.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Style_Transfer_model/__pycache__/__init__.cpython-39.pyc -------------------------------------------------------------------------------- /Style_Transfer_model/train.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import tensorflow as tf 3 | from tensorflow import keras 4 | from tensorflow.keras.applications import vgg19 5 | from keras.preprocessing import image as keras_image 6 | from PIL import Image 7 | import IPython.display as display 8 | from keras.preprocessing import image as keras_image 9 | from keras.models import Model 10 | import json 11 | import tensorflow as tf 12 | from tensorflow.keras.layers import Input 13 | 14 | from StyleTransferFunctions import * 15 | 16 | base_image_path = '/content/base_image.jpg' 17 | style_reference_image_path = '/content/style_image.png' 18 | result_prefix = "image_generated" 19 | 20 | # Weights of the different loss components 21 | total_variation_weight = 1e-6 22 | style_weight = 1e-6 23 | content_weight = 2.5e-8 24 | 25 | 26 | # Dimensions of the generated picture. 27 | width, height = keras.utils.load_img('/content/base_image.jpg').size 28 | img_nrows = 400 29 | img_ncols = int(width * img_nrows / height) 30 | 31 | 32 | base_image = Image.open(base_image_path) 33 | base_image = base_image.resize((300, 300)) 34 | 35 | 36 | model = vgg19.VGG19(weights="imagenet", include_top=False) 37 | 38 | outputs_dict = dict([(layer.name, layer.output) for layer in model.layers]) 39 | 40 | feature_extractor = keras.Model(inputs=model.inputs, outputs=outputs_dict) 41 | 42 | style_layer_names = [ 43 | "block1_conv1", 44 | "block2_conv1", 45 | "block3_conv1", 46 | "block4_conv1", 47 | "block5_conv1", 48 | ] 49 | 50 | content_layer_name = "block5_conv2" 51 | 52 | 53 | def compute_loss(combination_image, base_image, style_reference_image): 54 | input_tensor = tf.concat( 55 | [base_image, style_reference_image, combination_image], axis=0 56 | ) 57 | features = feature_extractor(input_tensor) 58 | 59 | # Initialize the loss 60 | loss = tf.zeros(shape=()) 61 | 62 | # Add content loss 63 | layer_features = features[content_layer_name] 64 | base_image_features = layer_features[0, :, :, :] 65 | combination_features = layer_features[2, :, :, :] 66 | loss = loss + content_weight * content_loss( 67 | base_image_features, combination_features 68 | ) 69 | # Add style loss 70 | for layer_name in style_layer_names: 71 | layer_features = features[layer_name] 72 | style_reference_features = layer_features[1, :, :, :] 73 | combination_features = layer_features[2, :, :, :] 74 | sl = style_loss(style_reference_features, combination_features) 75 | loss += (style_weight / len(style_layer_names)) * sl 76 | 77 | # Add total variation loss 78 | loss += total_variation_weight * total_variation_loss(combination_image) 79 | return loss 80 | 81 | 82 | 83 | @tf.function 84 | def compute_loss_and_grads(combination_image, base_image, style_reference_image): 85 | with tf.GradientTape() as tape: 86 | loss = compute_loss(combination_image, base_image, style_reference_image) 87 | grads = tape.gradient(loss, combination_image) 88 | return loss, grads 89 | 90 | 91 | optimizer = keras.optimizers.SGD( 92 | keras.optimizers.schedules.ExponentialDecay( 93 | initial_learning_rate=100.0, decay_steps=100, decay_rate=0.96 94 | ) 95 | ) 96 | 97 | base_image = preprocess_image(base_image_path) 98 | style_reference_image = preprocess_image(style_reference_image_path) 99 | combination_image = tf.Variable(preprocess_image(base_image_path)) 100 | 101 | iterations = 4000 102 | for i in range(1, iterations + 1): 103 | loss, grads = compute_loss_and_grads( 104 | combination_image, base_image, style_reference_image 105 | ) 106 | optimizer.apply_gradients([(grads, combination_image)]) 107 | if i % 100 == 0: 108 | print("Iteration %d: loss=%.2f" % (i, loss)) 109 | img = deprocess_image(combination_image.numpy()) 110 | fname = result_prefix + "_at_iteration_%d.png" % i 111 | keras.utils.save_img(fname, img) 112 | 113 | content_input = Input(tensor=base_image) 114 | style_input = Input(tensor=combination_image) 115 | 116 | # Define the model architecture and get the combined model 117 | model = Model(inputs=[content_input], outputs=[style_input]) 118 | 119 | # Save the model's weights and architecture 120 | model.save_weights('model_weights.h5') 121 | with open('model_architecture.json', 'w') as f: 122 | f.write(model.to_json()) 123 | 124 | # Save the input image paths for reference 125 | input_paths = {'content_image': base_image_path, 'style_image': style_reference_image_path} 126 | with open('input_paths.json', 'w') as f: 127 | json.dump(input_paths, f) 128 | 129 | -------------------------------------------------------------------------------- /Style_Transfer_model/train_images/base_image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Style_Transfer_model/train_images/base_image.jpg -------------------------------------------------------------------------------- /Style_Transfer_model/train_images/style_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Style_Transfer_model/train_images/style_image.png -------------------------------------------------------------------------------- /Style_Transfer_model/trained_net/input_paths.json: -------------------------------------------------------------------------------- 1 | {"content_image": "/content/base_image.jpg", "style_image": "/content/style_image.png"} -------------------------------------------------------------------------------- /Style_Transfer_model/trained_net/model_architecture.json: -------------------------------------------------------------------------------- 1 | {"class_name": "Functional", "config": {"name": "model_1", "trainable": true, "layers": [{"class_name": "InputLayer", "config": {"batch_input_shape": [1, 400, 710, 3], "dtype": "float32", "sparse": false, "ragged": false, "name": "input_2"}, "name": "input_2", "inbound_nodes": []}, {"class_name": "InputLayer", "config": {"batch_input_shape": [1, 400, 710, 3], "dtype": "float32", "sparse": false, "ragged": false, "name": "input_3"}, "name": "input_3", "inbound_nodes": []}], "input_layers": [["input_2", 0, 0]], "output_layers": [["input_3", 0, 0]]}, "keras_version": "2.12.0", "backend": "tensorflow"} -------------------------------------------------------------------------------- /Style_Transfer_model/trained_net/model_weights.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahmed-Hereiz/Computer-Vision-Filters/9c6520ef86767e9cc042dd7c7c37e6e41366279b/Style_Transfer_model/trained_net/model_weights.h5 -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import torch 2 | import pandas as pd 3 | import numpy as np 4 | import matplotlib.pyplot as plt 5 | import cv2 6 | from PIL import Image 7 | import tensorflow as tf 8 | import tkinter as tk 9 | import threading 10 | from threading import Thread 11 | from colorama import Fore 12 | 13 | 14 | # Load Images, models and styles : 15 | from ImportScript import load_models, load_style_images, load_background_images, load_add_filter_images 16 | 17 | # Load models: 18 | model, model_detect, model_t_l, class_names = load_models() 19 | 20 | # load styles for neural style transfer: 21 | styles = load_style_images() 22 | 23 | # laod background images for background removal: 24 | astro_image_dir, diver_image_dir = load_background_images() 25 | 26 | # load filters to be added to images: 27 | glasses_img_dir, nose_img_dir, hair_img_dir = load_add_filter_images() 28 | 29 | # Import my functions form it's directories : 30 | from Remove_background_model.RemoveBackgroundCam import * 31 | from Landmark_detection_model.LandmarkDetectCam import * 32 | from Style_Transfer_model.StyleTransferCam import * 33 | from Person_detect_model.PersonDetectCam import * 34 | from Filter_images.ApplyFiltersCam import * 35 | 36 | 37 | def start_count(): 38 | thread = Thread(target=count_people, args=(model_detect, class_names)) 39 | thread.start() 40 | 41 | def start_astro(): 42 | thread = Thread(target=astronut_filter_function, args=(model_detect, astro_image_dir)) 43 | thread.start() 44 | 45 | def start_diver(): 46 | thread = Thread(target=diver_filter_function, args=(model_detect, diver_image_dir)) 47 | thread.start() 48 | 49 | def start_style_transfer(): 50 | thread = Thread(target=run_style_transfer, args=(model_t_l, styles)) 51 | thread.start() 52 | 53 | def start_add_filters(): 54 | window = tk.Toplevel(root) 55 | checkbox1_var = tk.IntVar() 56 | checkbox2_var = tk.IntVar() 57 | checkbox3_var = tk.IntVar() 58 | run_final_filters(window, checkbox1_var, checkbox2_var, checkbox3_var, 59 | model_detect, model, glasses_img_dir, nose_img_dir, hair_img_dir) 60 | 61 | def start_cartoon_frame(): 62 | thread = Thread(target=apply_stylify_filters, args=(apply_cartoon_effect, "cartoon Frame")) 63 | thread.start() 64 | 65 | def start_sketch_frame(): 66 | thread = Thread(target=apply_stylify_filters, args=(apply_pencil_sketch_effect, "Pencil Sketched Frame")) 67 | thread.start() 68 | 69 | def start_edges_frame(): 70 | thread = Thread(target=apply_stylify_filters, args=(apply_sobel_edges, "Edges Frame")) 71 | thread.start() 72 | 73 | def start_paint_frame(): 74 | thread = Thread(target=apply_stylify_filters, args=(apply_painting_effect, "Painted Frame")) 75 | thread.start() 76 | 77 | def start_remove_backgrounds(): 78 | window = tk.Tk() 79 | window.geometry("600x600") 80 | button_width = 20 81 | 82 | start_button1 = tk.Button(window, text="Use Astronaut background", 83 | command=start_astro, font=("Arial", 30), 84 | width=button_width, bg="blue", fg="white") 85 | start_button1.pack(pady=10) 86 | 87 | start_button2 = tk.Button(window, text="Use Diver background", 88 | command=start_diver, font=("Arial", 30), 89 | width=button_width, bg="blue", fg="white") 90 | start_button2.pack(pady=10) 91 | 92 | instructions = tk.Label(window, text="Click on a button to start the corresponding Background Removal.", 93 | font=("Arial", 14)) 94 | instructions.pack(pady=100) 95 | 96 | window.mainloop() 97 | 98 | def start_stylify_backgrounds(): 99 | window = tk.Toplevel(root) 100 | window.geometry("600x600") 101 | button_width = 20 102 | 103 | start_button1 = tk.Button(window, text="Cartoon Filter", 104 | command=start_cartoon_frame, font=("Arial", 30), 105 | width=button_width, bg="blue", fg="white") 106 | start_button1.pack(pady=10) 107 | 108 | start_button2 = tk.Button(window, text="Pencil Sketch Filter", 109 | command=start_sketch_frame, font=("Arial", 30), 110 | width=button_width, bg="blue", fg="white") 111 | start_button2.pack(pady=10) 112 | 113 | start_button3 = tk.Button(window, text="Edges Filter", 114 | command=start_edges_frame, font=("Arial", 30), 115 | width=button_width, bg="blue", fg="white") 116 | start_button3.pack(pady=10) 117 | 118 | start_button4 = tk.Button(window, text="Painting Filter", 119 | command=start_paint_frame, font=("Arial", 30), 120 | width=button_width, bg="blue", fg="white") 121 | start_button4.pack(pady=10) 122 | 123 | instructions = tk.Label(window, text="Click on a button to start the corresponding filter.", 124 | font=("Arial", 14)) 125 | instructions.pack(pady=90) 126 | 127 | 128 | print(Fore.LIGHTBLUE_EX, "\nOpening GUI....") 129 | root = tk.Tk() 130 | root.geometry("650x650") 131 | button_width = 25 132 | 133 | start_button1m = tk.Button(root, text="Count number of people", command=start_count, font=("Arial", 30), width=button_width) 134 | start_button1m.pack(pady=3) 135 | 136 | start_button2m = tk.Button(root, text="Neural Style Transfer", command=start_style_transfer, font=("Arial", 30), width=button_width) 137 | start_button2m.pack(pady=3) 138 | 139 | start_button3m = tk.Button(root, text="Remove Background", command=start_remove_backgrounds, font=("Arial", 30), width=button_width) 140 | start_button3m.pack(pady=3) 141 | 142 | start_button4m = tk.Button(root, text="Add Filters", command=start_add_filters, font=("Arial", 30), width=button_width) 143 | start_button4m.pack(pady=3) 144 | 145 | start_button5m = tk.Button(root, text="Apply Stylify Filters", command=start_stylify_backgrounds, font=("Arial", 30), width=button_width) 146 | start_button5m.pack(pady=3) 147 | 148 | instructions = tk.Label(root, text="Choose the task by clicking on the corresponding button.", font=("Arial", 14)) 149 | instructions.pack(pady=50) 150 | 151 | root.mainloop() 152 | print(Fore.LIGHTBLUE_EX, "GUI Closed :)") 153 | --------------------------------------------------------------------------------