LapStore commited on
Commit
ceb119d
1 Parent(s): b1f46e5
Files changed (4) hide show
  1. app.py +3 -10
  2. index.html +14 -0
  3. requirements.txt +4 -0
  4. server.py +224 -0
app.py CHANGED
@@ -8,23 +8,16 @@ from PIL import ImageOps,Image ,ImageFilter
8
  import matplotlib.pyplot as plt
9
  import numpy as np
10
  import ast
 
 
11
  #http://localhost:8000
12
  app = FastAPI()
13
 
14
  # Root route
15
  @app.get('/')
16
- def hello_world():
17
  return "Hello World taha"
18
 
19
- def get_segment_image(raw_image):
20
- #pipe = pipeline("image-segmentation", model="Intel/dpt-large-ade")
21
- #output = pipe(raw_image, points_per_batch=32)
22
- #return output
23
- pass
24
-
25
- def get_supported_segmentation(output,supported_types):
26
- return [obj for obj in output if (obj['label'] in supported_types)]
27
-
28
 
29
  @app.post('/predict')
30
  async def predict(supported_types_str: str = Form(),age: str = Form() , file: UploadFile = File(...)):
 
8
  import matplotlib.pyplot as plt
9
  import numpy as np
10
  import ast
11
+ import server
12
+
13
  #http://localhost:8000
14
  app = FastAPI()
15
 
16
  # Root route
17
  @app.get('/')
18
+ def main():
19
  return "Hello World taha"
20
 
 
 
 
 
 
 
 
 
 
21
 
22
  @app.post('/predict')
23
  async def predict(supported_types_str: str = Form(),age: str = Form() , file: UploadFile = File(...)):
index.html ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <html>
2
+ <body bgcolor="#00cccc">
3
+ <center>
4
+ <br><br><br>
5
+ <form action="https://taha454-backg.hf.space/predict" method="post" enctype="multipart/form-data">
6
+ <p><h3>Enter Image:</h3></p>
7
+ Name :<p><input type="text" name="supported_types_str" /></p><br>
8
+ Age :<p><input type="text" name="age" /></p><br>
9
+ File : <input type="file" name="file" required><br><br>
10
+ <p><input type="submit" value="submit" /></p>
11
+ </form>
12
+ </center>
13
+ </body>
14
+ </html>
requirements.txt CHANGED
@@ -5,3 +5,7 @@ transformers
5
  matplotlib
6
  numpy
7
  python-multipart
 
 
 
 
 
5
  matplotlib
6
  numpy
7
  python-multipart
