Search code examples
pythonopencvcomputer-visionmediapipe

how to fix the size of the image so that it can be imposed on a Video using Opencv and media pipe


so i was trying to replicate a project from github https://github.com/GH0STH4CKER/Sunglass_Overlay_Effect/tree/main to create the augmented reality sunglasses using opencv

the following is the code:-

import cv2
import mediapipe as mp
import numpy as np 
import keyboard

face = mp.solutions.face_detection
drawing = mp.solutions.drawing_utils

address = 'images2.jpeg'

cap = cv2.VideoCapture(0)

with face.FaceDetection(min_detection_confidence = 0.5) as face_detection :
    while cap.isOpened():
        success, image = cap.read()
        imgFront = cv2.imread(address, cv2.IMREAD_UNCHANGED)
        
        s_h, s_w, _ = imgFront.shape
        image_Height, image_Width, _ = image.shape
        
        results = face_detection.process(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)) 
        
        if results.detections:
            for detection in results.detections :
                
                normalizedLandmark = face.get_key_point(detection, face.FaceKeyPoint.NOSE_TIP)
                pixelCoordinatesLandmark = drawing._normalized_to_pixel_coordinates(normalizedLandmark.x, normalizedLandmark.y, image_Width, image_Height)
                Nose_tip_x = pixelCoordinatesLandmark[0]
                Nose_tip_y = pixelCoordinatesLandmark[1]
                
                normalizedLandmark = face.get_key_point(detection, face.FaceKeyPoint.LEFT_EAR_TRAGION)
                pixelCoordinatesLandmark = drawing._normalized_to_pixel_coordinates(normalizedLandmark.x, normalizedLandmark.y, image_Width, image_Height)
                Left_Ear_x = pixelCoordinatesLandmark[0]
                Left_Ear_y = pixelCoordinatesLandmark[1]
                
                normalizedLandmark = face.get_key_point(detection, face.FaceKeyPoint.RIGHT_EAR_TRAGION)
                pixelCoordinatesLandmark = drawing._normalized_to_pixel_coordinates(normalizedLandmark.x, normalizedLandmark.y, image_Width, image_Height)
                Right_Ear_x = pixelCoordinatesLandmark[0]
                Right_Ear_y = pixelCoordinatesLandmark[1]
                
                normalizedLandmark = face.get_key_point(detection, face.FaceKeyPoint.LEFT_EYE)
                pixelCoordinatesLandmark = drawing._normalized_to_pixel_coordinates(normalizedLandmark.x, normalizedLandmark.y, image_Width, image_Height)
                Left_Eye_x = pixelCoordinatesLandmark[0]
                Left_Eye_y = pixelCoordinatesLandmark[1]
                
                normalizedLandmark = face.get_key_point(detection, face.FaceKeyPoint.RIGHT_EYE)
                pixelCoordinatesLandmark = drawing._normalized_to_pixel_coordinates(normalizedLandmark.x, normalizedLandmark.y, image_Width, image_Height)
                RIGHT_Eye_x = pixelCoordinatesLandmark[0]
                RIGHT_Eye_y = pixelCoordinatesLandmark[1]
                
                sunglass_width = int(Left_Ear_x - Right_Ear_x + 60)
                sunglass_height = int((s_h/s_w)*sunglass_width)
                
                imgFront = cv2.resize(imgFront, (sunglass_width, sunglass_height), None, 0.3, 0.3)
                hf, wf, cf = imgFront.shape
                
                hb, wb, cb = image.shape
                
                y_adjust = int((sunglass_height/80)*80)
                x_adjust = int((sunglass_width/194)*100)
                
                pos = [Nose_tip_x-x_adjust,Nose_tip_y-y_adjust]
                
                hf, wf, cf = imgFront.shape
                hb, wb, cb = image.shape
                *_, mask = cv2.split(imgFront)
                maskBGRA = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGRA)
                maskBGR = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR)
                imgRGBA = cv2.bitwise_and(imgFront, maskBGRA)
                imgRGB = cv2.cvtColor(imgRGBA, cv2.COLOR_BGRA2BGR)

                imgMaskFull = np.zeros((hb, wb, cb), np.uint8)
                imgMaskFull[pos[1]:hf + pos[1], pos[0]:wf + pos[0], :] = imgRGB
                imgMaskFull2 = np.ones((hb, wb, cb), np.uint8) * 255
                maskBGRInv = cv2.bitwise_not(maskBGR)
                imgMaskFull2[pos[1]:hf + pos[1], pos[0]:wf + pos[0], :] = maskBGRInv

                image = cv2.bitwise_and(image, imgMaskFull2)
                image = cv2.bitwise_or(image, imgMaskFull)
                
        cv2.imshow('Sunglass Effect', image)
        
        if keyboard.is_pressed('q'):
            break
        
        cv2.waitKey(5)      

