Alenorze
@Alenorze
Не люблю Индию

Как конвертировать OpenCV Mat в Python ndarray?

Всем привет знатоки, вообщем есть функция которую я использую через Python Boost, мне нужно в Python передать OpenCV Mat, при попытке сделать это на прямую boost выдает TypeError: No to_python (by-value) converter found for C++ type: cv::Mat, что логично тк Python не использует ndarray для изображений.

#include <iostream>
#include <opencv2/highgui.hpp>
#include "opencv2/cudawarping.hpp"
#include <boost/python.hpp>

using namespace std;
using namespace cv;


Mat gpuResize(string path, int maxwidth, int height)
{   
    Mat inputCpu = imread(path, IMREAD_COLOR);
    cuda::GpuMat input(inputCpu);
    cuda::GpuMat output;
    cuda::resize(input, output, Size(maxwidth, height), 0, 0, INTER_LINEAR);
    
    Mat outputCpu;
    output.download(outputCpu);

    // PyObject* ret = toNDArray(outputCpu);

    return outputCpu;
}

char const* greet()
{
   return "hello, world";
}


BOOST_PYTHON_MODULE(cvcuda)
{
    using namespace boost::python;
    def("gpuResize",gpuResize);
}


from cvcuda import gpuResize
path = '/home/alenorze/Workspace/Current/hair/backend/test_data/0e6303c4-0b29-457e-ab74-ac2d1cfb1ecf.jpeg'
maxwidth = 650
height = 500
print(gpuResize(path, maxwidth, height))


Мне нужно простое решение, все конвертеры в десятки тысяч строк устарели, и их сложно запустить. Заранее спасибо за помощь.
  • Вопрос задан
  • 507 просмотров
Решения вопроса 1
Alenorze
@Alenorze Автор вопроса
Не люблю Индию
Вообщем есть одно решение, и оно совершенно неправильное, но логичное. OpenCV не имеет кода для Python, он полностью на C++, в python/src2/cv2.cpp есть конвертер, которые способен конвертировать много чего, в том числе и Mat, но поскольку чтобы его запустить отдельно нужно иметь хоть какой то опыт с плюсами(которого у меня нет).
Я решил видоизменить саму библиотеку и вставить в нее новые функции, чтобы импортировать сразу через cv2. Я нашел функцию imread внутри loadsave.cpp, добавил свою функцию, задекларировал рядом с imread, и все заработало, никаких проблем. Но опять же таки не рекомендую так делать, это грех.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@res2001
Developer, ex-admin
Делал в свое время вычислительный модуль для питона на Си, из модуля передавал Си массивы в питон и там их отображал с помощью Matplotlib. В модуле реализовал питоновский Buffer Protocol. Дальше в питоне получал такой объект от модуля и с помощью numpy.asarray() перегонял его в ndarray.
Если в основе Mat то же лежит обычный массив, то и для него можно реализовать Buffer Protocol похожим образом.
Как это делать с python boost не в курсе, я использовал Python C API.

Так же есть возможность непосредственно в модуле создавать numpy объекты, у numpy есть собственный numpy C API. Но с этим у меня опыта не было.

Более простых вариантов у меня нет.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы