5

我正在尝试将使用PIL加载的 iamge 转换为 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 对象的“值”字段?使用什么样的数据结构将图像数据从 python 传递到 c++ 代码?

另外,还有其他方法可以将 PIL 图像转换为 Cimg 吗?

4

2 回答 2

0

我假设您的主应用程序是用 Python 编写的,并且您想从 Python 调用 C++ 代码。您可以通过创建一个“ Python 模块”来实现这一点,它将所有本机 C/C++ 功能暴露给 Python。您可以使用 SWIG 之类的工具来简化您的工作。

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

于 2013-03-09T17:21:15.107 回答
0

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

所以这是一个基于 C++ CImg 的程序,它从 Python 调用者读取图像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(“便携式 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'
于 2020-01-21T15:02:53.093 回答