├── 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 |
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 |

21 |

22 |

23 |

24 |

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 |

30 |

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 |

37 |

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 |
48 |
49 | ## Apply Stylish Filters :
50 | ### This is Image processing filters that I made using `OpenCV`, here is the outputs :
51 |
52 |
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 |
--------------------------------------------------------------------------------