Overlay Image quality decreasing with every frame in Live Video Feed

Viewed 71

I am trying to make a filter using OpenCV in which I am putting glasses over eyes in Live Video Capture Feed. The problem I am facing is that the Video Feed starts off with good quality of overlaying glasses image but with each frame the image quality of glasses seems to decrease itself and the height of glasses seem to increase slowly frame by frame itself.

Here is my code:-


mport cv2

face_Cascade = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_frontalface_default.xml")
eye_Cascade = cv2.CascadeClassifier(cv2.data.haarcascades + "frontalEyes35x16.xml")
nose_Cascade = cv2.CascadeClassifier(cv2.data.haarcascades + "Nose18x15.xml")
glasses = cv2.imread('glasses.png', -1) 
mustache = cv2.imread('mustache.png',-1)
cap = cv2.VideoCapture(0)

while True:
    ret, frame = cap.read()
    gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    
    if ret == False:
        continue
        
    frame = cv2.cvtColor(frame , cv2.COLOR_BGR2BGRA) # so that we can use glasses and mustaches alpha value
                                                     # otherwise we get white box around them
    
    faces = face_Cascade.detectMultiScale(gray_frame, 1.3, 5)
    
    for (x,y,w,h) in faces:
        
        #cv2.rectangle(frame, (x,y), (x+w, y+h), (255,255,255),3)
        roi_gray = gray_frame[y:y+h , x:x+w]
        roi_color = frame[y:y+h , x:x+w]
        
   
        eyes = eye_Cascade.detectMultiScale(roi_gray, 1.3, 5)
        for (ex,ey,ew,eh) in eyes:
            #cv2.rectangle(roi_color, (ex,ey), (ex+ew, ey+eh), (0,255,0),3)
            roi_eye_gray = roi_gray[ey:ey+eh, ex:ex+ew]
            roi_eye_color = roi_color[ey:ey+eh, ex:ex+ew]
            glasses = cv2.resize(glasses, (ew,eh), interpolation = cv2.INTER_AREA)
            
            gw, gh, gc = glasses.shape
            # We are going to iterate through every single pixel value in the glasses image and then we
            # are going to replace it with roi_color
            
            for i in range (0,gw):
                for j in range(0,gh):
                    if glasses[i, j][3] != 0: # 3rd value [3] means alpha value there is 0 so we want it  
                             #to  be transparent and we dont need to change that pixel value in roi_color
                        roi_color[ey + i, ex+ j ] = glasses[i , j]
        
        
        #nose = nose_Cascade.detectMultiScale(roi_gray, 1.3, 5)
        #for (nx,ny,nw,nh) in nose:
            #cv2.rectangle(roi_color, (nx,ny), (nx+nw, ny+nh), (255,0,0),3)
            #roi_nose_gray = roi_gray[ny:ny+nh , nx:nx+nw]
            #roi_nose_color = roi_color[ny:ny+nh , nx:nx+nw]
            
        
             
    cv2.imshow("Video Frame",frame)

    frame = cv2.cvtColor(frame , cv2.COLOR_BGRA2BGR)
    
    # Wait for user Input s, then you will stop the loop
    key_pressed = cv2.waitKey(1) & 0xFF # for converting waitkey(32 bit) into 8 bit
    if key_pressed == ord('s'):
        break

cap.release()
cv2.destroyAllWindows()
1 Answers

It is happening at this line:

glasses = cv2.resize(glasses, (ew,eh), interpolation = cv2.INTER_AREA)

because you keep resizing the glasses up and down in size at every iteration overwriting the original, so the same pair of glasses gets made bigger, then smaller, then bigger.


Instead, you should start from the original, high-quality glasses rather than from the resized glasses from the previous frame. So, outside the loop, change this line:

glasses = cv2.imread('glasses.png', -1) 

to

origGlasses = cv2.imread('glasses.png', -1) 

And inside the loop, change this line:

glasses = cv2.resize(glasses, (ew,eh), interpolation = cv2.INTER_AREA)

to:

glasses = cv2.resize(origGlasses, (ew,eh), interpolation = cv2.INTER_AREA)
Related