使用PIL加载的图像转换为Cimg图像对象

5
我正在尝试将使用PIL加载的图像转换为Cimg图像对象。我知道Cimg是一个C++库,而PIL是一个Python图像处理库。给定一个图像URL,我的目标是在不将其写入磁盘的情况下计算图像的pHash。pHash模块与Cimg图像对象一起使用,并已在C++中实现。因此,我计划使用Python扩展绑定从我的Python程序向C++程序发送所需的图像数据。在以下代码片段中,我正在从给定的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  
)

我可以使用img.size获取宽度(size_x)和高度(size_y),并将其传递给C++。我不确定如何填写Cimg对象的“values”字段?应该使用什么样的数据结构将图像数据从Python传递到C++代码中?
此外,是否有其他方法将PIL图像转换为Cimg?
2个回答

0

我猜你的主要应用程序是用Python编写的,而你想从Python中调用C++代码。你可以通过创建一个“Python模块”来实现这个目标,该模块将把所有本地的C/C++功能暴露给Python。你可以使用像SWIG这样的工具来使你的工作更轻松。

这是我能想到的解决你问题的最佳方案。


谢谢您的回复。我一直在尝试使用您提到的Python扩展模块。我不确定要传递什么图像数据。我的第二个问题是,“我不确定如何填写Cimg对象的'values'字段”。我能否直接将下载的图像数据用作Cimg结构中'value'变量的值? - Shobhit Puri

0

将图像从Python传递到基于C++ CImg的程序最简单的方法是通过管道。

因此,这是一个基于C++ CImg的程序,它从stdin读取图像,并向Python调用者返回虚拟pHash - 这样您就可以看到它的工作原理:

#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(“便携式像素图”),并将其发送到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://istack.dev59.com/DRQbq.webp'
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'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接