|
| 1 | +# OpenCV C++, OpenCV-Python, and OpenCvSharp |
| 2 | + |
| 3 | +OpenCvSharp exposes OpenCV to .NET applications. Its API is intentionally designed to stay as close as practical to the native OpenCV C++ API so that OpenCV concepts, documentation, and code transfer naturally to .NET. Most computer vision concepts, algorithm behavior, and parameter constraints come directly from OpenCV, while the managed surface also follows C# conventions and cannot be translated mechanically from every C++ or Python example. |
| 4 | + |
| 5 | +Use the official OpenCV documentation for algorithm theory and native parameter requirements. Use the OpenCvSharp guides and API reference for .NET package selection, managed types, overloads, resource ownership, and application integration. |
| 6 | + |
| 7 | +## How the three APIs relate |
| 8 | + |
| 9 | +OpenCV is implemented primarily in C++. Its C++ API is therefore the closest description of the native functions that OpenCvSharp eventually calls. |
| 10 | + |
| 11 | +OpenCV-Python is an official generated binding over the same native implementation. Images are normally presented as NumPy arrays, and the binding adapts many C++ output parameters into Python return values. |
| 12 | + |
| 13 | +OpenCvSharp is a .NET wrapper with a managed API and a native bridge. It preserves many OpenCV names and concepts while representing them with .NET classes, enums, arrays, spans, exceptions, and `IDisposable`. |
| 14 | + |
| 15 | +| Concept | OpenCV C++ | OpenCV-Python | OpenCvSharp | |
| 16 | +|---|---|---|---| |
| 17 | +| Free function | `cv::GaussianBlur` | `cv.GaussianBlur` | `Cv2.GaussianBlur` | |
| 18 | +| Submodule function | `cv::dnn::readNetFromONNX` | `cv.dnn.readNetFromONNX` | `Cv2.Dnn.ReadNetFromONNX` | |
| 19 | +| Image container | `cv::Mat` | `numpy.ndarray` or `cv.Mat` | `Mat` | |
| 20 | +| Image size | `cv::Size` | `(width, height)` tuple | `Size` | |
| 21 | +| Coordinate | `cv::Point` | `(x, y)` tuple | `Point` | |
| 22 | +| Color conversion enum and value | `cv::ColorConversionCodes` and `cv::COLOR_BGR2GRAY` | `cv.COLOR_BGR2GRAY` | `ColorConversionCodes.BGR2GRAY` | |
| 23 | +| Output image | `OutputArray dst` argument | Usually a return value | Usually a caller-owned `Mat` argument | |
| 24 | +| Native failure | `cv::Exception` | `cv2.error` | `OpenCVException` | |
| 25 | +| Lifetime | RAII and reference counting | Python and NumPy ownership | `IDisposable` and `using` | |
| 26 | + |
| 27 | +The correspondence is deliberately recognizable, but it is not a promise that every native overload has an identical managed overload. |
| 28 | + |
| 29 | +## The same operation in three languages |
| 30 | + |
| 31 | +The following examples all load a color image, validate it, and convert it to grayscale. |
| 32 | + |
| 33 | +### C++ |
| 34 | + |
| 35 | +```cpp |
| 36 | +cv::Mat source = cv::imread("input.jpg", cv::IMREAD_COLOR); |
| 37 | +if (source.empty()) |
| 38 | +{ |
| 39 | + throw std::runtime_error("Could not read input.jpg."); |
| 40 | +} |
| 41 | + |
| 42 | +cv::Mat grayscale; |
| 43 | +cv::cvtColor(source, grayscale, cv::COLOR_BGR2GRAY); |
| 44 | +``` |
| 45 | +
|
| 46 | +### Python |
| 47 | +
|
| 48 | +```python |
| 49 | +import cv2 as cv |
| 50 | +
|
| 51 | +source = cv.imread("input.jpg", cv.IMREAD_COLOR) |
| 52 | +if source is None: |
| 53 | + raise RuntimeError("Could not read input.jpg.") |
| 54 | +
|
| 55 | +grayscale = cv.cvtColor(source, cv.COLOR_BGR2GRAY) |
| 56 | +``` |
| 57 | + |
| 58 | +### OpenCvSharp |
| 59 | + |
| 60 | +```csharp |
| 61 | +using var source = Cv2.ImRead("input.jpg", ImreadModes.Color); |
| 62 | +if (source.Empty()) |
| 63 | +{ |
| 64 | + throw new InvalidOperationException("Could not read input.jpg."); |
| 65 | +} |
| 66 | + |
| 67 | +using var grayscale = new Mat(); |
| 68 | +Cv2.CvtColor(source, grayscale, ColorConversionCodes.BGR2GRAY); |
| 69 | +``` |
| 70 | + |
| 71 | +The OpenCvSharp example resembles the C++ API because `grayscale` is an explicit destination. It also adds deterministic disposal because both managed objects own native resources. |
| 72 | + |
| 73 | +## Translating names from C++ |
| 74 | + |
| 75 | +Most free functions in the `cv` namespace are static methods on `Cv2`, with .NET-style capitalization: |
| 76 | + |
| 77 | +| C++ | OpenCvSharp | |
| 78 | +|---|---| |
| 79 | +| `cv::imread` | `Cv2.ImRead` | |
| 80 | +| `cv::cvtColor` | `Cv2.CvtColor` | |
| 81 | +| `cv::findContours` | `Cv2.FindContours` | |
| 82 | +| `cv::warpPerspective` | `Cv2.WarpPerspective` | |
| 83 | + |
| 84 | +Functions in an OpenCV submodule normally use a nested `Cv2` class. For example, `cv::dnn` maps to `Cv2.Dnn`, while wrapper object types remain in namespaces such as `OpenCvSharp.Dnn`. |
| 85 | + |
| 86 | +OpenCvSharp enum types generally mirror named enums declared by the native C++ API. For example, OpenCV declares the unscoped enum `cv::ColorConversionCodes`; because its enumerators are injected into the enclosing `cv` namespace, C++ code normally writes `cv::COLOR_BGR2GRAY` without mentioning the enum type. OpenCvSharp exposes the same grouping through the scoped C# expression `ColorConversionCodes.BGR2GRAY`. |
| 87 | + |
| 88 | +Apply the same rule when translating names such as `cv::INTER_AREA` or `cv::THRESH_OTSU`: identify the native enum declaration or inspect the parameter type, then use the corresponding OpenCvSharp enum member. |
| 89 | + |
| 90 | +## Translating Python examples |
| 91 | + |
| 92 | +Python tutorials are valuable explanations of OpenCV algorithms, but NumPy operations need special attention. |
| 93 | + |
| 94 | +### NumPy arrays are not OpenCvSharp Mat objects |
| 95 | + |
| 96 | +A Python image commonly exposes shape, data type, channels, slicing, broadcasting, and arithmetic through NumPy. OpenCvSharp keeps the native `cv::Mat` model instead: |
| 97 | + |
| 98 | +| Python and NumPy | OpenCvSharp | |
| 99 | +|---|---| |
| 100 | +| `image.shape` | `image.Rows`, `image.Cols`, and `image.Channels()` | |
| 101 | +| `image.dtype` | `image.Depth()` or `image.Type()` | |
| 102 | +| `image[y, x]` | `image.At<T>(y, x)` or span-based access | |
| 103 | +| `image[y1:y2, x1:x2]` | A `Mat` region of interest | |
| 104 | +| NumPy vectorized expression | A corresponding `Cv2` operation, matrix expression, or span loop | |
| 105 | + |
| 106 | +Do not translate a NumPy loop or slice one token at a time. First identify whether the operation is a native OpenCV function. Native operations usually express intent more clearly and avoid repeated managed-to-native calls. |
| 107 | + |
| 108 | +See [Mat Basics](../guides/mat-basics.md) and [Pixel Access](../guides/pixel-access.md) for the OpenCvSharp data model. |
| 109 | + |
| 110 | +### Python often returns C++ output arguments |
| 111 | + |
| 112 | +The generated Python binding turns many C++ `OutputArray` arguments into return values. For example, Python thresholding returns both the selected threshold and the output image: |
| 113 | + |
| 114 | +```python |
| 115 | +selected_threshold, binary = cv.threshold( |
| 116 | + grayscale, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU) |
| 117 | +``` |
| 118 | + |
| 119 | +OpenCvSharp keeps the destination as an argument and returns the scalar result: |
| 120 | + |
| 121 | +```csharp |
| 122 | +using var binary = new Mat(); |
| 123 | +double selectedThreshold = Cv2.Threshold( |
| 124 | + grayscale, binary, 0, 255, ThresholdTypes.Binary | ThresholdTypes.Otsu); |
| 125 | +``` |
| 126 | + |
| 127 | +Functions with several Python return values may instead use `out` parameters, arrays, tuples, or result objects in OpenCvSharp. Check the managed signature rather than assuming the Python return shape. |
| 128 | + |
| 129 | +## Resource ownership is a .NET concern |
| 130 | + |
| 131 | +OpenCvSharp objects that own native resources must be disposed. This includes `Mat`, `VideoCapture`, `VideoWriter`, `Net`, feature detectors, and many other wrappers. |
| 132 | + |
| 133 | +Use `using` declarations for local ownership and document ownership when returning an OpenCvSharp object from a method. Garbage collection does not provide timely accounting for native image buffers. |
| 134 | + |
| 135 | +Read [Resource Management](../guides/resource-management.md) before translating a long-running Python application or a C++ pipeline that relies on scope-based RAII. |
| 136 | + |
| 137 | +## Find the corresponding OpenCvSharp API |
| 138 | + |
| 139 | +When starting from an OpenCV C++ or Python page: |
| 140 | + |
| 141 | +1. Identify the C++ function and its module in the official OpenCV reference. |
| 142 | +2. Map `cv::functionName` to `Cv2.FunctionName`, or `cv::module::functionName` to `Cv2.Module.FunctionName`. |
| 143 | +3. Replace global constants with the enum type accepted by the OpenCvSharp parameter. |
| 144 | +4. Search the [OpenCvSharp API reference](../../api/index.md) for the managed overload. |
| 145 | +5. Check whether returned images or algorithm objects need disposal. |
| 146 | +6. Confirm that the OpenCvSharp and OpenCV versions provide the same module and behavior. |
| 147 | + |
| 148 | +If a direct mapping is missing, search the [issue tracker](https://github.com/shimat/opencvsharp/issues) before assuming that the native feature is unavailable. |
| 149 | + |
| 150 | +## Version and package differences |
| 151 | + |
| 152 | +This documentation describes OpenCvSharp5 and OpenCV 5.x. OpenCvSharp4 wraps the OpenCV 4.x line and targets older .NET applications. Some module names, APIs, data types, and package requirements differ between the two major versions. |
| 153 | + |
| 154 | +See [Choose a Version and Package](package-selection.md) before combining code or documentation from different OpenCV generations. |
| 155 | + |
| 156 | +## Official OpenCV references |
| 157 | + |
| 158 | +- [OpenCV 5 documentation](https://docs.opencv.org/5.0/index.html) |
| 159 | +- [OpenCV 5 tutorials](https://docs.opencv.org/5.0/tutorials/tutorials.html) |
| 160 | +- [OpenCV-Python tutorials](https://docs.opencv.org/5.0/py_tutorials/py_tutorials.html) |
| 161 | +- [How OpenCV-Python bindings work](https://docs.opencv.org/5.0/py_tutorials/py_bindings/py_bindings_basics/py_bindings_basics.html) |
0 commit comments