Преобразование изображения, загруженного с помощью PIL, в объект изображения Cimg.

Я пытаюсь преобразовать iamge, загруженный с помощью PIL, в образ Cimg объект. Я понимаю, что Cimg — это библиотека C++, а PIL — библиотека изображений Python. Учитывая URL-адрес изображения, моя цель — вычислить pHash изображения, не записывая его на диск. Модуль pHash работает с 1CImg.html" rel="nofollow noreferrer">объектом изображения Cimg и реализован на C++. Поэтому я планирую отправить необходимые данные изображения из моей программы на Python в программу на С++, используя привязку расширения Python. В следующем фрагменте кода я загружаю изображение с заданного URL-адреса:

//python code sniplet   
import PIL.Image as pil

file = StringIO(urlopen(url).read())
img = pil.open(file).convert("RGB")

Объект изображения Cimg, который мне нужно создать, выглядит следующим образом:

CImg  ( const t *const  values,  
    const unsigned int  size_x,  
    const unsigned int  size_y = 1,  
    const unsigned int  size_z = 1,  
    const unsigned int  size_c = 1,  
    const bool  is_shared = false  
)

Я могу получить ширину (size_x) и высоту (size_y) с помощью img.size и передать их на С++. Я не уверен, как заполнить поле «значения» объекта Cimg? Какую структуру данных использовать для передачи данных изображения из кода python в код C++?

Кроме того, есть ли другой способ преобразовать образ PIL в Cimg?


person Shobhit Puri    schedule 09.03.2013    source источник


Ответы (2)


Я предполагаю, что ваше основное приложение написано на Python, и вы хотите вызывать код C++ из Python. Этого можно добиться, создав "модуль Python", который будет отображать все родные C /C++ для Python. Вы можете использовать такой инструмент, как SWIG, чтобы упростить свою работу.

Это лучшее решение вашей проблемы, которое пришло мне в голову.

person cubuspl42    schedule 09.03.2013
comment
Спасибо за ответ. Я пытался использовать упомянутый вами модуль расширения Python. Я не уверен, что передать для данных изображения. Вторая часть моего вопроса заключалась в том, что я не уверен, как заполнить поле «значения» объекта Cimg. Могу ли я просто использовать данные изображения, которые я загрузил, непосредственно в переменную «значение» внутри структуры Cimg? - person Shobhit Puri; 11.03.2013

Самый простой способ передать изображение из Python в программу на основе C++ CImg — через конвейер.

Итак, это программа на основе C++ CImg, которая считывает изображение из stdin и возвращает фиктивный pHash вызывающей программе Python — просто чтобы вы могли увидеть, как это работает:

#include "CImg.h"
#include <iostream>

using namespace cimg_library;
using namespace std;

int main()
{
    // Load image from stdin in PNM (a.k.a. PPM Portable PixMap) format
    cimg_library::CImg<unsigned char> image;
    image.load_pnm("-");

    // Save as PNG (just for debug) rather than generate pHash
    image.save_png("result.png");

    // Send dummy result back to Python caller
    std::cout << "pHash = 42" << std::endl;
}

А вот программа на Python, которая загружает изображение с URL-адреса, преобразует его в PNM/PPM ("Portable PixMap") и отправляет его в программу C++, чтобы она могла сгенерировать и вернуть pHash:

#!/usr/bin/env python3

import requests
import subprocess
from PIL import Image
from io import BytesIO

# Grab image and open as PIL Image
url = 'https://i.stack.imgur.com/DRQbq.png'
response = requests.get(url)
img = Image.open(BytesIO(response.content)).convert('RGB')

# Generate in-memory PPM image which CImg can read without any libraries
with BytesIO() as buffer:
    img.save(buffer,format="PPM")
    data = buffer.getvalue()

# Start CImg passing our PPM image via pipe (not disk)
with subprocess.Popen(["./main"], stdin=subprocess.PIPE, stdout=subprocess.PIPE) as proc:
    (stdout, stderr) = proc.communicate(input=data)

print(f"Returned: {stdout}")

Если вы запустите программу Python, вы получите:

Returned: b'pHash = 42\n'
person Mark Setchell    schedule 21.01.2020