8
+ PIL
9
+ ultralytics
10
+ cv2
11
+
server.py ADDED
@@ -0,0 +1,224 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import PIL
2
+ from PIL import ImageDraw, ImageFont, Image ,ImageOps ,ImageFilter
3
+ from ultralytics import YOLO
4
+ import warnings
5
+ import cv2
6
+ import numpy as np
7
+ import subprocess
8
+ import os
9
+ import matplotlib.pyplot as plt
10
+
11
+ warnings.filterwarnings("ignore", category=FutureWarning)
12
+
13
+ class SegmenterBackground():
14
+ def __init__(self) -> None:
15
+ self.segment_names = {} # This dictionary will store names for segments across multiple inferences
16
+ self.person=['person']
17
+ self.animal=[ 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow', 'elephant', 'bear','zebra', 'giraffe']
18
+ self.drive=['bicycle','car','motorcycle', 'airplane', 'bus', 'train','truck','boat']
19
+
20
+
21
+
22
+ def predict_image(self,raw_image: Image):
23
+ model = YOLO("yolov8n-seg.pt")
24
+ class_names = model.names
25
+ results = model(raw_image)
26
+ return results, class_names
27
+
28
+
29
+
30
+ def assign_segment_name(self,label, segment_id):
31
+ """ Assigns a unique name for each detected segment (e.g., Person 1, Person 2). """
32
+ if label not in self.segment_names:
33
+ self.segment_names[label] = {}
34
+
35
+ if segment_id not in self.segment_names[label]:
36
+ segment_count = len(self.segment_names[label]) + 1
37
+ self.segment_names[label][segment_id] = f"{label} {segment_count}"
38
+
39
+ return self.segment_names[label][segment_id]
40
+
41
+
42
+ def putMaskImage(self,raw_image,masks,background_image="remove",blur_radius=23):
43
+ combined_mask = np.max(masks, axis=0)
44
+
45
+ # Create mask for areas to replace
46
+ mask = combined_mask == True
47
+
48
+ # Ensure the mask has the same shape as the raw image (broadcast the mask to RGB channels)
49
+ mask_rgb = np.stack([mask] * 3, axis=-1)
50
+
51
+ # Initialize the output array as a copy of the background image
52
+ ##outpt = np.array(background_image.copy())
53
+ if type(background_image)==PIL.Image.Image: # not PIL.JpegImagePlugin.JpegImageFile as resized
54
+ outpt = np.array(background_image.copy())
55
+ elif(background_image=="cam"):
56
+ outpt=np.array(raw_image.filter(ImageFilter.GaussianBlur(radius=blur_radius)))
57
+ else:#default ,say on "remove"
58
+ outpt=np.zeros_like(raw_image)
59
+
60
+ # Replace the background in the output image with the raw image where the mask is True
61
+ outpt[mask_rgb] = np.array(raw_image)[mask_rgb]
62
+
63
+ # Resize the output for better experience
64
+ outpt = Image.fromarray(outpt)
65
+
66
+ return outpt
67
+
68
+
69
+ def getFont(self):
70
+ try:
71
+ font = ImageFont.truetype("arial.ttf", size=20)
72
+ except IOError:
73
+ font = ImageFont.load_default()
74
+ return font
75
+
76
+ def Back_step1(self,raw_image: Image, background_image: Image,blur_radius=23):
77
+ org_size = raw_image.size
78
+ raw_image = raw_image.resize((640, 480))
79
+ if type(background_image) == PIL.JpegImagePlugin.JpegImageFile:
80
+ background_image = background_image.resize((640, 480))
81
+ label_counter = []
82
+
83
+
84
+ results, class_names = self.predict_image(raw_image)
85
+
86
+ masks = [results[0].masks.data[i].cpu().numpy() for i in range(len(results[0].masks.data))]
87
+
88
+ ##### put masks on image
89
+ outpt = self.putMaskImage(raw_image,masks,background_image,blur_radius)
90
+
91
+ # Draw bounding boxes and labels
92
+ font=self.getFont()
93
+ draw = ImageDraw.Draw(outpt)
94
+
95
+
96
+
97
+ for box, label, seg_id in zip(results[0].boxes.xyxy.cpu().numpy(),
98
+ results[0].boxes.cls.cpu().numpy(),
99
+ range(len(results[0].boxes))): # segment_id for each box
100
+ label_name = class_names[int(label)]
101
+
102
+ # Assign a unique name for each detected object based on its segment
103
+ current_label = self.assign_segment_name(label_name, seg_id)
104
+
105
+ x1, y1, x2, y2 = map(int, box)
106
+
107
+ draw.rectangle([x1, y1, x2, y2], outline="red", width=2)
108
+
109
+ draw.text((x1, y1), current_label+" " + str(seg_id), fill="black", font=font)
110
+
111
+ label_counter.append(current_label)
112
+
113
+ return outpt.resize(org_size), label_counter
114
+
115
+
116
+ def Back_step2(self,raw_image:Image,background_image:Image,things_replace:list,blur_radius=23):
117
+ org_size = raw_image.size
118
+ raw_image = raw_image.resize((640, 480))
119
+ print(type(background_image))
120
+ if type(background_image)==PIL.JpegImagePlugin.JpegImageFile:
121
+ background_image = background_image.resize((640, 480))
122
+
123
+
124
+ results, class_names = self.predict_image(raw_image)
125
+
126
+ masks=[]
127
+ for segm, label,seg_id in zip(results[0].masks.data,results[0].boxes.cls.cpu().numpy(),range(len(results[0].boxes))):
128
+ label_name = class_names[int(label)]
129
+ current_label = self.assign_segment_name(label_name, seg_id)
130
+
131
+ if current_label in things_replace:
132
+ masks.append(segm.cpu().numpy())
133
+
134
+ masked_image=self.putMaskImage(raw_image,masks,background_image,blur_radius)
135
+ return masked_image.resize(org_size)
136
+
137
+
138
+
139
+ def get_labels(self,kind_back):
140
+ list_output=[]
141
+
142
+ if ('person' in kind_back):
143
+ list_output=list_output + self.person
144
+ if ('animal' in kind_back):
145
+ list_output=list_output + self.animal
146
+ if ('drive' in kind_back):
147
+ list_output=list_output + self.drive
148
+
149
+ return list_output
150
+
151
+
152
+ def Back_video_step1(self,video_path,output_path,background_image,kind_back,blur_radius=35):#background_image,what_remove,blur_radius=23): # back_image and video? #what_remove if many person it is not identify so same
153
+ cap = cv2.VideoCapture(video_path)
154
+
155
+ # Get video properties
156
+ frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
157
+ frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
158
+ fps = int(cap.get(cv2.CAP_PROP_FPS))
159
+ #number_frames= int(cv2.CAP_PROP_FRAME_COUNT)
160
+
161
+ # Define the codec and create VideoWriter object to save the output video
162
+ fourcc = cv2.VideoWriter_fourcc(*'XVID')
163
+ out = cv2.VideoWriter(output_path, fourcc, fps, (frame_width, frame_height))
164
+ if isinstance(background_image, Image.Image):
165
+ background_image = background_image.resize((640, 480))
166
+
167
+
168
+ sound_tmp_file='audio.mp3'
169
+ if os.path.exists(sound_tmp_file):# to not give error
170
+ os.remove(sound_tmp_file)
171
+ subprocess.run(['ffmpeg', '-i', video_path, '-q:a', '0', '-map', 'a',sound_tmp_file])
172
+ else:
173
+ subprocess.run(['ffmpeg', '-i', video_path, '-q:a', '0', '-map', 'a',sound_tmp_file])
174
+
175
+
176
+
177
+ i=0
178
+ while True:
179
+
180
+ ret, frame = cap.read()
181
+ if not ret:
182
+ break # End of video
183
+
184
+ # Convert the current frame to RGB
185
+ frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
186
+ frame_rgb = Image.fromarray(np.array(frame_rgb))
187
+ org_size = frame_rgb.size
188
+ frame_rgb = frame_rgb.resize((640, 480))
189
+
190
+ results,class_names = self.predict_image(frame_rgb)
191
+
192
+ masks=[]
193
+
194
+ things_replace=self.get_labels(kind_back)
195
+
196
+ for segm, label in zip(results[0].masks.data,results[0].boxes.cls.cpu().numpy()):
197
+ label_name = class_names[int(label)]
198
+
199
+ if label_name in things_replace:
200
+ masks.append(segm.cpu().numpy())
201
+
202
+ masked_image = self.putMaskImage(frame_rgb,masks,background_image,blur_radius)
203
+
204
+
205
+ out.write(cv2.cvtColor(np.array(masked_image.resize(org_size)), cv2.COLOR_RGB2BGR))
206
+
207
+ print(f"Completed frame {i+1} ")
208
+ i=i+1
209
+
210
+ #if (i==10):
211
+ # break
212
+
213
+ print("Finished frames")
214
+ # adding original sound ,by extracting sound then put in new video
215
+
216
+ cap.release()
217
+ out.release()
218
+ cv2.destroyAllWindows()
219
+
220
+
221
+ #subprocess.run(['ffmpeg', '-i', output_path, '-i', 'audio.mp3', '-c:v', 'copy', '-c:a', 'aac', '-strict', 'experimental',"temp_output_video.mp4" ])
222
+ os.remove(sound_tmp_file)
223
+
224
+