如何 return 包含 PyObject* 的 boost::python::tuple?
How do I return a boost::python::tuple containing a PyObject*?
我目前有一个 boost.python class 用于从 basler 相机获取图像,将它们转换为 opencv 图像并 return 它们作为 [=26= 的 numpy 数组] 脚本。
我最初有以下有效的代码:
PyObject *capture()
{
PyObject * ret;
CGrabResultPtr ptrGrabResult;
CPylonImage pylonImage;
Mat image;
//timer t;
try
{
// Set timer to 0
//t.reset();
// get a pointer to pylon image
camera->RetrieveResult( 50000, ptrGrabResult, TimeoutHandling_ThrowException);
// Get dimensions of image
int imageWidthPixels = ptrGrabResult->GetWidth();
int imageHeightPixels = ptrGrabResult->GetHeight();
if (ptrGrabResult->GrabSucceeded())
{
// Convert Grab result from YUV422 to BGR8
formatConverter->Convert(pylonImage, ptrGrabResult);
// Convert pylon image to opencv image
image = Mat(imageHeightPixels, imageWidthPixels, CV_8UC3, (std::uint8_t *) pylonImage.GetBuffer());
// Convert opencv image to PyObject
ret = pbcvt::fromMatToNDArray(image);
return ret;
}
else
{
//cout << "Error: " << ptrGrabResult->GetErrorCode() << " " << ptrGrabResult->GetErrorDescription() << endl;
}
}
catch (const GenericException &e)
{
// Error handling.
cerr << "An exception occurred." << endl
<< e.GetDescription() << endl;
}
// Return empty image if acquisition failed
return pbcvt::fromMatToNDArray(Mat());
}
但是我想模拟 opencv 的 VideoCapture 函数和 return 元组的方式
因此,我天真地修改了代码:
boost::python::tuple capture()
{
PyObject * ret;
CGrabResultPtr ptrGrabResult;
CPylonImage pylonImage;
Mat image;
//timer t;
try
{
// Set timer to 0
//t.reset();
// get a pointer to pylon image
camera->RetrieveResult( 50000, ptrGrabResult, TimeoutHandling_ThrowException);
// Get dimensions of image
int imageWidthPixels = ptrGrabResult->GetWidth();
int imageHeightPixels = ptrGrabResult->GetHeight();
if (ptrGrabResult->GrabSucceeded())
{
// Convert Grab result from YUV422 to BGR8
formatConverter->Convert(pylonImage, ptrGrabResult);
// Convert pylon image to opencv image
image = Mat(imageHeightPixels, imageWidthPixels, CV_8UC3, (std::uint8_t *) pylonImage.GetBuffer());
// Convert opencv image to PyObject
ret = pbcvt::fromMatToNDArray(image);
return boost::python::make_tuple(true, ret);
}
else
{
//cout << "Error: " << ptrGrabResult->GetErrorCode() << " " << ptrGrabResult->GetErrorDescription() << endl;
}
}
catch (const GenericException &e)
{
// Error handling.
cerr << "An exception occurred." << endl
<< e.GetDescription() << endl;
}
// Return opencv image
return boost::python::make_tuple(false, pbcvt::fromMatToNDArray(Mat()));
}
但是当我尝试编译时出现以下错误:
In file included from /usr/include/boost/python/call.hpp:15:0,
from /usr/include/boost/python/object_core.hpp:14,
from /usr/include/boost/python/args.hpp:25,
from /usr/include/boost/python.hpp:11,
from /home/anand/docker/pybasler/src/pyBasler.cpp:3:
/usr/include/boost/python/converter/arg_to_python.hpp: In instantiation of ‘static void boost::python::converter::detail::reject_raw_object_helper<T, Convertibility>::error(Convertibility) [with T = _object; Convertibility = char*]’:
/usr/include/boost/python/converter/arg_to_python.hpp:189:57: required from ‘void boost::python::converter::detail::reject_raw_object_ptr(T*) [with T = _object]’
/usr/include/boost/python/converter/arg_to_python.hpp:217:36: required from ‘boost::python::converter::detail::pointer_deep_arg_to_python<Ptr>::pointer_deep_arg_to_python(Ptr) [with Ptr = _object*]’
/usr/include/boost/python/converter/arg_to_python.hpp:256:13: required from ‘boost::python::converter::arg_to_python<T>::arg_to_python(const T&) [with T = _object*]’
/usr/include/boost/python/object_core.hpp:292:44: required from ‘static PyObject* boost::python::api::object_initializer_impl<is_proxy, is_object_manager>::get(const T&, mpl_::false_) [with T = _object*; bool is_proxy = false; bool is_object_manager = false; PyObject = _object; mpl_::false_ = mpl_::bool_<false>]’
/usr/include/boost/python/object_core.hpp:235:13: required from ‘PyObject* boost::python::api::object_base_initializer(const T&) [with T = _object*; PyObject = _object]’
/usr/include/boost/python/object_core.hpp:250:46: required from ‘boost::python::api::object::object(const T&) [with T = _object*]’
/usr/include/boost/python/detail/make_tuple.hpp:25:9: required from ‘boost::python::tuple boost::python::make_tuple(const A0&, const A1&) [with A0 = bool; A1 = _object*]’
/home/anand/docker/pybasler/src/pyBasler.cpp:130:63: required from here
/usr/include/boost/python/converter/arg_to_python.hpp:181:72: error: incomplete type ‘boost::python::converter::detail::cannot_convert_raw_PyObject<_object*>’ used in nested name specifier
cannot_convert_raw_PyObject<T*>::to_python_use_handle_instead();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
/usr/include/boost/python/converter/arg_to_python.hpp: In instantiation of ‘static void boost::python::converter::detail::reject_raw_object_helper<T, Convertibility>::error(Convertibility) [with T = _object; Convertibility = int*]’:
/usr/include/boost/python/converter/arg_to_python.hpp:194:56: required from ‘void boost::python::converter::detail::reject_raw_object_ptr(T*) [with T = _object]’
/usr/include/boost/python/converter/arg_to_python.hpp:217:36: required from ‘boost::python::converter::detail::pointer_deep_arg_to_python<Ptr>::pointer_deep_arg_to_python(Ptr) [with Ptr = _object*]’
/usr/include/boost/python/converter/arg_to_python.hpp:256:13: required from ‘boost::python::converter::arg_to_python<T>::arg_to_python(const T&) [with T = _object*]’
/usr/include/boost/python/object_core.hpp:292:44: required from ‘static PyObject* boost::python::api::object_initializer_impl<is_proxy, is_object_manager>::get(const T&, mpl_::false_) [with T = _object*; bool is_proxy = false; bool is_object_manager = false; PyObject = _object; mpl_::false_ = mpl_::bool_<false>]’
/usr/include/boost/python/object_core.hpp:235:13: required from ‘PyObject* boost::python::api::object_base_initializer(const T&) [with T = _object*; PyObject = _object]’
/usr/include/boost/python/object_core.hpp:250:46: required from ‘boost::python::api::object::object(const T&) [with T = _object*]’
/usr/include/boost/python/detail/make_tuple.hpp:25:9: required from ‘boost::python::tuple boost::python::make_tuple(const A0&, const A1&) [with A0 = bool; A1 = _object*]’
/home/anand/docker/pybasler/src/pyBasler.cpp:130:63: required from here
/usr/include/boost/python/converter/arg_to_python.hpp:181:72: error: incomplete type ‘boost::python::converter::detail::cannot_convert_raw_PyObject<_object*>’ used in nested name specifier
CMakeFiles/pbcvt.dir/build.make:62 : la recette pour la cible « CMakeFiles/pbcvt.dir/src/pyBasler.cpp.o » a échouée
make[2]: *** [CMakeFiles/pbcvt.dir/src/pyBasler.cpp.o] Erreur 1
CMakeFiles/Makefile2:67 : la recette pour la cible « CMakeFiles/pbcvt.dir/all » a échouée
make[1]: *** [CMakeFiles/pbcvt.dir/all] Erreur 2
Makefile:129 : la recette pour la cible « all » a échouée
make: *** [all] Erreur 2
我做错了什么?我怎样才能得到想要的结果?
问题的关键指标是编译错误中的这一行:
/usr/include/boost/python/converter/arg_to_python.hpp:181:72: error: incomplete type ‘boost::python::converter::detail::cannot_convert_raw_PyObject<_object*>’ used in nested name specifier
cannot_convert_raw_PyObject<T*>::to_python_use_handle_instead();
这说明您不能直接将 PyObject*
转换为 object
。您需要告诉它如何处理 PyObject*
的所有权。这是通过 boost::python::handle
类型完成的。
因此,更改此行:
return boost::python::make_tuple(true, ret);
至:
boost::python::make_tuple(true, boost::python::handle<>(ret));
将解决错误。
我目前有一个 boost.python class 用于从 basler 相机获取图像,将它们转换为 opencv 图像并 return 它们作为 [=26= 的 numpy 数组] 脚本。
我最初有以下有效的代码:
PyObject *capture()
{
PyObject * ret;
CGrabResultPtr ptrGrabResult;
CPylonImage pylonImage;
Mat image;
//timer t;
try
{
// Set timer to 0
//t.reset();
// get a pointer to pylon image
camera->RetrieveResult( 50000, ptrGrabResult, TimeoutHandling_ThrowException);
// Get dimensions of image
int imageWidthPixels = ptrGrabResult->GetWidth();
int imageHeightPixels = ptrGrabResult->GetHeight();
if (ptrGrabResult->GrabSucceeded())
{
// Convert Grab result from YUV422 to BGR8
formatConverter->Convert(pylonImage, ptrGrabResult);
// Convert pylon image to opencv image
image = Mat(imageHeightPixels, imageWidthPixels, CV_8UC3, (std::uint8_t *) pylonImage.GetBuffer());
// Convert opencv image to PyObject
ret = pbcvt::fromMatToNDArray(image);
return ret;
}
else
{
//cout << "Error: " << ptrGrabResult->GetErrorCode() << " " << ptrGrabResult->GetErrorDescription() << endl;
}
}
catch (const GenericException &e)
{
// Error handling.
cerr << "An exception occurred." << endl
<< e.GetDescription() << endl;
}
// Return empty image if acquisition failed
return pbcvt::fromMatToNDArray(Mat());
}
但是我想模拟 opencv 的 VideoCapture 函数和 return 元组的方式 因此,我天真地修改了代码:
boost::python::tuple capture()
{
PyObject * ret;
CGrabResultPtr ptrGrabResult;
CPylonImage pylonImage;
Mat image;
//timer t;
try
{
// Set timer to 0
//t.reset();
// get a pointer to pylon image
camera->RetrieveResult( 50000, ptrGrabResult, TimeoutHandling_ThrowException);
// Get dimensions of image
int imageWidthPixels = ptrGrabResult->GetWidth();
int imageHeightPixels = ptrGrabResult->GetHeight();
if (ptrGrabResult->GrabSucceeded())
{
// Convert Grab result from YUV422 to BGR8
formatConverter->Convert(pylonImage, ptrGrabResult);
// Convert pylon image to opencv image
image = Mat(imageHeightPixels, imageWidthPixels, CV_8UC3, (std::uint8_t *) pylonImage.GetBuffer());
// Convert opencv image to PyObject
ret = pbcvt::fromMatToNDArray(image);
return boost::python::make_tuple(true, ret);
}
else
{
//cout << "Error: " << ptrGrabResult->GetErrorCode() << " " << ptrGrabResult->GetErrorDescription() << endl;
}
}
catch (const GenericException &e)
{
// Error handling.
cerr << "An exception occurred." << endl
<< e.GetDescription() << endl;
}
// Return opencv image
return boost::python::make_tuple(false, pbcvt::fromMatToNDArray(Mat()));
}
但是当我尝试编译时出现以下错误:
In file included from /usr/include/boost/python/call.hpp:15:0,
from /usr/include/boost/python/object_core.hpp:14,
from /usr/include/boost/python/args.hpp:25,
from /usr/include/boost/python.hpp:11,
from /home/anand/docker/pybasler/src/pyBasler.cpp:3:
/usr/include/boost/python/converter/arg_to_python.hpp: In instantiation of ‘static void boost::python::converter::detail::reject_raw_object_helper<T, Convertibility>::error(Convertibility) [with T = _object; Convertibility = char*]’:
/usr/include/boost/python/converter/arg_to_python.hpp:189:57: required from ‘void boost::python::converter::detail::reject_raw_object_ptr(T*) [with T = _object]’
/usr/include/boost/python/converter/arg_to_python.hpp:217:36: required from ‘boost::python::converter::detail::pointer_deep_arg_to_python<Ptr>::pointer_deep_arg_to_python(Ptr) [with Ptr = _object*]’
/usr/include/boost/python/converter/arg_to_python.hpp:256:13: required from ‘boost::python::converter::arg_to_python<T>::arg_to_python(const T&) [with T = _object*]’
/usr/include/boost/python/object_core.hpp:292:44: required from ‘static PyObject* boost::python::api::object_initializer_impl<is_proxy, is_object_manager>::get(const T&, mpl_::false_) [with T = _object*; bool is_proxy = false; bool is_object_manager = false; PyObject = _object; mpl_::false_ = mpl_::bool_<false>]’
/usr/include/boost/python/object_core.hpp:235:13: required from ‘PyObject* boost::python::api::object_base_initializer(const T&) [with T = _object*; PyObject = _object]’
/usr/include/boost/python/object_core.hpp:250:46: required from ‘boost::python::api::object::object(const T&) [with T = _object*]’
/usr/include/boost/python/detail/make_tuple.hpp:25:9: required from ‘boost::python::tuple boost::python::make_tuple(const A0&, const A1&) [with A0 = bool; A1 = _object*]’
/home/anand/docker/pybasler/src/pyBasler.cpp:130:63: required from here
/usr/include/boost/python/converter/arg_to_python.hpp:181:72: error: incomplete type ‘boost::python::converter::detail::cannot_convert_raw_PyObject<_object*>’ used in nested name specifier
cannot_convert_raw_PyObject<T*>::to_python_use_handle_instead();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
/usr/include/boost/python/converter/arg_to_python.hpp: In instantiation of ‘static void boost::python::converter::detail::reject_raw_object_helper<T, Convertibility>::error(Convertibility) [with T = _object; Convertibility = int*]’:
/usr/include/boost/python/converter/arg_to_python.hpp:194:56: required from ‘void boost::python::converter::detail::reject_raw_object_ptr(T*) [with T = _object]’
/usr/include/boost/python/converter/arg_to_python.hpp:217:36: required from ‘boost::python::converter::detail::pointer_deep_arg_to_python<Ptr>::pointer_deep_arg_to_python(Ptr) [with Ptr = _object*]’
/usr/include/boost/python/converter/arg_to_python.hpp:256:13: required from ‘boost::python::converter::arg_to_python<T>::arg_to_python(const T&) [with T = _object*]’
/usr/include/boost/python/object_core.hpp:292:44: required from ‘static PyObject* boost::python::api::object_initializer_impl<is_proxy, is_object_manager>::get(const T&, mpl_::false_) [with T = _object*; bool is_proxy = false; bool is_object_manager = false; PyObject = _object; mpl_::false_ = mpl_::bool_<false>]’
/usr/include/boost/python/object_core.hpp:235:13: required from ‘PyObject* boost::python::api::object_base_initializer(const T&) [with T = _object*; PyObject = _object]’
/usr/include/boost/python/object_core.hpp:250:46: required from ‘boost::python::api::object::object(const T&) [with T = _object*]’
/usr/include/boost/python/detail/make_tuple.hpp:25:9: required from ‘boost::python::tuple boost::python::make_tuple(const A0&, const A1&) [with A0 = bool; A1 = _object*]’
/home/anand/docker/pybasler/src/pyBasler.cpp:130:63: required from here
/usr/include/boost/python/converter/arg_to_python.hpp:181:72: error: incomplete type ‘boost::python::converter::detail::cannot_convert_raw_PyObject<_object*>’ used in nested name specifier
CMakeFiles/pbcvt.dir/build.make:62 : la recette pour la cible « CMakeFiles/pbcvt.dir/src/pyBasler.cpp.o » a échouée
make[2]: *** [CMakeFiles/pbcvt.dir/src/pyBasler.cpp.o] Erreur 1
CMakeFiles/Makefile2:67 : la recette pour la cible « CMakeFiles/pbcvt.dir/all » a échouée
make[1]: *** [CMakeFiles/pbcvt.dir/all] Erreur 2
Makefile:129 : la recette pour la cible « all » a échouée
make: *** [all] Erreur 2
我做错了什么?我怎样才能得到想要的结果?
问题的关键指标是编译错误中的这一行:
/usr/include/boost/python/converter/arg_to_python.hpp:181:72: error: incomplete type ‘boost::python::converter::detail::cannot_convert_raw_PyObject<_object*>’ used in nested name specifier
cannot_convert_raw_PyObject<T*>::to_python_use_handle_instead();
这说明您不能直接将 PyObject*
转换为 object
。您需要告诉它如何处理 PyObject*
的所有权。这是通过 boost::python::handle
类型完成的。
因此,更改此行:
return boost::python::make_tuple(true, ret);
至:
boost::python::make_tuple(true, boost::python::handle<>(ret));
将解决错误。