Doubt regarding putting of glasses and mustache over image

How do i maintain the transparency of the region outside the boundaries of glasses and mustache? The BGR value of pixels outside is [ 0,0,0 ] (black), so i can’t just copy it in the detected region of eyes and below nose.

Hey @SanchitSayala, While reading moustache and glasses image use,
img = plt.imread(’./Train/mustache.png’)
print(img.shape)

You will notice that img has 4 channels and not 3. These channels are rgba. Where ‘a’ channel stores the opacity of channel. It will be greater than 0 if there is some opacity otherwise zero.

Next step is to resize this image, to the one having same width and height to that of nose.

Than you need to iterate on every pixels value on img from x to x+w and from y to y+h. And replace the pixel values to that of moustache image if ‘a’ channel value i.e. opacity value is greater than 0.

Hope this resolved your doubt.
Plz mark the doubt as resolved in my doubts :blush:

I did the same but the white portion of the glasses is not copied over to the face(here, I tried to apply the changes to Jamie first):

Here’s the code used for copying:


gh, gw, mh, mw are the heights & widths of glasses and mustache respectively. And (X1, Y1) and (X2, Y2) are the midpoints of glasses and mustache respectively in the image jamie_before.

Hey @SanchitSayala, when you loading glasses.png do it like this,

glasses = plt.imread('glasses.png')
finalglasses = np.zeros(glasses.shape, dtype = 'uint8')
finalglasses[:,:,:] = glasses[:,:,:]*255.0 

And keep everything same.

Hope this resolved your doubt.
Plz mark it as resolved in my doubts section. :blush:

Thanks, it worked! But can you please tell why it did so??

Hey @SanchitSayala, when you load image its in float, means values are between 0 and 1. and when you try to put those values in jamie_before which is uint8 so when you put value in it, it rounds off it to zero or 1 which is black colour.

Hope this resolved your doubt.
Plz mark the doubt as resolved in my doubts :blush:

Thanks for the explanation :+1:

Here was my working code,

import matplotlib.pyplot as plt
import pandas as pd
import cv2
def image_resize(image, width = None, height = None, inter = cv2.INTER_AREA):
    dim = None
    (h, w) = image.shape[:2]
    if width is None and height is None:
        return image
    # check to see if the width is None
    if width is None:
        r = height / float(h)
        dim = (int(w * r), height)
    else:
        r = width / float(w)
        dim = (width, int(h * r))
    resized = cv2.resize(image, dim, interpolation = inter)
    return resized
classifier = cv2.CascadeClassifier('Train/third-party/frontalEyes35x16.xml')
classifier_nose = cv2.CascadeClassifier('Train/third-party/Nose18x15.xml')
img = cv2.imread('Train/Jamie_Before.jpg')
glasses = cv2.imread('Train/glasses.png',-1)
# glasses = cv2.resize(glasses,10,10)
mustache = cv2.imread('Train/mustache.png',-1)
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
detect = classifier.detectMultiScale(img_gray)
img_rgba = cv2.cvtColor(img,cv2.COLOR_BGR2BGRA)
for x,y,w,h in detect:
    eyes = img_rgba[y:y+h,x:x+w]
    glasses_re = image_resize(glasses,width=w)
    gw, gh, gc = glasses_re.shape
    for i in range(0, gw):
        for j in range(0, gh):
            #print(glasses[i, j]) #RGBA
            if glasses_re[i, j][3] != 0: # alpha 0
                img_rgba[y + i, x + j] = glasses_re[i, j]
detect_nose = classifier_nose.detectMultiScale(img_rgba)
key = -1
nx,ny,nw,nh = detect_nose[key][0],detect_nose[key][1],detect_nose[key][2],detect_nose[key][3]
nose = img_rgba[ny:ny+nh,nx:nx+nw]
mustache2 = image_resize(mustache, width=int(nw*1))
mw, mh, mc = mustache2.shape
    
for i in range(0, mw):
    for j in range(0, mh):
        if mustache2[i,j][3] != 0: # alpha 0
            img_rgba[ny+int(nh/2)+i,nx+j] = mustache2[i,j]
img = cv2.cvtColor(img_rgba,cv2.COLOR_BGRA2BGR)
img = image_resize(img,200)
cv2.imshow("a",img)
cv2.waitKey(0)
cv2.destroyAllWindows()