Я использую скрипт Python в проекте C ++. Этот скрипт использует изображения подушек и обрабатывает их. Чтобы использовать его, я сделал небольшую инкапсуляцию API Python C. При использовании функции PIL.Image.new первый раз хорош, но во второй я получаю указатель NULL.
Короче говоря, я получаю изображения для динамической обработки в формате opencv. Я создаю свои изображения с помощью pillow.Image.new
(см. ref ) и устанавливаю содержимое с помощью pillow.Image.putpixel
(см. ref ). При первом вызове работает нормально, изображение корректно обрабатывается скриптом python. Как ни странно, при втором звонке вылетает. Это обычное поведение или я делаю что-то глупое здесь?
Я на Windows 7, использую Python 3.7, PILLOW на версии 5.4.1, и у меня есть все необходимые .dll либо для openCV или дляпитон. Поскольку я использую Visual Studio, я использовал отладчик для проверки всех переменных. Модуль взимается также за новый метод. Ширина и высота моего изображения хорошая, а формат правильный. И в первый И во второй (и более) раз.
Без использования инкапсуляции и перехода к точке код выглядел бы так:
cv::VideoCapture cap("PathForMyVideo");
PyObject *PIL, *Image, *ImageNew, *PILImage, *putpixel; // Pillow variables
PyObject *Arg; // Tool for arguments
cv::Mat frame;
/* PILLOW module / class / method Import */
PIL = PyImport_Import(PyUnicode_FromString("PIL"));
Image = PyObject_GetAttrString(PIL, "Image");
ImageNew= PyObject_GetAttrString(Image, "new");
// Here I load the everything from the python script that process the images
cap >> frame; // Get the frame from the video - In BGR format
while (!frame.empty())
{
Arg = Py_BuildValue("(s(ii))", "RGB", frame.cols, frame.rows); // 1920 x 1080
PILImage = PyEval_CallObject(ImageNew, Arg); // Here is where I receive a NULL on the second iteration
putpixel = PyObject_GetAttrString(PILImage, "putpixel");
Py_DECREF(Arg);
int i = 0, x = 0, y;
while (x < p_Rows) {
y = 0;
while (y < p_Cols) {
Arg = Py_BuildValue("((ii)(iii))", y, x, (int)frame.data[i + 2], (int)frame.data[i + 1], (int)frame.data[i]); // Opencv is BGR so we have to reorder the bytes
m_pImageSetPixel->Execute(Arg);
Py_DECREF(Arg);
y++;
i += p_PixelSize;
}
x++;
}
// 1. Calls the script function
// 2. Displays the process image using the openCV frame
// Clean and free the pointer no longer needed
Py_DECREF(putpixel);
Py_DECREF(PILImage);
cap >> frame; // Retreive a new frame and iterate
}
// Free everything from PILLOW and close the video
Мне бы хотелось иметь возможность сохранять изображение PIL в памяти и выделять его только один раз. но полученные изображения будут меняться в размерах, поэтому я должен распределять их при каждом вызове.
Я не понимаю, что у меня нет утечки памяти, моя память при необходимости освобождается. Зачем PIL.Image.new возвращать NULL при втором вызове, если при вызове у меня совпадают значения?