random2222 commited on
Commit
b224bbe
·
verified ·
1 Parent(s): ea3cae7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +113 -130
app.py CHANGED
@@ -5,24 +5,21 @@ import gradio as gr
5
  from PIL import Image
6
  import tempfile
7
 
8
- # Enable OpenCL for better performance if available
9
- try:
10
- cv2.ocl.setUseOpenCL(True)
11
- except:
12
- pass # OpenCL might not be available in all environments
13
 
14
  # ------------------- Black & White Converter Functions ------------------- #
15
  def convert_to_black_white(image, threshold_value=127, method="otsu"):
16
  """Convert image to black and white using specified thresholding method"""
17
  if isinstance(image, str):
18
  image = cv2.imread(image)
19
-
20
  # Convert to grayscale if not already
21
  if len(image.shape) == 3:
22
  gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
23
  else:
24
  gray = image
25
-
26
  if method == "adaptive":
27
  binary = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
28
  cv2.THRESH_BINARY, 11, 2)
@@ -30,17 +27,14 @@ def convert_to_black_white(image, threshold_value=127, method="otsu"):
30
  _, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
31
  else:
32
  _, binary = cv2.threshold(gray, threshold_value, 255, cv2.THRESH_BINARY)
33
-
34
  return binary
35
 
36
- def process_image_bw(image, threshold_method, threshold_value):
37
- """Process image with black and white thresholding for Gradio"""
38
  if image is None:
39
- raise gr.Error("No image provided")
40
-
41
- if threshold_method != "manual":
42
- threshold_value = 0 # Not used for adaptive or Otsu
43
-
44
  # Convert to numpy array if PIL Image
45
  if isinstance(image, Image.Image):
46
  image_np = np.array(image)
@@ -49,59 +43,56 @@ def process_image_bw(image, threshold_method, threshold_value):
49
  image_np = cv2.cvtColor(image_np, cv2.COLOR_RGB2BGR)
50
  else:
51
  image_np = image
52
-
53
- result = convert_to_black_white(image_np, threshold_value, threshold_method)
54
- return Image.fromarray(result)
55
 
56
- def process_video_bw(video_path, threshold_method, threshold_value):
57
- """Process video with black and white filter for Gradio"""
58
- if video_path is None:
59
- raise gr.Error("No video provided")
60
-
61
- if threshold_method != "manual":
62
- threshold_value = 0 # Not used for adaptive or Otsu
63
-
64
  try:
65
  cap = cv2.VideoCapture(video_path)
66
  if not cap.isOpened():
67
- raise gr.Error("Could not open video file")
68
 
69
  # Get video properties
70
  fourcc = cv2.VideoWriter_fourcc(*'mp4v')
71
  frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
72
  frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
73
  fps = int(cap.get(cv2.CAP_PROP_FPS))
74
-
75
  # Create temporary output file
76
  temp_output = tempfile.NamedTemporaryFile(suffix='.mp4', delete=False)
77
  output_path = temp_output.name
78
  temp_output.close()
79
-
80
  # Create video writer
81
  out = cv2.VideoWriter(output_path, fourcc, fps, (frame_width, frame_height), isColor=False)
82
-
83
  # Process each frame
84
  while cap.isOpened():
85
  ret, frame = cap.read()
86
  if not ret:
87
  break
88
-
89
- bw_frame = convert_to_black_white(frame, threshold_value, threshold_method)
90
  out.write(bw_frame)
91
-
92
  cap.release()
93
  out.release()
94
-
95
- return output_path
96
  except Exception as e:
97
- raise gr.Error(f"Error processing video: {str(e)}")
98
 
99
  # ------------------- Pencil Sketch Converter Functions ------------------- #
100
- def process_image_sketch(image, intensity, blur_ksize, sigma):
101
- """Process image with pencil sketch effect for Gradio"""
102
  if image is None:
103
- raise gr.Error("No image provided")
104
-
105
  # Convert to numpy array if PIL Image
106
  if isinstance(image, Image.Image):
107
  image_np = np.array(image)
@@ -110,93 +101,104 @@ def process_image_sketch(image, intensity, blur_ksize, sigma):
110
  image_np = cv2.cvtColor(image_np, cv2.COLOR_RGB2BGR)
111
  else:
112
  image_np = image
113
-
114
  # Convert to grayscale
115
  gray = cv2.cvtColor(image_np, cv2.COLOR_BGR2GRAY) if len(image_np.shape) == 3 else image_np
116
-
117
  # Create sketch effect
118
  inverted = cv2.bitwise_not(gray)
