Python OpenCv2 얼굴 위에 이미지를 배치했습니다.

Oct 02 2020

여러 장의 이미지를 불러오는 중입니다. 내 얼굴을 덮을 수 있으며 얼굴을 만들기 위해 이미지가 사각형을 넘어가는 데 어려움이 있습니다. 많은 리소스를 살펴 보았지만 어떤 이유로 든 방법을 따르려고 할 때 오류가 발생합니다.

그렇게 할 때마다 오류가 발생합니다.

ValueError : 모양 (334,334,3)에서 모양 (234,234,3)으로 입력 배열을 브로드 캐스트 할 수 없습니다.

이미지가 너무 클 수 있다고 생각하지만 크기를 조정하여 아무 소용이 없는지 확인했습니다.

내 코드는 다음과 같습니다.

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

답변

1 KarthikSanka Oct 03 2020 at 03:44
  • 다음 줄에서
frame[y:y+s_img.shape[0]  , x:x+s_img.shape[1]] = s_img 

s_img를 다른 모양의 frame [y : y + s_img.shape [0], x : x + s_img.shape [1]] 에 할당하려고합니다 .

  • 모양을 인쇄하여 둘의 모양을 확인할 수 있습니다 (오류에 언급 된 모양과 동일합니다).
  • s_img 를 동일한 모양으로 변경 한 다음 할당 해보십시오.
이 링크를 참조하십시오 : https://www.geeksforgeeks.org/image-resizing-using-opencv-python/

이 기능을 사용하여 이미지 크기를 조정했습니다.

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

그런 다음 나중에 전화

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

여기에서 가져온 답변 : 왜곡없이 이미지 크기 조정 OpenCV