2

我在 python 3.3 上使用 Tkinter 和 python.boost。

我想创建一个在中心显示图像的简单 gui。图像使用双精度值存储在 C++ 类中。为了使用 tkinter 显示图像,我必须创建一个PhotoImage对象。

我读过可以使用Image.fromstring(mode, size, data, decoder, parameters)方法创建一个 PhotoImage 对象。我的想法是:如果我创建一个将缓冲区转换为 std::string 的函数,我将能够创建一个 PhotoImage 对象。

我的 C++ 类是:

class DoubleImage
{
    double* m_dBuffer; // Values from 0 to 1

public:
    DoubleImage(const char* fileName, const int width, const int height);

    /* Class Functions  */

    std::string toString( void ) {
        double *pSrc  = m_dBuffer;
        int size = getWidth() * getHeight() * getChannels();

        char* buffer = new char[size];
        char* pbuffer = buffer;

        for ( int i = 0; i < size; ++i, ++pSrc, ++pbuffer ) {
            *pbuffer = ((char) (*pSrc * 255.0));
        }

        std::string ret(buffer);

        delete[] buffer;

        return ret;
    }
};

而python boost代码是:

using namespace boost::python;

BOOST_PYTHON_MODULE(ImageModule)
{

    class_<DoubleImage>("DoubleImage", init<const char*, const int, const int>()) 
        .add_property("width", &DoubleImage::getWidth)
        .add_property("height", &DoubleImage::getHeight)
        .add_property("channels", &DoubleImage::getChannels)
        // Some functions ...
        .def("toString", &DoubleImage::toString)
    ; 
}

但是当我在 python 中运行 toString 时,会出现以下错误:

>>> from ImageModule import *
>>> img = DoubleImage('001.png', 300, 200)
>>> buffer = img.toString()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x86 in position 155: invalid start byte
>>>

我有两个问题,首先我错过了什么?第二,一旦我解决了这个错误,我必须使用哪些参数来创建 PhotoImage 对象?

4

1 回答 1

0

终于在痛苦中找到了解决方案:P

首先必须像这样更改函数toString :

std::string DoubleImage::toString( void ) {
    ECV_CHECK_ERROR ( m_eType == IT_UKNOWN, "The image is not initialized!" );

    double *pSrc  = (double *) m_cvImage.data;
    long size = getWidth() * getHeight() * getChannels();

    std::string ret(size, ' ');

    for ( long i = 0; i < size; ++i, ++pSrc ) {
         ret[i] = ((char) (*pSrc * 255.0));
    }

    return ret;
}

否则,生成的 std::string 不会有总长度(因为构造函数搜索第一个 '\0')。另外奇怪的错误“ UnicodeDecodeError ”,仅在使用python 3.3时出现。通过使用 python 2.7 解决了这个问题。因此,我建议使用 python 2.7 进行图像处理。

然后我安装了PIL 模块(也只在 python 2.7 上可用)。然后在 python 中,我使用以下代码创建 PhotoImage 对象:

>>> from ImageModule import *
>>> from PIL import image
>>> from ImageTk import PhotoImage
>>> img = DoubleImage('001.png', 300, 200)
>>> buffer = img.toString()
>>> img_pil = Image.fromstring('RGB', [300, 200], buffer, 'raw', 'BGR', 300 * 3, 0)
>>> tk_image = PhotoImage(img_pil)

其中 300 是图像,200 是图像高度,RGB 是输出格式,BGR 是输入格式(IplImage),3 是通道(3 * 300 图像步长)。然后一切都像魅力一样工作:)

于 2012-12-03T13:49:08.160 回答