119
  blur_ksize = blur_ksize if blur_ksize % 2 == 1 else blur_ksize + 1 # Ensure kernel size is odd
120
  blurred = cv2.GaussianBlur(inverted, (blur_ksize, blur_ksize), sigma)
121
  sketch = cv2.divide(gray, cv2.bitwise_not(blurred), scale=intensity)
122
-
123
- return Image.fromarray(sketch)
124
-
125
- def process_video_sketch(video_path, intensity, blur_ksize, sigma):
126
- """Process video with pencil sketch effect for Gradio"""
127
- if video_path is None:
128
- raise gr.Error("No video provided")
129
-
130
  try:
131
  cap = cv2.VideoCapture(video_path)
132
  if not cap.isOpened():
133
- raise gr.Error("Could not open video file")
134
 
135
  # Get video properties
136
  fourcc = cv2.VideoWriter_fourcc(*'mp4v')
137
  frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
138
  frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
139
  fps = int(cap.get(cv2.CAP_PROP_FPS))
140
-
141
  # Create temporary output file
142
  temp_output = tempfile.NamedTemporaryFile(suffix='.mp4', delete=False)
143
  output_path = temp_output.name
144
  temp_output.close()
145
-
146
  # Create video writer
147
  out = cv2.VideoWriter(output_path, fourcc, fps, (frame_width, frame_height), isColor=True)
148
-
149
  # Process each frame
150
  while cap.isOpened():
151
  ret, frame = cap.read()
152
  if not ret:
153
  break
154
-
155
- gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
156
- inverted = cv2.bitwise_not(gray)
157
- blur_ksize_adj = blur_ksize if blur_ksize % 2 == 1 else blur_ksize + 1
158
- blurred = cv2.GaussianBlur(inverted, (blur_ksize_adj, blur_ksize_adj), sigma)
159
- sketch = cv2.divide(gray, cv2.bitwise_not(blurred), scale=intensity)
160
- sketch_bgr = cv2.cvtColor(sketch, cv2.COLOR_GRAY2BGR)
161
  out.write(sketch_bgr)
162
-
163
  cap.release()
164
  out.release()
165
-
166
- return output_path
167
  except Exception as e:
168
- raise gr.Error(f"Error processing video: {str(e)}")
169
 
170
- # ------------------- Create Gradio Interface ------------------- #
171
- def update_blur(value):
172
- """Ensure blur kernel size is always odd"""
173
- return value if value % 2 == 1 else value + 1
 
174
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
  def create_interface():
176
- # App title and description
177
- title = "Image & Video Processor"
178
- description = """
179
- # Image and Video Processing App
180
-
181
- This app provides tools to convert images and videos to black & white or pencil sketch styles.
182
-
183
- ## Features:
184
- - **Black & White Conversion**: Apply different thresholding methods
185
- - **Pencil Sketch Effect**: Create artistic pencil drawings with customizable parameters
186
- - **Support for both images and videos**
187
-
188
- Made with ❤️ using Gradio and OpenCV
189
- """
190
-
191
  # Black and White Image Interface
192
- with gr.Blocks(title=title) as app:
193
- gr.Markdown(description)
194
-
195
  with gr.Tab("Black & White Converter"):
196
  with gr.Tab("Image"):
197
  with gr.Row():
198
  with gr.Column():
199
- bw_image_input = gr.Image(label="Input Image", type="numpy")
200
  bw_method = gr.Radio(
201
  choices=["otsu", "adaptive", "manual"],
202
  value="otsu",
@@ -211,16 +213,10 @@ def create_interface():
211
  interactive=True
212
  )
213
  bw_image_btn = gr.Button("Convert to Black & White")
214
-
215
  with gr.Column():
216
  bw_image_output = gr.Image(label="Processed Image")
217
-
218
- # Show/hide threshold slider based on method
219
- def update_threshold_visibility(method):
220
- return gr.update(visible=(method == "manual"))
221
-
222
- bw_method.change(fn=update_threshold_visibility, inputs=bw_method, outputs=bw_threshold)
223
-
224
  with gr.Tab("Video"):
225
  with gr.Row():
226
  with gr.Column():
@@ -239,18 +235,15 @@ def create_interface():
239
  interactive=True
240
  )
241
  bw_video_btn = gr.Button("Convert to Black & White")
242
-
243
  with gr.Column():
244
  bw_video_output = gr.Video(label="Processed Video")
245
-
246
- # Show/hide threshold slider based on method
247
- bw_video_method.change(fn=update_threshold_visibility, inputs=bw_video_method, outputs=bw_video_threshold)
248
-
249
  with gr.Tab("Pencil Sketch Converter"):
