eienmojiki commited on
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

Files changed (1) hide show
  1. 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
+