Skip to content

Commit a894815

Browse files
authored
Merge pull request #1798 from ctacke/main
Added support for no-contrib builds and instructions for how to build for linux-arm64 (like Raspberry Pi)
2 parents d8e8e0c + 4c06067 commit a894815

67 files changed

Lines changed: 693 additions & 23 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,9 @@ dotnet add package OpenCvSharp4
229229
# -- edit Program.cs --- #
230230
dotnet run
231231
```
232+
## Customizing OpenCV and OpenCvSharp for embedded (ARM) Platforms
233+
234+
If you want to use OpenCV and OpenCvSharp on an embedded platform like a Raspberry Pi with a 64-bit OS, you have to build both libraries manually, and it's easiest to build it right on your target hardware to avoid cross-compiler toolchain challenges. [The instructions for this build and install are here](embedded-builds.md).
232235

233236
## Donations
234237
If you find the OpenCvSharp library useful and would like to show your gratitude by donating, here are some donation options. Thank you.

embedded-builds.md

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
# Building OpenCV and OpenCvSharpExtern for your Embedded Platform
2+
3+
Using a Raspberry Pi with a 64-bit build of Debian Trixie (Lite is fine)
4+
5+
If you want a build of OpenCV that minimizes the on-disk footprint, you can turn off features (i.e. omit them from the build) for a custom OpenCV build. If you do this, you must also build a custom OpenCvSharpExtern library that matches your configuration.
6+
7+
## Feature Sets
8+
9+
The following table shows the available OpenCV modules and their corresponding OpenCvSharpExtern exclusion flags:
10+
11+
| OpenCV Module | OpenCV CMake Flag | OpenCvSharpExtern Flag | Description |
12+
|---------------|-------------------|------------------------|-------------|
13+
| core | (always included) | (always included) | Core functionality (Mat, basic operations) |
14+
| imgproc | BUILD_opencv_imgproc | (always included) | Image processing (resize, filters, color conversion) |
15+
| imgcodecs | BUILD_opencv_imgcodecs | (always included) | Image file reading/writing |
16+
| videoio | BUILD_opencv_videoio | (always included) | Video capture and writing |
17+
| highgui | BUILD_opencv_highgui | (always included) | GUI windows and trackbars |
18+
| video | BUILD_opencv_video | NO_VIDEO | Video analysis (optical flow, background subtraction) |
19+
| calib3d | BUILD_opencv_calib3d | NO_CALIB3D | Camera calibration, 3D reconstruction |
20+
| features2d | BUILD_opencv_features2d | NO_FEATURES2D | 2D feature detection (ORB, SIFT, etc.) |
21+
| flann | BUILD_opencv_flann | NO_FLANN | Fast approximate nearest neighbor searches |
22+
| dnn | BUILD_opencv_dnn | NO_DNN | Deep neural network inference |
23+
| ml | BUILD_opencv_ml | NO_ML | Machine learning (SVM, decision trees, etc.) |
24+
| objdetect | BUILD_opencv_objdetect | NO_OBJDETECT | Object detection (cascade classifiers, QR codes) |
25+
| photo | BUILD_opencv_photo | NO_PHOTO | Computational photography (inpainting, HDR) |
26+
| stitching | BUILD_opencv_stitching | NO_STITCHING | Image stitching and panorama creation |
27+
| shape | BUILD_opencv_shape | NO_CONTRIB | Shape matching |
28+
| superres | BUILD_opencv_superres | NO_CONTRIB | Super resolution |
29+
| contrib modules | OPENCV_EXTRA_MODULES_PATH | NO_CONTRIB | All opencv_contrib modules (aruco, face, tracking, etc.) |
30+
| barcode | (part of contrib) | NO_BARCODE | Barcode detection |
31+
32+
## Example: USB Camera Frame Capture
33+
34+
Let's say your app needs to connect to a USB camera and simply capture frames from it. You'll need these features:
35+
36+
- **core** - Basic Mat operations
37+
- **imgproc** - Image processing (color conversion, resizing)
38+
- **imgcodecs** - Saving captured frames to disk
39+
- **videoio** - Camera capture via V4L2/FFMPEG
40+
- **highgui** - Optional, for displaying frames in a window
41+
42+
You do NOT need: video, calib3d, features2d, flann, dnn, ml, objdetect, photo, stitching, or any contrib modules.
43+
44+
So you'll need to build a custom set of OpenCV libraries first. Directly on your Raspberry Pi, do the following (Recommend a Pi 5 for compiling speed, but earlier versions work just fine as well).
45+
46+
## Build Scripts
47+
48+
Two build scripts are provided for convenience:
49+
50+
| Script | Description | Output Size |
51+
|--------|-------------|-------------|
52+
| [build-opencvsharp-arm64.sh](tool/build-opencvsharp-arm64.sh) | Full build with all features and contrib modules | ~140MB |
53+
| [build-opencvsharp-minimal-arm64.sh](tool/build-opencvsharp-minimal-arm64.sh) | Minimal build for basic camera capture | ~25MB |
54+
55+
To use either script:
56+
```bash
57+
cd ~
58+
git clone https://github.com/opencv/opencv.git
59+
git clone https://github.com/opencv/opencv_contrib.git # only needed for full build
60+
git clone https://github.com/shimat/opencvsharp.git
61+
62+
cd ~/opencv
63+
git fetch --tags
64+
git checkout 4.10.0
65+
66+
# Only for full build:
67+
cd ~/opencv_contrib
68+
git fetch --tags
69+
git checkout 4.10.0
70+
71+
# Run the desired build script
72+
cd ~
73+
chmod +x ~/opencvsharp/tool/build-opencvsharp-minimal-arm64.sh
74+
~/opencvsharp/tool/build-opencvsharp-minimal-arm64.sh
75+
```
76+
77+
## Building a full OpenCV feature set - large (~140MB) output
78+
79+
First, you can run with a full-featured set of binaries. It's large, and contains probably things you don't need, but it works.
80+
81+
[A script to do the full-up build for linux-arm64 is available here](tool/build-opencvsharp-arm64.sh), but below are the manual instructions.
82+
83+
```bash
84+
cd ~
85+
git clone https://github.com/opencv/opencv.git
86+
git clone https://github.com/opencv/opencv_contrib.git
87+
88+
cd ~/opencv
89+
git fetch --tags
90+
git checkout 4.10.0
91+
cd ~/opencv_contrib
92+
git fetch --tags
93+
git checkout 4.10.0
94+
```
95+
96+
## Building a subset
97+
98+
You can build a subset, but it takes some work. The way Linux libraries link, you have to handle all of the dependencies. You can't simply rebuild OpenCV with fewer features and have it work. OpenCvSharpExtern is linked to the endpoints of all of the features in OpenCV, so if some of them are missing, loading `libOpenCvSharpExtern.so` will fail even if you aren't using the missing features. You must rebuild both, and the original OpenCVSharpExtern is not created to make this friendly.
99+
100+
This repository attempts to address that by providing better support for minimal, configurable builds.
101+
102+
[A script to do a minimal build for linux-arm64 is available here](tool/build-opencvsharp-minimal-arm64.sh), but below are the manual instructions.
103+
104+
### Building OpenCV from Source
105+
106+
First, you have to clone and build OpenCV with your desired features. This is supported and fairly well documented for OpenCV.
107+
108+
Make sure you have all of the dev tools installed:
109+
```bash
110+
sudo apt update
111+
sudo apt install -y \
112+
build-essential \
113+
cmake \
114+
git \
115+
pkg-config \
116+
libgtk-3-dev \
117+
libavcodec-dev \
118+
libavformat-dev \
119+
libswscale-dev \
120+
libv4l-dev
121+
```
122+
123+
Now clone the OpenCV code:
124+
125+
```bash
126+
cd ~
127+
git clone https://github.com/opencv/opencv.git
128+
129+
cd ~/opencv
130+
git fetch --tags
131+
git checkout 4.10.0
132+
```
133+
134+
Now you need to configure the cmake build for your desired feature set:
135+
```bash
136+
cd ~/opencv
137+
mkdir build
138+
cd build
139+
cmake .. \
140+
-DCMAKE_BUILD_TYPE=Release \
141+
-DCMAKE_INSTALL_PREFIX=/opt/opencv-nocontrib \
142+
-DBUILD_SHARED_LIBS=ON \
143+
-DBUILD_TESTS=OFF \
144+
-DBUILD_PERF_TESTS=OFF \
145+
-DBUILD_EXAMPLES=OFF \
146+
-DBUILD_opencv_apps=OFF \
147+
-DBUILD_opencv_dnn=OFF \
148+
-DBUILD_opencv_ml=OFF \
149+
-DBUILD_opencv_objdetect=OFF \
150+
-DBUILD_opencv_photo=OFF \
151+
-DBUILD_opencv_stitching=OFF \
152+
-DBUILD_opencv_video=OFF \
153+
-DBUILD_opencv_calib3d=OFF \
154+
-DBUILD_opencv_features2d=OFF \
155+
-DBUILD_opencv_flann=OFF \
156+
-DBUILD_opencv_shape=OFF \
157+
-DBUILD_opencv_superres=OFF \
158+
-DBUILD_opencv_xphoto=OFF \
159+
-DBUILD_opencv_highgui=ON \
160+
-DBUILD_opencv_imgproc=ON \
161+
-DBUILD_opencv_imgcodecs=ON \
162+
-DBUILD_opencv_videoio=ON \
163+
-DWITH_GSTREAMER=ON \
164+
-DWITH_FFMPEG=ON \
165+
-DWITH_V4L=ON
166+
```
167+
168+
And now build the libraries. This will take a while. Note that the config above puts the output into `/opt/opencv-nocontrib`. You can adjust that as you see fit, but you will need it for the config process for `OpenCvSharpExtern`.
169+
```bash
170+
make -j$(nproc)
171+
sudo make install
172+
```
173+
174+
### Building OpenCvSharpExtern from Source
175+
176+
Here we continue the build process from above. You must have already built OpenCV above and you will need the install path from above if you adjusted it.
177+
178+
First, clone the OpenCvSharp repository that contains the matching build configuration.
179+
180+
```bash
181+
cd ~
182+
git clone https://github.com/shimat/opencvsharp.git
183+
cd opencvsharp/src
184+
```
185+
186+
Now configure this build to match the features you included in OpenCV. This is absolutely a manual process, so the list below only matches the build from above. Refer to the earlier feature table for your specific needs.
187+
188+
```bash
189+
mkdir ~/opencvsharp/src/build
190+
cd ~/opencvsharp/src/build
191+
192+
cmake .. \
193+
-DCMAKE_BUILD_TYPE=Release \
194+
-DOpenCV_DIR=/opt/opencv-nocontrib/lib/cmake/opencv4 \
195+
-DNO_CONTRIB=ON \
196+
-DNO_STITCHING=ON \
197+
-DNO_CALIB3D=ON \
198+
-DNO_VIDEO=ON \
199+
-DNO_FEATURES2D=ON \
200+
-DNO_FLANN=ON \
201+
-DNO_DNN=ON \
202+
-DNO_ML=ON \
203+
-DNO_OBJDETECT=ON \
204+
-DNO_PHOTO=ON \
205+
-DNO_BARCODE=ON
206+
```
207+
208+
And now build the libOpenCvSharpExtern binary:
209+
210+
```bash
211+
make -j$(nproc)
212+
```
213+
214+
### Collecting the Output
215+
216+
After building, you'll find:
217+
- OpenCV libraries in `/opt/opencv-nocontrib/lib/`
218+
- OpenCvSharpExtern in `~/opencvsharp/src/build/OpenCvSharpExtern/libOpenCvSharpExtern.so`
219+
220+
Copy all required `.so` files to your application's runtime directory:
221+
222+
```bash
223+
mkdir -p ~/myapp/runtimes/linux-arm64/native
224+
cp /opt/opencv-nocontrib/lib/libopencv_*.so* ~/myapp/runtimes/linux-arm64/native/
225+
cp ~/opencvsharp/src/build/OpenCvSharpExtern/libOpenCvSharpExtern.so ~/myapp/runtimes/linux-arm64/native/
226+
```
227+
228+
Verify the dependencies are satisfied:
229+
```bash
230+
ldd ~/myapp/runtimes/linux-arm64/native/libOpenCvSharpExtern.so | grep "not found"
231+
```
232+
233+
If no output, all dependencies are satisfied.

src/CMakeLists.txt

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,52 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
99
# remove MinSizeRel & RelWithDebInfo
1010
SET(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "limited configs" FORCE)
1111

12-
add_subdirectory(OpenCvSharpExtern)
12+
# Feature options - must be defined before add_subdirectory
13+
option(NO_CONTRIB "Disable all contrib features" OFF)
14+
option(NO_STITCHING "Disable stitching bindings" OFF)
15+
option(NO_CALIB3D "Disable 3D calibration bindings" OFF)
16+
option(NO_VIDEO "Disable video bindings" OFF)
17+
option(NO_FEATURES2D "Disable 2D feature bindings" OFF)
18+
option(NO_FLANN "Disable FLANN bindings" OFF)
19+
option(NO_DNN "Disable DNN bindings" OFF)
20+
option(NO_ML "Disable ML bindings" OFF)
21+
option(NO_OBJDETECT "Disable object detection bindings" OFF)
22+
option(NO_PHOTO "Disable photo bindings" OFF)
23+
option(NO_BARCODE "Disable barcode bindings" OFF)
24+
25+
# Convert options to compile definitions so C++ preprocessor can see them
26+
if(NO_CONTRIB)
27+
add_compile_definitions(NO_CONTRIB)
28+
endif()
29+
if(NO_STITCHING)
30+
add_compile_definitions(NO_STITCHING)
31+
endif()
32+
if(NO_CALIB3D)
33+
add_compile_definitions(NO_CALIB3D)
34+
endif()
35+
if(NO_VIDEO)
36+
add_compile_definitions(NO_VIDEO)
37+
endif()
38+
if(NO_FEATURES2D)
39+
add_compile_definitions(NO_FEATURES2D)
40+
endif()
41+
if(NO_FLANN)
42+
add_compile_definitions(NO_FLANN)
43+
endif()
44+
if(NO_DNN)
45+
add_compile_definitions(NO_DNN)
46+
endif()
47+
if(NO_ML)
48+
add_compile_definitions(NO_ML)
49+
endif()
50+
if(NO_OBJDETECT)
51+
add_compile_definitions(NO_OBJDETECT)
52+
endif()
53+
if(NO_PHOTO)
54+
add_compile_definitions(NO_PHOTO)
55+
endif()
56+
if(NO_BARCODE)
57+
add_compile_definitions(NO_BARCODE)
58+
endif()
59+
60+
add_subdirectory(OpenCvSharpExtern)

src/OpenCvSharpExtern/aruco.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#pragma once
22

3+
#ifndef NO_CONTRIB
4+
35
#include "include_opencv.h"
46

57
// ReSharper disable IdentifierTypo
@@ -372,3 +374,5 @@ CVAPI(ExceptionStatus) aruco_drawDetectedCornersCharuco(
372374
cv::aruco::drawDetectedCornersCharuco(*image, *corners, *ids, cpp(cornerColor));
373375
END_WRAP
374376
}
377+
378+
#endif // NO_CONTRIB

src/OpenCvSharpExtern/barcode.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#pragma once
22

3+
#ifndef NO_BARCODE
4+
35
#include "include_opencv.h"
46

57
CVAPI(ExceptionStatus) barcode_BarcodeDetector_create(const char *super_resolution_prototxt_path,
@@ -63,3 +65,5 @@ CVAPI(ExceptionStatus) barcode_BarcodeDetector_detectAndDecodeWithType(cv::barco
6365
obj->detectAndDecodeWithType(*inputImage, *detectorInfos, *detectorTypes, *points);
6466
END_WRAP
6567
}
68+
69+
#endif //NO_BARCODE

src/OpenCvSharpExtern/bgsegm.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#pragma once
22

3+
#ifndef NO_CONTRIB
4+
35
// ReSharper disable IdentifierTypo
46
// ReSharper disable CppInconsistentNaming
57
// ReSharper disable CppNonInlineFunctionDefinitionInHeaderFile
@@ -241,3 +243,5 @@ CVAPI(ExceptionStatus) bgsegm_BackgroundSubtractorGMG_setMaxVal(cv::Ptr<cv::bgse
241243
}
242244

243245
#pragma endregion
246+
247+
#endif // NO_CONTRIB

src/OpenCvSharpExtern/calib3d.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#pragma once
22

3+
#ifndef NO_CALIB3D
4+
35
// ReSharper disable IdentifierTypo
46
// ReSharper disable CppInconsistentNaming
57
// ReSharper disable CppNonInlineFunctionDefinitionInHeaderFile
@@ -1233,3 +1235,5 @@ CVAPI(ExceptionStatus) calib3d_findEssentialMat_InputArray2(
12331235
*returnValue = new cv::Mat(mat);
12341236
END_WRAP
12351237
}
1238+
1239+
#endif // NO_CALIB3D

src/OpenCvSharpExtern/calib3d_StereoMatcher.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#pragma once
22

3+
#ifndef NO_CALIB3D
4+
35
// ReSharper disable IdentifierTypo
46
// ReSharper disable CppInconsistentNaming
57
// ReSharper disable CppNonInlineFunctionDefinitionInHeaderFile
@@ -356,4 +358,6 @@ CVAPI(ExceptionStatus) calib3d_StereoSGBM_setMode(cv::Ptr<cv::StereoSGBM> *obj,
356358
END_WRAP
357359
}
358360

359-
#pragma endregion
361+
#pragma endregion
362+
363+
#endif // NO_CALIB3D

src/OpenCvSharpExtern/calib3d_fisheye.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#pragma once
22

3+
#ifndef NO_CALIB3D
4+
35
// ReSharper disable IdentifierTypo
46
// ReSharper disable CppInconsistentNaming
57
// ReSharper disable CppNonInlineFunctionDefinitionInHeaderFile
@@ -120,3 +122,5 @@ CVAPI(ExceptionStatus) calib3d_fisheye_stereoCalibrate(
120122
cpp(imageSize), entity(R), entity(T), flags, cpp(criteria));
121123
END_WRAP
122124
}
125+
126+
#endif // NO_CALIB3D

src/OpenCvSharpExtern/dnn.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#pragma once
22

3+
#ifndef NO_DNN
4+
35
#ifndef _WINRT_DLL
46

57
// ReSharper disable IdentifierTypo
@@ -199,3 +201,5 @@ CVAPI(ExceptionStatus) dnn_resetMyriadDevice()
199201
}
200202

201203
#endif // !#ifndef _WINRT_DLL
204+
205+
#endif // NO_DNN

0 commit comments

Comments
 (0)