removeRedEyes.py 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. '''
  2. Copyright 2017 by Satya Mallick ( Big Vision LLC )
  3. http://www.learnopencv.com
  4. '''
  5. import cv2
  6. import numpy as np
  7. def fillHoles(mask):
  8. '''
  9. This hole filling algorithm is decribed in this post
  10. https://www.learnopencv.com/filling-holes-in-an-image-using-opencv-python-c/
  11. '''
  12. maskFloodfill = mask.copy()
  13. h, w = maskFloodfill.shape[:2]
  14. maskTemp = np.zeros((h+2, w+2), np.uint8)
  15. cv2.floodFill(maskFloodfill, maskTemp, (0, 0), 255)
  16. mask2 = cv2.bitwise_not(maskFloodfill)
  17. return mask2 | mask
  18. if __name__ == '__main__' :
  19. # Read image
  20. img = cv2.imread("red_eyes.jpg", cv2.IMREAD_COLOR)
  21. # Output image
  22. imgOut = img.copy()
  23. # Load HAAR cascade
  24. eyesCascade = cv2.CascadeClassifier("haarcascade_eye.xml")
  25. # Detect eyes
  26. eyes = eyesCascade.detectMultiScale(img, scaleFactor=1.3, minNeighbors=4, minSize=(100, 100))
  27. # For every detected eye
  28. for (x, y, w, h) in eyes:
  29. # Extract eye from the image
  30. eye = img[y:y+h, x:x+w]
  31. # Split eye image into 3 channels
  32. b = eye[:, :, 0]
  33. g = eye[:, :, 1]
  34. r = eye[:, :, 2]
  35. # Add the green and blue channels.
  36. bg = cv2.add(b, g)
  37. # Simple red eye detector.
  38. mask = (r > 150) & (r > bg)
  39. # Convert the mask to uint8 format.
  40. mask = mask.astype(np.uint8)*255
  41. # Clean mask -- 1) File holes 2) Dilate (expand) mask.
  42. mask = fillHoles(mask)
  43. mask = cv2.dilate(mask, None, anchor=(-1, -1), iterations=3, borderType=1, borderValue=1)
  44. # Calculate the mean channel by averaging
  45. # the green and blue channels
  46. mean = bg / 2
  47. mask = mask.astype(np.bool)[:, :, np.newaxis]
  48. mean = mean[:, :, np.newaxis]
  49. # Copy the eye from the original image.
  50. eyeOut = eye.copy()
  51. # Copy the mean image to the output image.
  52. #np.copyto(eyeOut, mean, where=mask)
  53. eyeOut = np.where(mask, mean, eyeOut)
  54. # Copy the fixed eye to the output image.
  55. imgOut[y:y+h, x:x+w, :] = eyeOut
  56. # Display Result
  57. cv2.imshow('Red Eyes', img)
  58. cv2.imshow('Red Eyes Removed', imgOut)
  59. cv2.waitKey(0)