ValueError: Входные данные имеют неправильный формат

Вопрос или проблема

Я сталкиваюсь с постоянной проблемой при запуске StableDiffusionInpaintPipeline для задачи инпейнтинга. Несмотря на то, что я передаю данные в ожидаемом формате (как изображение, так и маска имеют формат PIL.Image.Image с правильными размерами), я постоянно получаю следующую ошибку:

ValueError: Входные данные в неправильном формате. В настоящее время мы поддерживаем только <class 'PIL.Image.Image'>, <class 'numpy.ndarray'>, <class 'torch.Tensor'>

Вот код:

@torch.inference_mode()
def generate_image_bytes(base64_img, request, prompt) -> dict:
    # Получаем модель из пула
    model = model_pool.get_model()
    
    try:
        if base64_img is not None:
            img_data = base64.b64decode(base64_img)
            img = Image.open(io.BytesIO(img_data))

            print("Получено изображение размером: ", img.size)
        
        img = img.convert("RGB")
        image_np = np.array(img)
        
        roi_points = [
            request["box"]["x1"],
            request["box"]["y1"],
            request["box"]["x2"],
            request["box"]["y2"],
        ]

        results = model["seg_model"](
            image_np, 
            device="cuda", 
            conf=0.6, 
            iou=0.9, 
            bboxes=roi_points,
            labels=[1],
            verbose=False    
        )
        black_mask = np.zeros_like(image_np[:, :, 0], dtype=np.uint8)
        for m in results[0].masks.data:
            mask = m.cpu().numpy().astype(np.uint8)

            orig_shape = results[0].masks.orig_shape
            resized_mask = cv2.resize(mask, (orig_shape[1], orig_shape[0]))

            black_mask[resized_mask == 1] = 255
        
        image_pil = Image.fromarray(image_np)
        mask_pil = Image.fromarray(black_mask).convert("L")

        print(f"Размер изображения: {image_pil.size}, режим: {image_pil.mode}")
        print(f"Размер маски: {mask_pil.size}, режим: {mask_pil.mode}")
        
        generator = torch.Generator(device="cuda").manual_seed(0)

        image = model["pipeline"](
            prompt=prompt,
            negative_prompt=IMG_INPAINTING_NEG_PROMPT,
            image=image_pil,
            mask=mask_pil,
            guidance_scale=8.0,
            num_inference_steps=50,
            strength=0.05,
            generator=generator,
        ).images[0]

        # Преобразуем изображение в байты
        bytes = io.BytesIO()
        image.save(bytes, format="PNG")

        return {"bytes": base64.b64encode(bytes.getvalue()).decode("utf-8")}

Я пытался просматривать как изображения image_pil, так и mask_pil, и у них нет проблем. Их формат и размер также одинаковы, но я все еще получаю эту ошибку.

Ответ или решение

Ошибка ValueError: Input is in incorrect format в первой строке вашего сообщения указывает на то, что сигнал о неправильном формате входных данных передается в коде, когда вы работаете с StableDiffusionInpaintPipeline. Несмотря на то, что вы упоминаете, что изображения и маска находятся в формате PIL.Image.Image и имеют соответствующие размеры, проблема может быть связана с несколькими причинами.

Анализ проблемы

  1. Проверка формата данных:
    Убедитесь, что переданные изображения (как image_pil, так и mask_pil) действительно являются экземплярами класса PIL.Image.Image. Используйте встроенный метод type() для дополнительной проверки, прежде чем передавать эти данные в метод модели. Например, добавьте следующие строки в вашу функцию перед вызовом модели:

    print(f"Image type: {type(image_pil)}")
    print(f"Mask type: {type(mask_pil)}")

    Это поможет вам убедиться, что данные действительно находятся в нужном формате.

  2. Проверка размеров изображений:
    Некоторые модели могут требовать изображений и масок, которые имеют размер, кратный определенному числу (например, 8 или 16). Проверьте, соответствуют ли размеры image_pil и mask_pil требованиям модели.

    print(f"Image size: {image_pil.size}")
    print(f"Mask size: {mask_pil.size}")
  3. Проблемы с каналами изображения:
    Убедитесь, что у маски правильное количество каналов. Ваша маска должна быть черно-белой, т.е. иметь режим "L". Вы уже выполняете конвертацию в "L", но рекомендуется также проверять, действительно ли маска имеет единственный канал:

    print(f"Mask mode after conversion: {mask_pil.mode}")
  4. Входные данные в модели:
    Метод model["pipeline"] может требовать, чтобы передаваемые изображения были предварительно подогнаны под определенные требования. Убедитесь, что вы используете правильные параметры, включая правильные значения для guidance_scale, num_inference_steps и strength, в том числе форматы для вашего конкретного случая использования.

Пример улучшенной отладки

Вот пример, как можно улучшить ваш код для точной отладки:

# Проверка типа и размера изображения и маски
assert isinstance(image_pil, Image.Image), "Image is not in the correct format"
assert isinstance(mask_pil, Image.Image), "Mask is not in the correct format"

print(f"Image dimensions: {image_pil.size}, Mask dimensions: {mask_pil.size}")
print(f"Image type: {type(image_pil)}, Mask type: {type(mask_pil)}")

# Перед вызовом модели добавьте дополнительные проверки
try:
    image = model["pipeline"](prompt=prompt, ...)
except ValueError as e:
    print(f"Error calling the model: {e}")
    print(f"Image: {image_pil}")
    print(f"Mask: {mask_pil}")

Заключение

Работая с моделями глубокого обучения, очень важно контролировать форматы и размеры входных данных. Используйте приведенные выше шаги для диагностики и устранения проблемы. Если проблема продолжает возникать, возможно, стоит обратиться к документации к используемой модели или на форум поддержки, где можно найти информацию о совместимости форматов. Поддержание professionalism и тщательность в коде могут значительно снизить вероятность возникновения подобных ошибок в будущем.

Оцените материал
Добавить комментарий

Капча загружается...