Spaces:
Running
Running
Commit
·
e6956bc
1
Parent(s):
3897042
Add new image processing filters to filters.py
Browse files- Introduced four new professional image filters:
* Gaussian Blur: Softens image with adjustable kernel size
* Sharpen: Enhances image details with intensity control
* Emboss: Creates 3D-like effect with direction and strength options
* Oil Painting: Applies artistic oil painting style to images
- Implemented comprehensive parameter controls for each filter
- Used OpenCV for advanced image processing techniques
- Registered new filters with default, min, max, and step values
- Expanded image editing capabilities with diverse filter options
- filters.py +156 -0
filters.py
CHANGED
@@ -370,3 +370,159 @@ def hdr_effect(image, strength: int = 50):
|
|
370 |
|
371 |
return result
|
372 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
370 |
|
371 |
return result
|
372 |
|
373 |
+
|
374 |
+
@registry.register("Gaussian Blur", defaults={
|
375 |
+
"kernel_size": 5,
|
376 |
+
}, min_vals={
|
377 |
+
"kernel_size": 1,
|
378 |
+
}, max_vals={
|
379 |
+
"kernel_size": 31,
|
380 |
+
}, step_vals={
|
381 |
+
"kernel_size": 2,
|
382 |
+
})
|
383 |
+
def gaussian_blur(image, kernel_size: int = 5):
|
384 |
+
"""
|
385 |
+
## Apply Gaussian blur effect to the image.
|
386 |
+
|
387 |
+
**Args:**
|
388 |
+
* `image` (numpy.ndarray): Input image (BGR)
|
389 |
+
* `kernel_size` (int): Size of the Gaussian kernel (must be odd)
|
390 |
+
|
391 |
+
**Returns:**
|
392 |
+
* `numpy.ndarray`: Blurred image
|
393 |
+
"""
|
394 |
+
# Ensure kernel size is odd
|
395 |
+
if kernel_size % 2 == 0:
|
396 |
+
kernel_size += 1
|
397 |
+
|
398 |
+
return cv2.GaussianBlur(image, (kernel_size, kernel_size), 0)
|
399 |
+
|
400 |
+
|
401 |
+
@registry.register("Sharpen", defaults={
|
402 |
+
"amount": 50,
|
403 |
+
}, min_vals={
|
404 |
+
"amount": 0,
|
405 |
+
}, max_vals={
|
406 |
+
"amount": 100,
|
407 |
+
}, step_vals={
|
408 |
+
"amount": 1,
|
409 |
+
})
|
410 |
+
def sharpen(image, amount: int = 50):
|
411 |
+
"""
|
412 |
+
## Sharpen the image.
|
413 |
+
|
414 |
+
**Args:**
|
415 |
+
* `image` (numpy.ndarray): Input image (BGR)
|
416 |
+
* `amount` (int): Sharpening intensity (0-100)
|
417 |
+
|
418 |
+
**Returns:**
|
419 |
+
* `numpy.ndarray`: Sharpened image
|
420 |
+
"""
|
421 |
+
amount = amount / 100.0
|
422 |
+
|
423 |
+
# Create the sharpening kernel
|
424 |
+
kernel = np.array([[-1,-1,-1],
|
425 |
+
[-1, 9,-1],
|
426 |
+
[-1,-1,-1]])
|
427 |
+
|
428 |
+
# Apply the kernel
|
429 |
+
sharpened = cv2.filter2D(image, -1, kernel)
|
430 |
+
|
431 |
+
# Blend with original image based on amount
|
432 |
+
return cv2.addWeighted(image, 1 - amount, sharpened, amount, 0)
|
433 |
+
|
434 |
+
|
435 |
+
@registry.register("Emboss", defaults={
|
436 |
+
"strength": 50,
|
437 |
+
"direction": 0,
|
438 |
+
}, min_vals={
|
439 |
+
"strength": 0,
|
440 |
+
"direction": 0,
|
441 |
+
}, max_vals={
|
442 |
+
"strength": 100,
|
443 |
+
"direction": 7,
|
444 |
+
}, step_vals={
|
445 |
+
"strength": 1,
|
446 |
+
"direction": 1,
|
447 |
+
})
|
448 |
+
def emboss(image, strength: int = 50, direction: int = 0):
|
449 |
+
"""
|
450 |
+
## Apply emboss effect to create a 3D look.
|
451 |
+
|
452 |
+
**Args:**
|
453 |
+
* `image` (numpy.ndarray): Input image (BGR)
|
454 |
+
* `strength` (int): Emboss strength (0-100)
|
455 |
+
* `direction` (int): Direction of emboss effect (0-7)
|
456 |
+
|
457 |
+
**Returns:**
|
458 |
+
* `numpy.ndarray`: Embossed image
|
459 |
+
"""
|
460 |
+
strength = strength / 100.0 * 2.0 # Scale to 0-2 range
|
461 |
+
|
462 |
+
# Define kernels for different directions
|
463 |
+
kernels = [
|
464 |
+
np.array([[-1,-1, 0],
|
465 |
+
[-1, 1, 1],
|
466 |
+
[ 0, 1, 1]]), # 0 - top left to bottom right
|
467 |
+
np.array([[-1, 0, 1],
|
468 |
+
[-1, 1, 1],
|
469 |
+
[-1, 0, 1]]), # 1 - left to right
|
470 |
+
np.array([[ 0, 1, 1],
|
471 |
+
[-1, 1, 1],
|
472 |
+
[-1,-1, 0]]), # 2 - bottom left to top right
|
473 |
+
np.array([[ 1, 1, 1],
|
474 |
+
[ 0, 1, 0],
|
475 |
+
[-1,-1,-1]]), # 3 - bottom to top
|
476 |
+
np.array([[ 1, 1, 0],
|
477 |
+
[ 1, 1,-1],
|
478 |
+
[ 0,-1,-1]]), # 4 - bottom right to top left
|
479 |
+
np.array([[ 1, 0,-1],
|
480 |
+
[ 1, 1,-1],
|
481 |
+
[ 1, 0,-1]]), # 5 - right to left
|
482 |
+
np.array([[ 0,-1,-1],
|
483 |
+
[ 1, 1,-1],
|
484 |
+
[ 1, 1, 0]]), # 6 - top right to bottom left
|
485 |
+
np.array([[-1,-1,-1],
|
486 |
+
[ 0, 1, 0],
|
487 |
+
[ 1, 1, 1]]) # 7 - top to bottom
|
488 |
+
]
|
489 |
+
|
490 |
+
# Apply the kernel
|
491 |
+
kernel = kernels[direction % 8]
|
492 |
+
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
|
493 |
+
embossed = cv2.filter2D(gray, -1, kernel * strength)
|
494 |
+
|
495 |
+
# Normalize to ensure good contrast
|
496 |
+
embossed = cv2.normalize(embossed, None, 0, 255, cv2.NORM_MINMAX)
|
497 |
+
|
498 |
+
# Convert back to BGR
|
499 |
+
return cv2.cvtColor(embossed.astype(np.uint8), cv2.COLOR_GRAY2BGR)
|
500 |
+
|
501 |
+
|
502 |
+
@registry.register("Oil Painting", defaults={
|
503 |
+
"size": 5,
|
504 |
+
"dynRatio": 1,
|
505 |
+
}, min_vals={
|
506 |
+
"size": 1,
|
507 |
+
"dynRatio": 1,
|
508 |
+
}, max_vals={
|
509 |
+
"size": 15,
|
510 |
+
"dynRatio": 7,
|
511 |
+
}, step_vals={
|
512 |
+
"size": 2,
|
513 |
+
"dynRatio": 1,
|
514 |
+
})
|
515 |
+
def oil_painting(image, size: int = 5, dynRatio: int = 1):
|
516 |
+
"""
|
517 |
+
## Apply oil painting effect to the image.
|
518 |
+
|
519 |
+
**Args:**
|
520 |
+
* `image` (numpy.ndarray): Input image (BGR)
|
521 |
+
* `size` (int): Size of the neighborhood considered
|
522 |
+
* `dynRatio` (int): Dynamic ratio affecting the intensity binning
|
523 |
+
|
524 |
+
**Returns:**
|
525 |
+
* `numpy.ndarray`: Image with oil painting effect
|
526 |
+
"""
|
527 |
+
return cv2.xphoto.oilPainting(image, size, dynRatio)
|
528 |
+
|