250
  with gr.Tab("Image"):
251
  with gr.Row():
252
  with gr.Column():
253
- sketch_image_input = gr.Image(label="Input Image", type="numpy")
254
  sketch_intensity = gr.Slider(
255
  minimum=1,
256
  maximum=255,
@@ -273,10 +266,10 @@ def create_interface():
273
  label="Standard Deviation (0-50)"
274
  )
275
  sketch_image_btn = gr.Button("Convert to Pencil Sketch")
276
-
277
  with gr.Column():
278
  sketch_image_output = gr.Image(label="Processed Image")
279
-
280
  with gr.Tab("Video"):
281
  with gr.Row():
282
  with gr.Column():
@@ -303,55 +296,45 @@ def create_interface():
303
  label="Standard Deviation (0-50)"
304
  )
305
  sketch_video_btn = gr.Button("Convert to Pencil Sketch")
306
-
307
  with gr.Column():
308
  sketch_video_output = gr.Video(label="Processed Video")
309
-
310
- # Examples section
311
- with gr.Accordion("Examples", open=False):
312
- gr.Markdown("""
313
- ## Example Usage:
314
-
315
- 1. **Black & White Conversion**: Great for document scanning, text enhancement, or artistic effects
316
- 2. **Pencil Sketch**: Perfect for creating artistic renderings from photos
317
-
318
- Try uploading your own images or videos!
319
- """)
320
-
321
  # Set up event listeners
322
  bw_image_btn.click(
323
- fn=process_image_bw,
324
  inputs=[bw_image_input, bw_method, bw_threshold],
325
  outputs=bw_image_output
326
  )
327
-
328
  bw_video_btn.click(
329
- fn=process_video_bw,
330
  inputs=[bw_video_input, bw_video_method, bw_video_threshold],
331
  outputs=bw_video_output
332
  )
333
-
334
  sketch_image_btn.click(
335
- fn=process_image_sketch,
336
  inputs=[sketch_image_input, sketch_intensity, sketch_blur, sketch_sigma],
337
  outputs=sketch_image_output
338
  )
339
-
340
  sketch_video_btn.click(
341
- fn=process_video_sketch,
342
  inputs=[sketch_video_input, sketch_video_intensity, sketch_video_blur, sketch_video_sigma],
343
  outputs=sketch_video_output
344
  )
345
-
346
  # Make blur slider always odd
 
 
 
347
  sketch_blur.change(update_blur, sketch_blur, sketch_blur)
348
  sketch_video_blur.change(update_blur, sketch_video_blur, sketch_video_blur)
349
-
350
- return app
351
 
352
- # Create and launch the app
353
- app = create_interface()
354
 
355
- # This is needed for Hugging Face Spaces
356
  if __name__ == "__main__":
 
357
  app.launch()
 
5
  from PIL import Image
6
  import tempfile
7
 
8
+ # Enable OpenCL for better performance
9
+ cv2.ocl.setUseOpenCL(True)
 
 
 
10
 
11
  # ------------------- Black & White Converter Functions ------------------- #
12
  def convert_to_black_white(image, threshold_value=127, method="otsu"):
13
  """Convert image to black and white using specified thresholding method"""
14
  if isinstance(image, str):
15
  image = cv2.imread(image)
16
+
17
  # Convert to grayscale if not already
18
  if len(image.shape) == 3:
19
  gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
20
  else:
21
  gray = image
22
+
23
  if method == "adaptive":
24
  binary = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
25
  cv2.THRESH_BINARY, 11, 2)
 
27
  _, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
28
  else:
29
  _, binary = cv2.threshold(gray, threshold_value, 255, cv2.THRESH_BINARY)
30
+
31
  return binary
32
 
33
+ def process_image_bw(image, threshold_value, method):
34
+ """Process image with black and white thresholding"""
35
  if image is None:
36
+ return None
37
+
 
 
 
38
  # Convert to numpy array if PIL Image
39
  if isinstance(image, Image.Image):
40
  image_np = np.array(image)
 
43
  image_np = cv2.cvtColor(image_np, cv2.COLOR_RGB2BGR)
44
  else:
45
  image_np = image
 
 
 
46
 
47
+ result = convert_to_black_white(image_np, threshold_value, method)
48
+ return result
49
+
50
+ def process_video_bw(video_path, threshold_value, method):
51
+ """Process video with black and white thresholding"""
52
+ if not os.path.exists(video_path):
53
+ return "Video file not found", None
54
+
55
  try:
