4

I have an image that has different shades of black at the edges and a bit of red in the centre. I want to convert all the black pixels to transparent using opencv. I'm new to opencv so I'd appreciate your help.

I tried following what fireant said in the link: overlay a smaller image on a larger image python OpenCv, but it didn't work. Here's the code I have so far:

img = cv2.imread("/home/uwatt/Downloads/lensf1.jpg")
img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
tmp = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
_,alpha = cv2.threshold(tmp,5,255,cv2.THRESH_BINARY)
b,g,r = cv2.split(img)
rgba = [b,g,r,alpha]
dst = cv2.merge(rgba, 4)
plt.imshow(dst)
print(dst.shape)

face_cascade = cv2.CascadeClassifier('/home/uwatt/DIP/lensflare/haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier('/home/uwatt/DIP/lensflare/haarcascade_eye.xml')

user = cv2.imread("/home/uwatt/Downloads/Dicaprio.jpg")
gray_user = cv2.cvtColor(user, cv2.COLOR_BGR2GRAY)
user = cv2.cvtColor(user, cv2.COLOR_BGR2BGRA)
faces = face_cascade.detectMultiScale(gray_user, 1.3, 5)
print("Faces:",faces)
for (x,y,w,h) in faces:
    roi_gray = gray_user[y:y+h,x:x+w]
    roi_color = user[y:y+h,x:x+w]
    eyes = eye_cascade.detectMultiScale(roi_gray)
    for (ex,ey,ew,eh) in eyes:
        print(ex,ey,ew,eh)
        #cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,0,255),5)

        # resizing & paste the lf image on user
        roi_eye = user[y+ey:y+ey+eh,x+ex:x+ex+ew]
        resized_lensflare = cv2.resize(dst,(eh,ew))    
        resized_lensflare = cv2.cvtColor(resized_lensflare, cv2.COLOR_BGR2RGBA)
        user[y+ey:y+ey+eh,x+ex:x+ex+ew] = resized_lensflare
U. Watt
  • 533
  • 1
  • 5
  • 27
  • That's nice but we have no idea what your image looks like!!! – Mark Setchell Aug 21 '19 at 12:25
  • yeah, my bad lol – U. Watt Aug 21 '19 at 12:32
  • what was wrong with "fireant said in the link" and can you explain why "it didn't work"? it looks like what you should be doing. the code you posted doesn't seem relevant it's mostly detecting eyes, which seems irrelevant to the question you're asking. questions should include [minimal code](https://stackoverflow.com/help/mcve) just hard code the coordinates, and remove other irrelevant stuff – Sam Mason Aug 21 '19 at 12:52
  • That's the problem, I don't know why it didn't work for me. It just displayed the image as is. – U. Watt Aug 21 '19 at 12:58
  • Have a look here https://stackoverflow.com/a/49908166/2836621 – Mark Setchell Aug 21 '19 at 13:29
  • I had looked into that, actually. Thing is, I can't use addweight here because the black background won't disappear completely. It'll fade but you will still be able to see it. I want to get rid of the black part completely. And afaik, you can't do that with addweight – U. Watt Aug 21 '19 at 13:58

1 Answers1

3

You need to use alpha blending to combine the lens flare with the background image. Check out this tutorial to find out more about alpha blending. Here is the stript that I used:

import cv2
flare = cv2.imread("/home/stephen/Desktop/flare.jpg")
user = cv2.imread("/home/stephen/Desktop/leo.jpg")
eyes = [[100,50,200,200],[175,50,200,200]]
for x,y,w,h in eyes:       
    # resizing & paste the lf image on user
    roi_eye = user[y:y+h,x:x+w]
    resized_lensflare = cv2.resize(flare,(w,h))    
    # Make foreground background and alpha
    foreground = resized_lensflare.copy()
    background = roi_eye.copy()
    alpha= foreground.copy()
    # Convert uint8 to float
    foreground = foreground.astype(float)
    background = background.astype(float) 
    # Normalize the alpha mask to keep intensity between 0 and 1
    alpha = alpha.astype(float)/255
    # Multiply the foreground with the alpha matte
    foreground = cv2.multiply(alpha, foreground)
    # Multiply the background with ( 1 - alpha )
    background = cv2.multiply(1.0 - alpha, background)
    # Add the masked foreground and background.
    outImage = cv2.add(foreground, background)
    # Mask the user image
    user[y:y+h,x:x+w] = outImage
cv2.imshow('img', user)
cv2.waitKey()
cv2.destroyAllWindows()

woah leo

Stephen Meschke
  • 2,820
  • 1
  • 13
  • 25