Python OpenCv2 coloca la imagen sobre la cara encontrada

Oct 02 2020

Estoy cargando varias imágenes que pasarán por mi cara y tengo dificultades para que la imagen pase sobre el cuadrado de la cara creada. He examinado muchos recursos, pero por alguna razón recibo un error al intentar seguir su método.

Cada vez que lo hago, recibo un error.

ValueError: no se pudo transmitir la matriz de entrada de la forma (334,334,3) a la forma (234,234,3)

Creo que las imágenes pueden ser demasiado grandes, sin embargo, traté de cambiar su tamaño para ver si encajaban en vano.

aquí está mi código:

import cv2
import sys
import logging as log
import datetime as dt
from time import sleep
import os
import random 
from timeit import default_timer as timer


cascPath = "haarcascade_frontalface_default.xml"
faceCascade = cv2.CascadeClassifier(cascPath)
#log.basicConfig(filename='webcam.log',level=log.INFO)

video_capture = cv2.VideoCapture(0)
anterior = 0

#s_img = cv2.imread("my.jpg")

increment = 0

for filename in os.listdir("Faces/"):
    if filename.endswith(".png"): 
         FullFile = (os.path.join("Faces/", filename))
         #ret, frame = video_capture.read()
         frame = cv2.imread(FullFile, cv2.IMREAD_UNCHANGED)

         gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
         faces = faceCascade.detectMultiScale( gray,scaleFactor=1.1, minNeighbors=5, minSize=(30, 30)  )
         edges = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 9, 9) 
         
         for (x, y, w, h) in faces:            
            roi_color = frame[y:( y ) + ( h ), x:x + w]
            status = cv2.imwrite('export/faces_detected'+ str( increment ) +'.png', roi_color)
            increment = increment + 1 

        
    else:
        continue

masks = []


for filename in os.listdir("export/"):
    if filename.endswith(".png"): 
         FullFile = (os.path.join("export/", filename))
         s_img = cv2.imread(FullFile)
         masks.append(s_img)


Start = timer()
End = timer()
MasksSize = len(masks)
nrand = random.randint(0, MasksSize -1 )

increment =  0

while True:
    if not video_capture.isOpened():
        print('Unable to load camera.')
        sleep(5)
        pass

    # Capture frame-by-frame
    ret, frame = video_capture.read()

    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    faces = faceCascade.detectMultiScale(
        gray,
        scaleFactor=1.1,
        minNeighbors=5,
        minSize=(30, 30)
    )



    edges = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 9, 9) 


    # Draw a rectangle around the faces
    for (x, y, w, h) in faces:
        if (End - Start) > 3:
            Start = timer()
            End = timer()
            nrand = random.randint(0, MasksSize -1 )


        # -75 and +20 added to fit my face
        cv2.rectangle(frame, (x, y - 75), (x+w, y+h+20), (0, 255, 0), 2)
        s_img = masks[nrand]  
        increment = increment + 1 
        #maskresize = cv2.resize(s_img, (150, 150))


        #frame[y:y+s_img.shape[0]  , x:x+s_img.shape[1]] = s_img # problem occurs here with 


        # ValueError: could not broadcast input array from shape (334,334,3) into shape (234,234,3)
        # I assume I am inserting somethign too big? 
        End = timer()
        


        


    if anterior != len(faces):
        anterior = len(faces)
        #log.info("faces: "+str(len(faces))+" at "+str(dt.datetime.now()))


    # Display the resulting frame
    cv2.imshow('Video', frame)
    #cv2.imshow('Video', cartoon)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

    # Display the resulting frame
    cv2.imshow('Video', frame)

# When everything is done, release the capture
video_capture.release()
cv2.destroyAllWindows()

Respuestas

1 KarthikSanka Oct 03 2020 at 03:44
  • En la siguiente línea,
frame[y:y+s_img.shape[0]  , x:x+s_img.shape[1]] = s_img 

está intentando asignar s_img al marco [y: y + s_img.shape [0], x: x + s_img.shape [1]] que tienen diferentes formas.

  • Puede verificar las formas de los dos imprimiendo la forma (será la misma que las formas mencionadas en el error).
  • Intente remodelar s_img a la misma forma y luego intente asignar.
Consulte este enlace: https://www.geeksforgeeks.org/image-resizing-using-opencv-python/

Usé esta función para cambiar el tamaño de la imagen a escala.

def image_resize(image, width = None, height = None, inter = cv2.INTER_AREA):
    # initialize the dimensions of the image to be resized and
    # grab the image size
    dim = None
    (h, w) = image.shape[:2]

    # if both the width and height are None, then return the
    # original image
    if width is None and height is None:
        return image

    # check to see if the width is None
    if width is None:
        # calculate the ratio of the height and construct the
        # dimensions
        r = height / float(h)
        dim = (int(w * r), height)

    # otherwise, the height is None
    else:
        # calculate the ratio of the width and construct the
        # dimensions
        r = width / float(w)
        dim = (width, int(h * r))

    # resize the image
    resized = cv2.resize(image, dim, interpolation = inter)

    # return the resized image
    return resized

Luego más tarde llamó

 r= image_resize(s_img, height = h, width=w)
 frame[y:y+r.shape[0]  , x:x+r.shape[1]] = r 

Respuesta también tomada de aquí: Cambiar el tamaño de una imagen sin distorsión OpenCV