Python OpenCv2 posiziona l'immagine sul viso trovata

Oct 02 2020

Sto caricando diverse immagini che andranno sul mio viso e ho difficoltà a far passare l'immagine sul quadrato per il viso creato. Ho esaminato molte risorse, ma per qualche motivo ricevo un errore quando tento di seguire il loro metodo.

Ogni volta che lo faccio, ricevo un errore

ValueError: impossibile trasmettere l'array di input dalla forma (334,334,3) alla forma (234,234,3)

Penso che le immagini potrebbero essere troppo grandi, tuttavia ho provato a ridimensionarle per vedere se si adattano inutilmente.

ecco il mio codice:

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()

Risposte

1 KarthikSanka Oct 03 2020 at 03:44
  • Nella riga seguente,
frame[y:y+s_img.shape[0]  , x:x+s_img.shape[1]] = s_img 

stai tentando di assegnare s_img al frame [y: y + s_img.shape [0], x: x + s_img.shape [1]] che sono di forme diverse.

  • Puoi controllare le forme dei due stampando la forma (sarà la stessa delle forme menzionate nell'errore).
  • Prova a rimodellare s_img con la stessa forma e poi prova ad assegnare.
Fare riferimento a questo collegamento: https://www.geeksforgeeks.org/image-resizing-using-opencv-python/

Ho usato questa funzione per ridimensionare l'immagine in scala.

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

Poi in seguito chiamato

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

Risposta presa anche da qui: Ridimensiona un'immagine senza distorsioni OpenCV