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 grep
ed 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 ifpython3
shows up in the "To be build" section of the outputrun
make install