Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

using cimg.i CImgToArr with boost::python segfault #175

Open
moloned opened this issue Sep 29, 2020 · 0 comments
Open

using cimg.i CImgToArr with boost::python segfault #175

moloned opened this issue Sep 29, 2020 · 0 comments

Comments

@moloned
Copy link

moloned commented Sep 29, 2020

The ArrToCImg() function in cimg.i was causing a segfault

The fix is detailed below

`// Convert CImg into numpy array - https://github.com/gipit/gippy/blob/master/gippy/cimg.i
//
template PyObject* CImgToArr(CImg cimg) {
int typenum;
int numdim = 4;
npy_intp dims[] = { cimg.spectrum(), cimg.depth(), cimg.height(), cimg.width() };
if (typeid(T) == typeid(uint8_t)) typenum = NPY_UINT8;
else if (typeid(T) == typeid(int8_t)) typenum = NPY_INT8;
else if (typeid(T) == typeid(uint16_t)) typenum = NPY_UINT16;
else if (typeid(T) == typeid(int16_t)) typenum = NPY_INT16;
else if (typeid(T) == typeid(uint32_t)) typenum = NPY_UINT32;
else if (typeid(T) == typeid(int32_t)) typenum = NPY_INT32;
else if (typeid(T) == typeid(uint64_t)) typenum = NPY_UINT64;
else if (typeid(T) == typeid(int64_t)) typenum = NPY_INT64;
else if (typeid(T) == typeid(float)) typenum = NPY_FLOAT32;
else if (typeid(T) == typeid(double)) typenum = NPY_FLOAT64;
else throw(std::runtime_error("Error converting CImg to numpy array"));

if (cimg.spectrum() == 1) {
numdim = 3;
if (cimg.depth() == 1) {
numdim=2;
if (cimg.height() == 1) {
numdim=1;
}
}
}

// segfault@ was caused by not calling import_array() inside BOOST_PYTHON_MODULE()
// however import_array() didn't compile and required a second fix, a wrapper function
// for import_array() as noted in https://wanzenbug.xyz/boost-numpy/
//
// reinterpret_cast https://forge.epn-campus.eu/svn/magnetix/src/pythonAPI/NumpyConverter.cpp
// PyArray_SimpleNewFromData https://docs.scipy.org/doc/numpy-1.13.0/reference/c-api.array.html
// https://stackoverflow.com/questions/30357115/pyarray-simplenewfromdata-example
//
static PyObject* arr;
arr = PyArray_SimpleNewFromData(numdim, &dims[4-numdim], typenum, reinterpret_cast<void*>(cimg.data()));
return arr;
} // CImgToArr()

// segfault@ in CImgToArr was caused by not calling import_array() inside
// BOOST_PYTHON_MODULE() as noted here
// https://www.reddit.com/r/cpp_questions/comments/54clp9/python_c_extension_segfault_in_pyarray_simplenew/
//
// however import_array() didn't compile and required a second fix, a wrapper function
// for import_array() as noted in https://wanzenbug.xyz/boost-numpy/
//
static void * wrap_import_array() { import_array(); return NULL; }

// wrap python callable functions using boost
//
// http://openalea.gforge.inria.fr/dokuwiki/data/pdfex/PDF_documentation_package_how_to_integrate_cpp_code_in_python.pdf
// https://github.com/TNG/boost-python-examples
//
BOOST_PYTHON_MODULE(py_run_startracker) {

using namespace boost::python;
using namespace cimg_library;
using namespace std;

// make sure to initialise!
Py_Initialize();
bn::initialize();

wrap_import_array(); // wrapper to fix import_array() segfault!

boost::python::def("np_thresholdOtsu" , np_thresholdOtsu);

} // BOOST_PYTHON_MODULE()`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant