Home > Mobile >  How to build cv2 binding
How to build cv2 binding

Time:06-02

I have followed the opencv doc for creating my own bindings.

I run the file gen2.py which generated some header files:

./
../
pyopencv_generated_enums.h
pyopencv_generated_funcs.h
pyopencv_generated_include.h
pyopencv_generated_modules_content.h
pyopencv_generated_modules.h
pyopencv_generated_types_content.h
pyopencv_generated_types.h
pyopencv_signatures.json

How should I build this? I tried running cmake CMakeLists.txt directly in /opencv/modules/python but some defines were not found.

and I tried on re-building running cmake CMakeLists.txt in /opencv/ , where I got:

  FATAL: In-source builds are not allowed.

         You should create a separate directory for build files.

I think both approaches were quite wrong, but I haven't found any doc explaining how to build using the generated headers.

I'm using opencv 4.5.5 which I cloned and built.

EDIT

I found this in /source/opencv/modules/python/bindings/CMakeLists.txt:

string(REPLACE ";" "\n" opencv_hdrs_ "${opencv_hdrs}")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/headers.txt" "${opencv_hdrs_}")
add_custom_command(
    OUTPUT ${cv2_generated_files}
    COMMAND "${PYTHON_DEFAULT_EXECUTABLE}" "${PYTHON_SOURCE_DIR}/src2/gen2.py" "${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/headers.txt"
    DEPENDS "${PYTHON_SOURCE_DIR}/src2/gen2.py"
            "${PYTHON_SOURCE_DIR}/src2/hdr_parser.py"
            # not a real build dependency (file(WRITE) result): ${CMAKE_CURRENT_BINARY_DIR}/headers.txt
            ${opencv_hdrs}
    COMMENT "Generate files for Python bindings and documentation"
)

I guess I have to add the path to my headers in ${CMAKE_CURRENT_BINARY_DIR}/headers.txt just not sure how to get the value of CMAKE_CURRENT_BINARY_DIR

EDIT 2

As proposed by @berak, I tried CMAKE_EXTRA_MODULES_PATH=my/path this seems to get me really close to what I need.

It compiles my sources and generates the .so files as libopencv_xxx.so and saves them in my /usr/local/lib

(when running nm on it I see my class and method)

BUT! when I import cv2 in a script I don't achieve to load my module. I tried print(cv2.__dict__) and greped on it, but it's not there.

Any clue on how to add the compiled modules into my python-opencv installation?

CodePudding user response:

There's not much documentation on how to create a bind (at least I only found this, which is very helpful but doesn't have all the information).

First, your module must use the following tree structure (I did everything with cmake):

.
src
└── modules
    └── your_module
        ├── CMakeLists.txt
        ├── include
        │   └── opencv2
        │       └── your_module_bind_lib.hpp
        └── src
            └── your_module_bind_lib.cpp

An example of my CMakeLists.txt (this of course may change according to your project):

set(the_description "yourModule LIB")
ocv_define_module(your_module opencv_imgproc WRAP python)
include_directories(${OpenCV_INCLUDE_DIRS})

Then I cloned OpenCV with

git clone https://github.com/opencv/opencv.git

Make a build folder

mkdir wherever/build

And run the following command for cmake

cd wherever/build
cmake -DOPENCV_EXTRA_MODULES_PATH=/project_from_previous_tree/src/modules/ -D BUILD_EXAMPLES=OFF -D BUILD_opencv_apps=OFF -D BUILD_DOCS=OFF -D BUILD_PERF_TESTS=OFF -D BUILD_TESTS=OFF -D CMAKE_INSTALL_PREFIX=/usr/local/  your_opencv_location/opencv/
make -j8
make install

In that command the only "special" thing was DOPENCV_EXTRA_MODULES_PATH (thanks to @berak for the idea).

And then? what happens in python level?

Make sure your python installation actually points to the built opencv, or use something like:

import sys
sys.path.append('/usr/local/lib/python3.8/site-packages/cv2/python-3.8')
import cv2

where /usr/local/lib/python3.8/site-packages/cv2/python-3.8' is where the generated .so is located in my PC.

With this you will be able to use things like

cv2.my_cpp_function()
cv2.my_cpp_class.some_method()
...

Where my_cpp stuff was declared and defined in the module project following the doc and can "easily" have OpenCV typed objects as parameters.

Et voila, now you can use your c functions in python.

Notice that this solution does not do any modification to the opencv directory cloned from Git.

CodePudding user response:

You're not supposed to run gen2.py manually, cmake will do this for you at some stage, internally.

since you seem to be on some linux, rather follow the build steps here, this will also generate python bindings, the gist of it is:

  • make a special "build folder" and cd into it (dont try to build in the src folder, you'll never be able to clean anything up)

  • run cmake <some args> path_to_src_folder (or better even - cmake-gui) , check if python3 shows up in the "To be build" section of the output

  • run make install

  • Related