0

I want to add glasses PNG image onto another image, but i get the PNG image with white background which hides the face.

I need to know what i did wrong please.

Original face image

original face image

Original glasses image

original glasses image

Expected result

here what i get as result

import cv2
import numpy
img = cv2.imread("barack-obama.jpg")
lunette = cv2.imread("lunette.png", cv2.IMREAD_UNCHANGED)
eye_cascade = cv2.CascadeClassifier('haarcascade_eye.xml')
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

eyes = eye_cascade.detectMultiScale(img, scaleFactor = 1.1, minNeighbors = 5)   

r = 500.0 / img.shape[1]
dim = (500, int(img.shape[0] * r))
resized = cv2.resize(img, dim, interpolation = cv2.INTER_AREA)

 grey = cv2.cvtColor(resized, cv2.COLOR_BGR2GRAY)

faces = face_cascade.detectMultiScale(grey, 1.3, 5)

for (x,y,w,h) in faces:

roi_grey = grey[y:y+h, x:x+w]
roi_color = resized[y:y + h, x:x + w]
eyes = eye_cascade.detectMultiScale(roi_grey)
for (ex,ey,ew,eh) in eyes:
cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)

lunette = cv2.resize(lunette , (w,h))
w, h, c = lunette.shape 
for i in range(0, w):
for j in range(0, h):

    if lunette[i, j][0] != 0:
        resized[y + i, x + j] = lunette[i, j][1]
#help please
cv2.imshow('img',resized)

cv2.waitKey(0)
Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
fares ben
  • 1
  • 3
  • possible duplicate of https://stackoverflow.com/questions/14063070/overlay-a-smaller-image-on-a-larger-image-python-opencv – Shawn Mathew Jun 24 '19 at 21:07

2 Answers2

1

Here is one way to do that in Python/OpenCV/Numpy:

  • Read the background image (Obama)
  • Read the overlay image (glasses) unchanged
  • Extract the base BGR channels from the overlay image
  • Extract the alpha channel from the overlay image as a mask
  • Insert the BGR channels of the overlay into the background image at the desired location
  • Insert the mask into a black image the size of the background image at the desired location
  • Use Numpy where to composite the new background and overlay images using the new mask image
  • Save the result
import cv2
import numpy as np

# read background image
img = cv2.imread("obama.jpg")
ht, wd = img.shape[:2]

# read overlay image
img2 = cv2.imread("sunglasses.png", cv2.IMREAD_UNCHANGED)
ht2, wd2 = img2.shape[:2]

# extract alpha channel as mask and base bgr images
bgr = img2[:,:,0:3]
mask = img2[:,:,3]

# insert bgr into img at desired location and insert mask into black image
x = 580
y = 390

bgr_new = img.copy()
bgr_new[y:y+ht2, x:x+wd2] = bgr

mask_new = np.zeros((ht,wd), dtype=np.uint8)
mask_new[y:y+ht2, x:x+wd2] = mask
mask_new = cv2.cvtColor(mask_new, cv2.COLOR_GRAY2BGR)

# overlay the base bgr image onto img using mask
result = np.where(mask_new==255, bgr_new, img)

# save results
cv2.imwrite('obama_glasses.jpg', result)

# display results
cv2.imshow('bgr', bgr)
cv2.imshow('mask', mask)
cv2.imshow('bgr_new', bgr_new)
cv2.imshow('mask_new', mask_new)
cv2.imshow('result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()

Result:

enter image description here

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
fmw42
  • 46,825
  • 10
  • 62
  • 80
0

You can use cvzone library for solve this problem.

  1. install cvzone library

    pip install cvzone
    
  2. import cvzone in your project

    import cvzone
    
  3. imread your emoji with following format

    lunette = cv2.imread("lunette.png", cv2.IMREAD_UNCHANGED)
    
  4. now replace the your emoji like this:

    YOUR BACKGROUND PICTURE = cvzone.overlayPNG(YOUR BACKGROUND PICTURE, lunette , [x, y])
    
Tomerikoo
  • 18,379
  • 16
  • 47
  • 61