Skip to content
New issue

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

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

Already on GitHub? # 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()`

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

No branches or pull requests

1 participant