cap.release()
cv2.destroyAllWindows()

the image size is ==> 338 x 149

I was expecting the image to overlay on my eyes but it gave me this error

imgRGBA = cv2.bitwise_and(imgFront, maskBGRA)
cv2.error: OpenCV(4.9.0) D:\a\opencv-python\opencv-python\opencv\modules\core\src\arithm.cpp:214: error: (-209:Sizes of input arguments do not match) The operation is neither 'array op array' (where arrays have the same size and type), nor 'array op scalar', nor 'scalar op array' in function 'cv::binary_op'


Solution

  • It seems like the error is occurring because the sizes of the input arrays (imgFront and maskBGRA) in the cv2.bitwise_and() operation do not match. To resolve this issue, you need to make sure that the dimensions of both arrays are compatible.
    
    Here's a modification to your code to address the issue:
    
    import cv2
    import mediapipe as mp
    import numpy as np 
    import keyboard
    
    face = mp.solutions.face_detection
    drawing = mp.solutions.drawing_utils
    
    address = 'images2.jpeg'
    
    cap = cv2.VideoCapture(0)
    
    with face.FaceDetection(min_detection_confidence=0.5) as face_detection:
        while cap.isOpened():
            success, image = cap.read()
            imgFront = cv2.imread(address, cv2.IMREAD_UNCHANGED)
    
            s_h, s_w, _ = imgFront.shape
            image_Height, image_Width, _ = image.shape
    
            results = face_detection.process(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)) 
    
            if results.detections:
                for detection in results.detections:
                    normalizedLandmark = face.get_key_point(detection, face.FaceKeyPoint.NOSE_TIP)
                    pixelCoordinatesLandmark = drawing._normalized_to_pixel_coordinates(normalizedLandmark.x, normalizedLandmark.y, image_Width, image_Height)
                    Nose_tip_x = pixelCoordinatesLandmark[0]
                    Nose_tip_y = pixelCoordinatesLandmark[1]
    
                    # ... (rest of your code)
    
                    imgFront = cv2.resize(imgFront, (sunglass_width, sunglass_height), None, 0.3, 0.3)
                    hf, wf, cf = imgFront.shape
    
                    y_adjust = int((sunglass_height/80)*80)
                    x_adjust = int((sunglass_width/194)*100)
    
                    pos = [Nose_tip_x-x_adjust, Nose_tip_y-y_adjust]
    
                    # Check if the image dimensions match
                    if pos[1] + hf > image_Height or pos[0] + wf > image_Width:
                        continue  # Skip this frame if the image exceeds the frame boundaries
    
                    # ... (rest of your code)
    
                    imgRGBA = cv2.bitwise_and(imgFront, imgFront, mask=mask)
    
                    imgRGB = cv2.cvtColor(imgRGBA, cv2.COLOR_BGRA2BGR)
    
                    # ... (rest of your code)
    
                    image = cv2.bitwise_and(image, imgMaskFull2)
                    image = cv2.bitwise_or(image, imgMaskFull)
    
            cv2.imshow('Sunglass Effect', image)
    
            if keyboard.is_pressed('q'):
                break
    
            cv2.waitKey(5)
    
    cap.release()
    cv2.destroyAllWindows()
    
    
    In this modification, cv2.bitwise_and() is applied directly to the imgFront array using its own mask. Additionally, a check is added to ensure that the image doesn't go beyond the frame boundaries`enter code here`, which might be the cause of the error you encountered. If the image exceeds the frame boundaries, the frame is skipped to avoid the error. Adjust the condition inside the if statement based on your specific requirements.