56
  cap = cv2.VideoCapture(video_path)
57
  if not cap.isOpened():
58
+ return "Could not open video file", None
59
 
60
  # Get video properties
61
  fourcc = cv2.VideoWriter_fourcc(*'mp4v')
62
  frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
63
  frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
64
  fps = int(cap.get(cv2.CAP_PROP_FPS))
65
+
66
  # Create temporary output file
67
  temp_output = tempfile.NamedTemporaryFile(suffix='.mp4', delete=False)
68
  output_path = temp_output.name
69
  temp_output.close()
70
+
71
  # Create video writer
72
  out = cv2.VideoWriter(output_path, fourcc, fps, (frame_width, frame_height), isColor=False)
73
+
74
  # Process each frame
75
  while cap.isOpened():
76
  ret, frame = cap.read()
77
  if not ret:
78
  break
79
+
80
+ bw_frame = convert_to_black_white(frame, threshold_value, method)
81
  out.write(bw_frame)
82
+
83
  cap.release()
84
  out.release()
85
+
86
+ return "Video processed successfully", output_path
87
  except Exception as e:
88
+ return f"Error processing video: {str(e)}", None
89
 
90
  # ------------------- Pencil Sketch Converter Functions ------------------- #
91
+ def process_image_sketch(image, intensity=255, blur_ksize=21, sigma=0):
92
+ """Convert image to pencil sketch effect"""
93
  if image is None:
94
+ return None
95
+
96
  # Convert to numpy array if PIL Image
97
  if isinstance(image, Image.Image):
98
  image_np = np.array(image)
 
101
  image_np = cv2.cvtColor(image_np, cv2.COLOR_RGB2BGR)
102
  else:
103
  image_np = image
104
+
105
  # Convert to grayscale
106
  gray = cv2.cvtColor(image_np, cv2.COLOR_BGR2GRAY) if len(image_np.shape) == 3 else image_np
107
+
108
  # Create sketch effect
109
  inverted = cv2.bitwise_not(gray)
110
  blur_ksize = blur_ksize if blur_ksize % 2 == 1 else blur_ksize + 1 # Ensure kernel size is odd
111
  blurred = cv2.GaussianBlur(inverted, (blur_ksize, blur_ksize), sigma)
112
  sketch = cv2.divide(gray, cv2.bitwise_not(blurred), scale=intensity)
113
+
114
+ return sketch
115
+
116
+ def process_video_sketch(video_path, intensity=255, blur_ksize=21, sigma=0):
117
+ """Process video with pencil sketch effect"""
118
+ if not os.path.exists(video_path):
119
+ return "Video file not found", None
120
+
121
  try:
122
  cap = cv2.VideoCapture(video_path)
123
  if not cap.isOpened():
124
+ return "Could not open video file", None
125
 
126
  # Get video properties
127
  fourcc = cv2.VideoWriter_fourcc(*'mp4v')
128
  frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
129
  frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
130
  fps = int(cap.get(cv2.CAP_PROP_FPS))
131
+
132
  # Create temporary output file
133
  temp_output = tempfile.NamedTemporaryFile(suffix='.mp4', delete=False)
134
  output_path = temp_output.name
135
  temp_output.close()
136
+
137
  # Create video writer
138
  out = cv2.VideoWriter(output_path, fourcc, fps, (frame_width, frame_height), isColor=True)
139
+
140
  # Process each frame
141
  while cap.isOpened():
142
  ret, frame = cap.read()
143
  if not ret:
144
  break
145
+
146
+ sketch_frame = process_image_sketch(frame, intensity, blur_ksize, sigma)
147
+ # Convert grayscale to BGR for video output
148
+ sketch_bgr = cv2.cvtColor(sketch_frame, cv2.COLOR_GRAY2BGR)
 
 
 
149
  out.write(sketch_bgr)
150
+
151
  cap.release()
152
  out.release()
153
+
154
+ return "Video processed successfully", output_path
155
  except Exception as e:
156
+ return f"Error processing video: {str(e)}", None
157
 
158
+ # ------------------- Gradio Interface Functions ------------------- #
159
+ def black_white_image(image, threshold_method, threshold_value):
160
+ """Process image with black and white filter for Gradio"""
161
+ if threshold_method != "manual":
162
+ threshold_value = 0 # Not used for adaptive or Otsu
163
 
