Ошибка при получении: (-215: утверждение не выполнено) При использовании seamlessClone - PullRequest
0 голосов
/ 10 октября 2019

Для ясности я новичок в Python. Я создаю сценарий, который заменяет глаза на роботизированный из серии изображений в папке. Я застрял на функции seamlessClone, которая продолжает выдавать эту ошибку.

Код неполный, поскольку выписывает весь сценарий (пока он клонирует только один глаз), но все должно работать. Я застрял на этом в течение 6 часов и думал, что спросить здесь.

Я попытался проверить мои имена файлов, пути, посмотреть, не поврежден ли файл изображения с помощью печати, изменив файлы изображенийс разными размерами, типами файлов (PNG, JPG) и так далее.

Я также пытался преобразовать каждый массив numpy (cv2_image, Eye) в 32-битный массив, чтобы увидеть, была ли это проблема, но ничего не получилось.

# Import

from PIL import Image, ImageDraw, ImageFilter
from statistics import mean
import face_recognition
import cv2
import glob
import numpy as np


# Open Eye Images

Eye = cv2.imread('eye.jpg')

# Loop Through Images

for filename in glob.glob('images/*.jpg'):

    cv2_image = cv2.imread(filename)
    image = face_recognition.load_image_file(filename)
    face_landmarks_list = face_recognition.face_landmarks(image)
    for facemarks in face_landmarks_list:

        # Get Eye Data
        eyeLPoints = facemarks['left_eye']
        eyeRPoints = facemarks['right_eye']
        npEyeL = np.array(eyeLPoints)
        npEyeR = np.array(eyeRPoints)

        # Create Mask

        mask = np.zeros(cv2_image.shape, cv2_image.dtype)
        mask.fill(0)
        poly = np.array([eyeLPoints])
        cv2.fillPoly(mask, [poly], (255,255, 255))

        # Get Eye Image Centers 

        npEyeL = np.array(eyeLPoints)
        eyeLCenter = npEyeL.mean(axis=0).astype("int")
        x1 = (eyeLCenter[0])
        x2 = (eyeLCenter[1])
        print(x1, x2)

        # Get Head Rotation (No code yet)

        # Apply Seamless Clone To Main Image
        saveImage = cv2.seamlessClone(Eye, cv2_image, mask ,(x1, x2) , cv2.NORMAL_CLONE)

# Output and Save

cv2.imwrite('output/output.png', saveImage)

Вот полная ошибка:

Traceback (most recent call last):
  File "stack.py", line 45, in <module>
    saveImage = cv2.seamlessClone(Eye, cv2_image, mask ,(x1, x2) , cv2.NORMAL_CLONE)
cv2.error: OpenCV(4.1.1) /io/opencv/modules/core/src/matrix.cpp:466: error: (-215:Assertion failed) 0 <= roi.x && 0 <= roi.width && roi.x + roi.width <= m.cols && 0 <= roi.y && 0 <= roi.height && roi.y + roi.height <= m.rows in function 'Mat'

В результате я ожидаю, что изображение глаза будет клонировано на исходное изображение, но эта ошибка продолжает появляться,мешает мне завершить сценарий. Если бы был какой-то намек на то, что происходит, я чувствую, что виновником является файл «Глаза», но я могу ошибаться. Любая помощь будет оценена.

1 Ответ

0 голосов
/ 10 октября 2019

Существует два набора ключевых точек:

  • Существует набор ключевых точек для глаза на целевом изображении: keypoints dst image
  • Естьнабор ключевых точек для глаза на исходном изображении: keypoints source image

Вы используете неправильный набор ключевых точек для создания маски для функции cv2.seamlessClone(). Вы должны использовать ключевые точки из исходного изображения. Маска должна быть изображением с двумя каналами, в вашем коде (среди других проблем) вы используете изображение с тремя каналами.

Это результат. Вы также можете видеть, что должна быть функция изменения размера, чтобы соответствовать размеру глаз:

output

Это код, который я использовал:

import face_recognition
import cv2
import numpy as np

# Open Eye Images
eye = cv2.imread('eye.jpg')

# Open Face image
face = cv2.imread('face.jpeg')
# Get Keypoints
image = face_recognition.load_image_file('face.jpeg')
face_landmarks_list = face_recognition.face_landmarks(image)
for facemarks in face_landmarks_list:
    # Get Eye Data
    eyeLPoints = facemarks['left_eye']
    eyeRPoints = facemarks['right_eye']
    npEyeL = np.array(eyeLPoints)

# These points define the contour of the eye in the EYE image
poly_left = np.array([(51, 228), (100, 151), (233, 102), (338, 110), (426, 160), (373, 252), (246, 284), (134, 268)], np.int32)

# Create a mask for the eye
src_mask = np.zeros(face.shape, face.dtype)
cv2.fillPoly(src_mask, [poly_left], (255, 255, 255))
cv2.imwrite('src_mask.png', src_mask)
# Find where the eye should go
center, r = cv2.minEnclosingCircle(npEyeL)
center = tuple(np.array(center, int))
# Clone seamlessly.
output = cv2.seamlessClone(eye, face, src_mask, center, cv2.NORMAL_CLONE)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...