Open shixudongleo opened 9 years ago
I think your example is missing a call to fs::python::init_and_export_converters();
after BOOST_PYTHON_MODULE(cv_module)
Thanks for comment/resolution @rodrigob.
@shixudongleo, As soon as you call from cv_module import process_mat
, you should see a PYTHON TYPE CONVERTERS exported
printed in the console implying that the np.ndarry<=>cv::Mat converters are registered within the Python runtime. This is done within fs::python::init_and_export_converters();
and it should be called as @rodrigob mentioned
BOOST_PYTHON_MODULE(cv_module)
{
fs::python::init_and_export_converters();
boost::python::def("process_mat", &process_mat);
}
ok, so now I got to try it, and it did not work either :(.
I do use
BOOST_PYTHON_MODULE(my_module)
{
fs::python::init_and_export_converters();
// here the defs
then I call
python my_test.py
PYTHON TYPE CONVERTERS exported
Traceback (most recent call last):
File "my_test.py", line 268, in <module>
main()
Boost.Python.ArgumentError: Python argument types in
my_method(numpy.ndarray, str, int, int, int, int, numpy.ndarray)
did not match C++ signature:
my_method(cv::Mat_<cv::Vec<unsigned char, 3> > image, std::string image_name, int x_min, int y_min, int x_max, int y_max, cv::Mat_<unsigned char> {lvalue} mask)
any idea of what is going on ?
Can you send me the C function you're trying to call and the corresponding my_test.py? It should be an easy fix I think. If my_method is accepting cv::Mat3b and cv::Mat1b then your numpy array need to be called with the appropriate dtypes (np.uint8), and shapes as well. Its much easier to write the API accepting cv::Mat and have the registry handle the conversions for you.
I am not sure what you are asking for (that you cannot already see in the previous message), the C++ prototype is
void my_method(const cv::Mat3b &image, const std::string &image_name,
const int x_min, const int y_min, const int x_max, const int y_max, cv::Mat1b &mask);
and the python call is
my_module.my_method(
image, "a_string",
x_min, y_min, x_max, y_max,
mask
)
where image
and mask
are numpy arrays of shape (321, 481, 3) and (321, 481) respectively both of dtype uint8.
If I change the prototype of the C++ function to use p::object &
instead of cv::Mat
and then use p::extract<cv::Mat>(...)
then things seem to work. But that does not match the examples of the documentation.
You're passing a cv::Mat1b
reference (cv::Mat1b&
) instead of a const reference (const cv::Mat1b&
).
Try this:
void my_method(const cv::Mat3b &image, const std::string &image_name, const int x_min, const int y_min, const int x_max, const int y_max, const cv::Mat1b &mask)
Unfortunately, I haven't spent too much time on the memory management (since both numpy and opencv have their own memory management policies), and the managing who handles the memory between Python and C can be a little tricky.
Also, if you're dealing with 3-channel images, you'll probably need to set the preprocessor to 1. (see here)
I just realized that this repo needs a little bit of work to get a first example up and running. I'll try to add more test examples in the near future.
ArgumentError: Python argument types in cv_module.process_mat(numpy.ndarray) did not match C++ signature: process_mat(cv::Mat)
call from python: import numpy as np from cv_module import process_mat A = np.random.random(shape=(4,3)) B = process_mat(A)
cv_module.cpp // Wrapper for most external modules
include <boost/python.hpp>
include <boost/python/suite/indexing/vector_indexing_suite.hpp>
include
// Opencv includes
include <opencv2/opencv.hpp>
// np_opencv_converter
include "np_opencv_converter.hpp"
cv::Mat process_mat(const cv::Mat& in) { // process matrix, or just plain-simple cloning! cv::Mat out = in.clone(); return out; }
BOOST_PYTHON_MODULE(cv_module) { boost::python::def("process_mat", &process_mat); }
CMakefile.txt project (my-numpy-opencv-converter) cmake_minimum_required (VERSION 2.6.0)
Include package config, boost-python
find_package(PkgConfig REQUIRED) include(cmake/boost-python.cmake)
configure opencv
pkg_check_modules(OpenCV opencv) include_directories(${OpenCV_INCLUDE_DIRS})
Include python (use -D flags instead)
if (NOT PYTHON_INCLUDE_DIRS OR NOT PYTHON_LIBRARY) SET(PYTHON_INCLUDE_DIRS "/usr/include/python2.7") SET(PYTHON_LIBRARY "/usr/lib/python2.7/config-x86_64-linux-gnu/libpython2.7.so") endif()
Build np<=>opencv converter library
boost_python_module(np_opencv_converter np_opencv_converter.cpp utils/conversion.cpp) target_link_libraries(np_opencv_converter boost_system boost_python ${OpenCV_LDFLAGS})
Build test library
include_directories(${CMAKE_CURRENT_SOURCE_DIR}) boost_python_module(cv_module tests/cv_module.cpp) target_link_libraries(cv_module boost_system boost_python np_opencv_converter ${OpenCV_LDFLAGS})