164
+ result = process_image_bw(image, threshold_value, threshold_method)
165
+ return Image.fromarray(result)
166
+
167
+ def black_white_video(video, threshold_method, threshold_value):
168
+ """Process video with black and white filter for Gradio"""
169
+ if threshold_method != "manual":
170
+ threshold_value = 0 # Not used for adaptive or Otsu
171
+
172
+ message, output_path = process_video_bw(video, threshold_value, threshold_method)
173
+ if output_path:
174
+ return output_path
175
+ else:
176
+ raise gr.Error(message)
177
+
178
+ def sketch_image(image, intensity, blur_ksize, sigma):
179
+ """Process image with pencil sketch filter for Gradio"""
180
+ result = process_image_sketch(image, intensity, blur_ksize, sigma)
181
+ return Image.fromarray(result)
182
+
183
+ def sketch_video(video, intensity, blur_ksize, sigma):
184
+ """Process video with pencil sketch filter for Gradio"""
185
+ message, output_path = process_video_sketch(video, intensity, blur_ksize, sigma)
186
+ if output_path:
187
+ return output_path
188
+ else:
189
+ raise gr.Error(message)
190
+
191
+ # ------------------- Create Gradio Interface ------------------- #
192
  def create_interface():
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
193
  # Black and White Image Interface
194
+ with gr.Blocks(title="Image Processor") as app:
195
+ gr.Markdown("# Image and Video Processor")
196
+
197
  with gr.Tab("Black & White Converter"):
198
  with gr.Tab("Image"):
199
  with gr.Row():
200
  with gr.Column():
201
+ bw_image_input = gr.Image(label="Input Image")
202
  bw_method = gr.Radio(
203
  choices=["otsu", "adaptive", "manual"],
204
  value="otsu",
 
213
  interactive=True
214
  )
215
  bw_image_btn = gr.Button("Convert to Black & White")
216
+
217
  with gr.Column():
218
  bw_image_output = gr.Image(label="Processed Image")
219
+
 
 
 
 
 
 
220
  with gr.Tab("Video"):
221
  with gr.Row():
222
  with gr.Column():
 
235
  interactive=True
236
  )
237
  bw_video_btn = gr.Button("Convert to Black & White")
238
+
239
  with gr.Column():
240
  bw_video_output = gr.Video(label="Processed Video")
241
+
 
 
 
242
  with gr.Tab("Pencil Sketch Converter"):
243
  with gr.Tab("Image"):
244
  with gr.Row():
245
  with gr.Column():
246
+ sketch_image_input = gr.Image(label="Input Image")
247
  sketch_intensity = gr.Slider(
248
  minimum=1,
249
  maximum=255,
 
266
  label="Standard Deviation (0-50)"
267
  )
268
  sketch_image_btn = gr.Button("Convert to Pencil Sketch")
269
+
270
  with gr.Column():
271
  sketch_image_output = gr.Image(label="Processed Image")
272
+
273
  with gr.Tab("Video"):
274
  with gr.Row():
275
  with gr.Column():
 
296
  label="Standard Deviation (0-50)"
297
  )
298
  sketch_video_btn = gr.Button("Convert to Pencil Sketch")
299
+
300
  with gr.Column():
301
  sketch_video_output = gr.Video(label="Processed Video")
302
+
 
 
 
 
 
 
 
 
 
 
 
303
  # Set up event listeners
304
  bw_image_btn.click(
305
+ fn=black_white_image,
306
  inputs=[bw_image_input, bw_method, bw_threshold],
307
  outputs=bw_image_output
308
  )
309
+
310
  bw_video_btn.click(
311
+ fn=black_white_video,
312
  inputs=[bw_video_input, bw_video_method, bw_video_threshold],
313
  outputs=bw_video_output
314
  )
315
+
316
  sketch_image_btn.click(
317
+ fn=sketch_image,
318
  inputs=[sketch_image_input, sketch_intensity, sketch_blur, sketch_sigma],
319
  outputs=sketch_image_output
320
  )
321
+
322
  sketch_video_btn.click(
323
+ fn=sketch_video,
324
  inputs=[sketch_video_input, sketch_video_intensity, sketch_video_blur, sketch_video_sigma],
325
  outputs=sketch_video_output
326
  )
327
+
328
  # Make blur slider always odd
329
+ def update_blur(value):
330
+ return value if value % 2 == 1 else value + 1
331
+
332
  sketch_blur.change(update_blur, sketch_blur, sketch_blur)
333
  sketch_video_blur.change(update_blur, sketch_video_blur, sketch_video_blur)
 
 
334
 
335
+ return app
 
336
 
337
+ # ------------------- Launch App ------------------- #
338
  if __name__ == "__main__":
339
+ app = create_interface()
340
  app.launch()