├── docs └── README.md ├── data ├── 3x5.jpg ├── road.mp4 ├── light.jpg ├── solar.jpg ├── invoice.jpg ├── SmoothImage.jpg ├── mnist_image_5.npy ├── UncorrectedImage.png └── mnist_image_5.txt ├── src ├── SharpCV │ ├── Binding.cs │ ├── APIs │ │ ├── cv2.dnn.cs │ │ ├── cv2.videoio.cs │ │ ├── cv2.highgui.cs │ │ ├── cv2.photo.cs │ │ ├── cv2.core.cs │ │ ├── cv2.imgcodecs.cs │ │ └── cv2.imgproc.cs │ ├── NativeAPIs │ │ ├── cv2_native_api.cs │ │ ├── enum │ │ │ ├── cv2_native_api.FLIP_MODE.cs │ │ │ ├── cv2_native_api.HersheyFonts.cs │ │ │ ├── cv2_native_api.LineTypes.cs │ │ │ ├── cv2_native_api.RotateFlags.cs │ │ │ ├── cv2_native_api.MorphShapes.cs │ │ │ ├── cv2_native_api.AdaptiveThresholdTypes.cs │ │ │ ├── cv2_native_api.BorderTypes.cs │ │ │ ├── cv2_native_api.WindowFlags.cs │ │ │ ├── cv2_native_api.ContourApproximationModes.cs │ │ │ ├── cv2_native_api.RetrievalModes.cs │ │ │ ├── cv2_native_api.ThresholdTypes.cs │ │ │ ├── cv2_native_api.InterpolationFlags.cs │ │ │ ├── cv2_native_api.MorphTypes.cs │ │ │ ├── cv2_native_api.IMREAD_COLOR.cs │ │ │ ├── cv2_native_api.VideoCaptureAPIs.cs │ │ │ ├── cv2_native_api.VideoCaptureProperties.cs │ │ │ └── cv2_native_api.ColorConversionCodes.cs │ │ ├── cv2_native_api.photo.cs │ │ ├── cv2_native_api.videoio.cs │ │ ├── cv2_native_api.highgui.cs │ │ ├── cv2_native_api.imgcodecs.cs │ │ ├── cv2_native_api.dnn.cs │ │ ├── cv2_native_api.stdvector.cs │ │ ├── cv2_native_api.core.cs │ │ └── cv2_native_api.imgproc.cs │ ├── Vectors │ │ ├── IStdVector.cs │ │ ├── VectorOfMat.cs │ │ ├── VectorOfVectorPoint.cs │ │ └── VectorOfByte.cs │ ├── Modules │ │ ├── Video │ │ │ └── VideoCapture.cs │ │ ├── ImgProc │ │ │ ├── Moments.Struct.cs │ │ │ └── Moments.cs │ │ └── Dnn │ │ │ ├── Net.cs │ │ │ └── Dnn.cs │ ├── Core │ │ ├── Mat.Implicit.cs │ │ ├── MatType.cs │ │ ├── Mat.Index.cs │ │ ├── Mat.Creation.cs │ │ └── Mat.cs │ ├── Structs │ │ ├── Size.cs │ │ ├── Scalar.cs │ │ ├── Rect.cs │ │ ├── RotatedRect.cs │ │ ├── Point.cs │ │ ├── Point2f.cs │ │ └── Size2f.cs │ ├── DisposableObject.cs │ ├── Util │ │ └── ArrayAddress2.cs │ └── SharpCV.csproj └── SharpCV.Examples │ ├── SharpCV.Examples.csproj │ └── Program.cs ├── test └── UnitTest │ ├── UnitTest.csproj │ ├── ImgHighGuiTest.cs │ ├── Test.cs │ ├── OCRImageEnhance.cs │ ├── ImgCodecsTest.cs │ ├── VideoTest.cs │ ├── CreationTest.cs │ ├── CorrectImageTest.cs │ ├── CoreTest.cs │ ├── ImgProcTest.cs │ └── data │ └── mnist_first_image_data.txt ├── README.md ├── SharpCV.sln ├── .gitignore └── LICENSE /docs/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /data/3x5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SciSharp/SharpCV/HEAD/data/3x5.jpg -------------------------------------------------------------------------------- /data/road.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SciSharp/SharpCV/HEAD/data/road.mp4 -------------------------------------------------------------------------------- /data/light.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SciSharp/SharpCV/HEAD/data/light.jpg -------------------------------------------------------------------------------- /data/solar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SciSharp/SharpCV/HEAD/data/solar.jpg -------------------------------------------------------------------------------- /data/invoice.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SciSharp/SharpCV/HEAD/data/invoice.jpg -------------------------------------------------------------------------------- /data/SmoothImage.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SciSharp/SharpCV/HEAD/data/SmoothImage.jpg -------------------------------------------------------------------------------- /data/mnist_image_5.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SciSharp/SharpCV/HEAD/data/mnist_image_5.npy -------------------------------------------------------------------------------- /data/UncorrectedImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SciSharp/SharpCV/HEAD/data/UncorrectedImage.png -------------------------------------------------------------------------------- /src/SharpCV/Binding.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace SharpCV 6 | { 7 | public static partial class Binding 8 | { 9 | public static cv_api cv2 { get; } = new cv_api(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/SharpCV/APIs/cv2.dnn.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | using System.Text; 5 | 6 | namespace SharpCV 7 | { 8 | public partial class cv_api 9 | { 10 | public Dnn dnn { get; } = new Dnn(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/SharpCV/NativeAPIs/cv2_native_api.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | using System.Text; 5 | 6 | namespace SharpCV 7 | { 8 | internal partial class cv2_native_api 9 | { 10 | internal const string OpenCvDllName = "OpenCvSharpExtern"; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/SharpCV/NativeAPIs/enum/cv2_native_api.FLIP_MODE.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | using System.Text; 5 | 6 | namespace SharpCV 7 | { 8 | /// 9 | /// 3rdparty\carotene\include\carotene\types.hpp 10 | /// 11 | public enum FLIP_MODE 12 | { 13 | FLIP_HORIZONTAL_MODE = 1, 14 | FLIP_VERTICAL_MODE = 2, 15 | FLIP_BOTH_MODE = FLIP_HORIZONTAL_MODE | FLIP_VERTICAL_MODE 16 | }; 17 | } 18 | -------------------------------------------------------------------------------- /src/SharpCV/NativeAPIs/enum/cv2_native_api.HersheyFonts.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace SharpCV 6 | { 7 | public enum HersheyFonts 8 | { 9 | HERSHEY_SIMPLEX = 0, 10 | HERSHEY_PLAIN = 1, 11 | HERSHEY_DUPLEX = 2, 12 | HERSHEY_COMPLEX = 3, 13 | HERSHEY_TRIPLEX = 4, 14 | HERSHEY_COMPLEXSMALL = 5, 15 | HERSHEY_SCRIPTSIMPLEX = 6, 16 | HERSHEY_SCRIPTCOMPLEX = 7, 17 | ITALIC = 16 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/SharpCV/NativeAPIs/enum/cv2_native_api.LineTypes.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | using System.Text; 5 | 6 | namespace SharpCV 7 | { 8 | /// 9 | /// modules\imgproc\include\opencv2\imgproc.hpp 10 | /// 11 | public enum LineTypes 12 | { 13 | FILLED = -1, 14 | LINE_4 = 4, //!< 4-connected line 15 | LINE_8 = 8, //!< 8-connected line 16 | LINE_AA = 16 //!< antialiased line 17 | }; 18 | } 19 | -------------------------------------------------------------------------------- /src/SharpCV/NativeAPIs/enum/cv2_native_api.RotateFlags.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | using System.Text; 5 | 6 | namespace SharpCV 7 | { 8 | /// 9 | /// modules\core\include\opencv2\core.hpp 10 | /// 11 | public enum RotateFlags 12 | { 13 | ROTATE_90_CLOCKWISE = 0, //! 6 | /// Represents std::vector 7 | /// 8 | public interface IStdVector : IDisposable 9 | { 10 | /// 11 | /// vector.size() 12 | /// 13 | int Size { get; } 14 | 15 | /// 16 | /// Convert std::vector<T> to managed array T[] 17 | /// 18 | /// 19 | T[] ToArray(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/SharpCV/Modules/Video/VideoCapture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace SharpCV 6 | { 7 | public class VideoCapture : DisposableObject 8 | { 9 | public VideoCapture(IntPtr handle) 10 | { 11 | _handle = handle; 12 | } 13 | 14 | public (bool, Mat) read() 15 | { 16 | var dst = new Mat(); 17 | cv2_native_api.videoio_VideoCapture_read_Mat(_handle, dst, out var output); 18 | return (output != 0, dst); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/SharpCV.Examples/SharpCV.Examples.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | AnyCPU;x64 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/SharpCV/Core/Mat.Implicit.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using Tensorflow.NumPy; 5 | 6 | namespace SharpCV 7 | { 8 | public partial class Mat 9 | { 10 | public static implicit operator IntPtr(Mat mat) 11 | => mat._handle; 12 | 13 | public static implicit operator Mat(IntPtr handle) 14 | => new Mat(handle); 15 | 16 | public static implicit operator NDArray(Mat mat) 17 | => mat.data; 18 | 19 | public static implicit operator Mat(NDArray nd) 20 | => new Mat(nd); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/SharpCV/Structs/Size.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace SharpCV 6 | { 7 | public struct Size 8 | { 9 | public int Width { get; } 10 | public int Height { get; } 11 | 12 | public Size(int width, int height) 13 | { 14 | Width = width; 15 | Height = height; 16 | } 17 | 18 | public static implicit operator Size((int, int) vals) 19 | => new Size(vals.Item1, vals.Item2); 20 | 21 | public override string ToString() 22 | { 23 | return $"{Width}x{Height}"; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/SharpCV/Modules/ImgProc/Moments.Struct.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | using System.Text; 5 | 6 | namespace SharpCV 7 | { 8 | public partial class Moments 9 | { 10 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 11 | public struct NativeStruct 12 | { 13 | public double m00, m10, m01, m20, m11, m02, m30, m21, m12, m03; /* spatial moments */ 14 | public double mu20, mu11, mu02, mu30, mu21, mu12, mu03; /* central moments */ 15 | public double inv_sqrt_m00; /* m00 != 0 ? 1/sqrt(m00) : 0 */ 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/SharpCV/Structs/Scalar.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace SharpCV 6 | { 7 | public struct Scalar 8 | { 9 | public double Val0 { get; } 10 | 11 | public double Val1 { get; } 12 | 13 | public double Val2 { get; } 14 | 15 | public double Val3 { get; } 16 | 17 | public Scalar(double v0, double v1, double v2) 18 | { 19 | Val0 = v0; 20 | Val1 = v1; 21 | Val2 = v2; 22 | Val3 = 0; 23 | } 24 | 25 | public static implicit operator Scalar((double, double, double) vals) 26 | => new Scalar(vals.Item1, vals.Item2, vals.Item3); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/SharpCV/NativeAPIs/cv2_native_api.photo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | using System.Text; 5 | 6 | namespace SharpCV 7 | { 8 | internal partial class cv2_native_api 9 | { 10 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 11 | internal static extern void photo_fastNlMeansDenoising(IntPtr src, IntPtr dst, float h, 12 | int templateWindowSize, int searchWindowSize); 13 | 14 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 15 | internal static extern void photo_fastNlMeansDenoisingColored(IntPtr src, IntPtr dst, 16 | float h, float hColor, int templateWindowSize, int searchWindowSize); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/SharpCV/Structs/Rect.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace SharpCV 6 | { 7 | public struct Rect 8 | { 9 | public int X { get; } 10 | public int Y { get; } 11 | 12 | public int Width { get; } 13 | public int Height { get; } 14 | 15 | public Rect(int x, int y, int width, int height) 16 | => (X, Y, Width, Height) = (x, y, width, height); 17 | 18 | public static implicit operator Rect((int, int, int, int) vals) 19 | => new Rect(vals.Item1, vals.Item2, vals.Item3, vals.Item4); 20 | 21 | public void Deconstruct(out int x, out int y, out int width, out int height) 22 | => (x, y, width, height) = (X, Y, Width, Height); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/SharpCV/APIs/cv2.videoio.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | using System.Text; 5 | 6 | namespace SharpCV 7 | { 8 | public partial class cv_api 9 | { 10 | public VideoCapture VideoCapture(int device, VideoCaptureAPIs api = VideoCaptureAPIs.CAP_ANY) 11 | { 12 | cv2_native_api.videoio_VideoCapture_new3(device, (int)api, out var handle); 13 | return new VideoCapture(handle); 14 | } 15 | 16 | public VideoCapture VideoCapture(string fileName, VideoCaptureAPIs api = VideoCaptureAPIs.CAP_ANY) 17 | { 18 | cv2_native_api.videoio_VideoCapture_new2(fileName, (int)api, out var handle); 19 | return new VideoCapture(handle); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/SharpCV/NativeAPIs/enum/cv2_native_api.MorphShapes.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | using System.Text; 5 | 6 | namespace SharpCV 7 | { 8 | /// 9 | /// opencv2\imgproc.hpp 10 | /// 11 | public enum MorphShapes 12 | { 13 | MORPH_RECT = 0, //!< a rectangular structuring element: \f[E_{ij}=1\f] 14 | MORPH_CROSS = 1, //!< a cross-shaped structuring element: 15 | //!< \f[E_{ij} = \fork{1}{if i=\texttt{anchor.y} or j=\texttt{anchor.x}}{0}{otherwise}\f] 16 | MORPH_ELLIPSE = 2 //!< an elliptic structuring element, that is, a filled ellipse inscribed 17 | //!< into the rectangle Rect(0, 0, esize.width, 0.esize.height) 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /test/UnitTest/UnitTest.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | 6 | false 7 | 8 | AnyCPU;x64 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/SharpCV/NativeAPIs/cv2_native_api.videoio.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | using System.Text; 5 | 6 | namespace SharpCV 7 | { 8 | internal partial class cv2_native_api 9 | { 10 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 11 | internal static extern void videoio_VideoCapture_new2(string filename, int api, out IntPtr output); 12 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 13 | internal static extern void videoio_VideoCapture_new3(int device, int api, out IntPtr output); 14 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 15 | internal static extern void videoio_VideoCapture_read_Mat(IntPtr vid, IntPtr frame, out int output); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/SharpCV/Structs/RotatedRect.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace SharpCV 6 | { 7 | public struct RotatedRect 8 | { 9 | public Point2f Center { get; } 10 | 11 | public Size2f Size { get; } 12 | 13 | public float Angle; 14 | 15 | public RotatedRect(Point2f center, Size2f size, float angle) 16 | { 17 | Size = size; 18 | Center = center; 19 | Angle = angle; 20 | } 21 | 22 | public void Deconstruct(out Point2f center, out Size2f size, out float angle) 23 | { 24 | center = Center; 25 | size = Size; 26 | angle = Angle; 27 | } 28 | 29 | public override string ToString() 30 | { 31 | return $"{Center}, {Size}, {Angle}"; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /test/UnitTest/ImgHighGuiTest.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using System.IO; 3 | using static SharpCV.Binding; 4 | 5 | namespace UnitTest 6 | { 7 | [TestClass] 8 | public class ImgHighGuiTest : Test 9 | { 10 | [TestMethod] 11 | public void imshow() 12 | { 13 | var img = cv2.imread(imgSolar); 14 | // cv2.imshow("solar", img); 15 | // cv2.waitKey(0); 16 | var dv = GetData(img); 17 | } 18 | 19 | public (byte,long[],byte[]) GetData(object target) 20 | { 21 | byte size = 0; 22 | long[] dims = new long[0]; 23 | byte[] data = new byte[0]; 24 | 25 | if (target is SharpCV.Mat mat) 26 | { 27 | dims = mat.shape.dims; 28 | size = (byte)dims.Length; 29 | data = mat.data.ToByteArray(); 30 | } 31 | 32 | return (size, dims, data); 33 | 34 | } 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/SharpCV/Structs/Point.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace SharpCV 6 | { 7 | public struct Point 8 | { 9 | public int X { get; } 10 | public int Y { get; } 11 | 12 | public Point(int x, int y) 13 | { 14 | X = x; 15 | Y = y; 16 | } 17 | 18 | public Point(float x, float y) 19 | { 20 | X = Convert.ToInt32(x); 21 | Y = Convert.ToInt32(y); 22 | } 23 | 24 | public static implicit operator Point((float, float) vals) 25 | => new Point(vals.Item1, vals.Item2); 26 | 27 | public static implicit operator Point((int, int) vals) 28 | => new Point(vals.Item1, vals.Item2); 29 | 30 | public override string ToString() 31 | { 32 | return $"{X}x{Y}"; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/SharpCV/Structs/Point2f.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace SharpCV 6 | { 7 | public struct Point2f 8 | { 9 | public float X { get; } 10 | public float Y { get; } 11 | 12 | public Point2f(int x, int y) 13 | { 14 | X = Convert.ToSingle(x); 15 | Y = Convert.ToSingle(y); 16 | } 17 | 18 | public Point2f(float x, float y) 19 | { 20 | X = x; 21 | Y = y; 22 | } 23 | 24 | public static implicit operator Point2f((float, float) vals) 25 | => new Point2f(vals.Item1, vals.Item2); 26 | 27 | public static implicit operator Point2f((int, int) vals) 28 | => new Point2f(vals.Item1, vals.Item2); 29 | 30 | public override string ToString() 31 | { 32 | return $"{X}x{Y}"; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/SharpCV/Core/MatType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace SharpCV 6 | { 7 | /// 8 | /// https://docs.opencv.org/master/d0/d3a/classcv_1_1DataType.html 9 | /// https://gist.github.com/pabloduque0/456cb62d02a027d3a458f31cdec6771d 10 | /// CV_{U|S|F}C() 11 | /// 12 | /// A Mapping of Type to Numbers in OpenCV 13 | /// C1 C2 C3 C4 14 | /// CV_8U 0 8 16 24 15 | /// CV_8S 1 9 17 25 16 | /// CV_16U 2 10 18 26 17 | /// CV_16S 3 11 19 27 18 | /// CV_32S 4 12 20 28 19 | /// CV_32F 5 13 21 29 20 | /// CV_64F 6 14 22 30 21 | /// 22 | public enum MatType 23 | { 24 | Unknown = -1, 25 | CV_8UC1 = 0, 26 | CV_8UC3 = 16, 27 | CV_32SC1 = 4, 28 | CV_32FC1 = 5, 29 | CV_32SC2 = 12, 30 | CV_64FC1 = 6 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/SharpCV/Structs/Size2f.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace SharpCV 6 | { 7 | public struct Size2f 8 | { 9 | public float Width { get; } 10 | public float Height { get; } 11 | 12 | public Size2f(int width, int height) 13 | { 14 | Width = width; 15 | Height = height; 16 | } 17 | 18 | public Size2f(float width, float height) 19 | { 20 | Width = width; 21 | Height = height; 22 | } 23 | 24 | public static implicit operator Size2f((float, float) vals) 25 | => new Size2f(vals.Item1, vals.Item2); 26 | 27 | public static implicit operator Size2f((int, int) vals) 28 | => new Size2f(vals.Item1, vals.Item2); 29 | 30 | public override string ToString() 31 | { 32 | return $"{Width}x{Height}"; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/SharpCV/NativeAPIs/enum/cv2_native_api.AdaptiveThresholdTypes.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | using System.Text; 5 | 6 | namespace SharpCV 7 | { 8 | /// 9 | /// modules\imgproc\include\opencv2\imgproc.hpp 10 | /// 11 | public enum AdaptiveThresholdTypes 12 | { 13 | /** the threshold value \f$T(x,y)\f$ is a mean of the \f$\texttt{blockSize} \times 14 | \texttt{blockSize}\f$ neighborhood of \f$(x, y)\f$ minus C */ 15 | ADAPTIVE_THRESH_MEAN_C = 0, 16 | /** the threshold value \f$T(x, y)\f$ is a weighted sum (cross-correlation with a Gaussian 17 | window) of the \f$\texttt{blockSize} \times \texttt{blockSize}\f$ neighborhood of \f$(x, y)\f$ 18 | minus C . The default sigma (standard deviation) is used for the specified blockSize . See 19 | #getGaussianKernel*/ 20 | ADAPTIVE_THRESH_GAUSSIAN_C = 1 21 | }; 22 | } 23 | -------------------------------------------------------------------------------- /test/UnitTest/Test.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | 6 | namespace UnitTest 7 | { 8 | public abstract class Test 9 | { 10 | public string datadir = Path.GetFullPath("../../../../../data"); 11 | protected string img3x5; 12 | protected string imgSolar; 13 | protected string mp4Road; 14 | protected string UncorrectedImage; 15 | protected string SmoothImage; 16 | protected string MNIST_Image_5; 17 | public Test() 18 | { 19 | img3x5 = Path.Combine(datadir, "3x5.jpg"); 20 | imgSolar = Path.Combine(datadir, "solar.jpg"); 21 | mp4Road = Path.Combine(datadir, "road.mp4"); 22 | UncorrectedImage = Path.Combine(datadir, "UncorrectedImage.png"); 23 | SmoothImage = Path.Combine(datadir, "SmoothImage.jpg"); 24 | MNIST_Image_5 = Path.Combine(datadir, "mnist_image_5.npy"); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/SharpCV/NativeAPIs/enum/cv2_native_api.BorderTypes.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | using System.Text; 5 | 6 | namespace SharpCV 7 | { 8 | /// 9 | /// modules\core\include\opencv2\core\base.hpp 10 | /// 11 | public enum BorderTypes 12 | { 13 | BORDER_CONSTANT = 0, //!< `iiiiii|abcdefgh|iiiiiii` with some specified `i` 14 | BORDER_REPLICATE = 1, //!< `aaaaaa|abcdefgh|hhhhhhh` 15 | BORDER_REFLECT = 2, //!< `fedcba|abcdefgh|hgfedcb` 16 | BORDER_WRAP = 3, //!< `cdefgh|abcdefgh|abcdefg` 17 | BORDER_REFLECT_101 = 4, //!< `gfedcb|abcdefgh|gfedcba` 18 | BORDER_TRANSPARENT = 5, //!< `uvwxyz|abcdefgh|ijklmno` 19 | 20 | BORDER_REFLECT101 = BORDER_REFLECT_101, //!< same as BORDER_REFLECT_101 21 | BORDER_DEFAULT = BORDER_REFLECT_101, //!< same as BORDER_REFLECT_101 22 | BORDER_ISOLATED = 16 //!< do not look outside of ROI 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /src/SharpCV/APIs/cv2.highgui.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | using System.Text; 5 | 6 | namespace SharpCV 7 | { 8 | public partial class cv_api 9 | { 10 | public void imshow(string windownName, Mat img) 11 | { 12 | cv2_native_api.highgui_imshow(windownName, img); 13 | } 14 | 15 | public void namedWindow(string name, WindowFlags mode) 16 | { 17 | cv2_native_api.highgui_namedWindow(name, (int)mode); 18 | } 19 | 20 | public void resizeWindow(string name, int width, int height) 21 | { 22 | cv2_native_api.highgui_resizeWindow(name, width, height); 23 | } 24 | 25 | public void waitKey(int delay = 0) 26 | { 27 | cv2_native_api.highgui_waitKey(delay, out var output); 28 | } 29 | 30 | public void destroyAllWindows() 31 | { 32 | cv2_native_api.highgui_destroyAllWindows(); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/SharpCV/NativeAPIs/cv2_native_api.highgui.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | using System.Text; 5 | 6 | namespace SharpCV 7 | { 8 | internal partial class cv2_native_api 9 | { 10 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 11 | internal static extern void highgui_imshow(string winName, IntPtr mat); 12 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 13 | internal static extern void highgui_namedWindow(string winName, int flags); 14 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 15 | internal static extern void highgui_resizeWindow(string winName, int width, int height); 16 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 17 | internal static extern void highgui_waitKey(int delay, out int output); 18 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 19 | internal static extern void highgui_destroyAllWindows(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/SharpCV/NativeAPIs/enum/cv2_native_api.WindowFlags.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | using System.Text; 5 | 6 | namespace SharpCV 7 | { 8 | /// 9 | /// modules\highgui\include\opencv2\highgui.hpp 10 | /// 11 | public enum WindowFlags 12 | { 13 | WINDOW_NORMAL = 0x00000000, //!< the user can resize the window (no constraint) / also use to switch a fullscreen window to a normal size. 14 | WINDOW_AUTOSIZE = 0x00000001, //!< the user cannot resize the window, the size is constrainted by the image displayed. 15 | WINDOW_OPENGL = 0x00001000, //!< window with opengl support. 16 | 17 | WINDOW_FULLSCREEN = 1, //!< change the window to fullscreen. 18 | WINDOW_FREERATIO = 0x00000100, //!< the image expends as much as it can (no ratio constraint). 19 | WINDOW_KEEPRATIO = 0x00000000, //!< the ratio of the image is respected. 20 | WINDOW_GUI_EXPANDED = 0x00000000, //!< status bar and tool bar 21 | WINDOW_GUI_NORMAL = 0x00000010, //!< old fashious way 22 | }; 23 | } 24 | -------------------------------------------------------------------------------- /src/SharpCV/Modules/Dnn/Net.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace SharpCV 6 | { 7 | public class Net : DisposableObject 8 | { 9 | public Net() 10 | { 11 | cv2_native_api.dnn_Net_new(out _handle); 12 | } 13 | 14 | public Net(IntPtr handle) 15 | { 16 | _handle = handle; 17 | } 18 | 19 | public void setInput(Mat blob, string name = "") 20 | { 21 | cv2_native_api.dnn_Net_setInput(_handle, blob, name); 22 | } 23 | 24 | public Mat forward(string outputName = "") 25 | { 26 | cv2_native_api.dnn_Net_forward1(_handle, outputName, out var handle); 27 | return new Mat(handle); 28 | } 29 | 30 | protected override void FreeHandle() 31 | { 32 | cv2_native_api.dnn_Net_delete(_handle); 33 | } 34 | 35 | public static implicit operator IntPtr(Net net) 36 | => net._handle; 37 | 38 | public static implicit operator Net(IntPtr handle) 39 | => new Net(handle); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/SharpCV/NativeAPIs/enum/cv2_native_api.ContourApproximationModes.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | using System.Text; 5 | 6 | namespace SharpCV 7 | { 8 | /// 9 | /// opencv2\imgproc.hpp 10 | /// 11 | public enum ContourApproximationModes 12 | { 13 | /** stores absolutely all the contour points. That is, any 2 subsequent points (x1,y1) and 14 | (x2,y2) of the contour will be either horizontal, vertical or diagonal neighbors, that is, 15 | max(abs(x1-x2),abs(y2-y1))==1. */ 16 | CHAIN_APPROX_NONE = 1, 17 | /** compresses horizontal, vertical, and diagonal segments and leaves only their end points. 18 | For example, an up-right rectangular contour is encoded with 4 points. */ 19 | CHAIN_APPROX_SIMPLE = 2, 20 | /** applies one of the flavors of the Teh-Chin chain approximation algorithm @cite TehChin89 */ 21 | CHAIN_APPROX_TC89_L1 = 3, 22 | /** applies one of the flavors of the Teh-Chin chain approximation algorithm @cite TehChin89 */ 23 | CHAIN_APPROX_TC89_KCOS = 4 24 | }; 25 | } 26 | -------------------------------------------------------------------------------- /src/SharpCV/NativeAPIs/enum/cv2_native_api.RetrievalModes.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | using System.Text; 5 | 6 | namespace SharpCV 7 | { 8 | /// 9 | /// opencv2\imgproc.hpp 10 | /// 11 | public enum RetrievalModes 12 | { 13 | /** retrieves only the extreme outer contours. It sets `hierarchy[i][2]=hierarchy[i][3]=-1` for 14 | all the contours. */ 15 | RETR_EXTERNAL = 0, 16 | /** retrieves all of the contours without establishing any hierarchical relationships. */ 17 | RETR_LIST = 1, 18 | /** retrieves all of the contours and organizes them into a two-level hierarchy. At the top 19 | level, there are external boundaries of the components. At the second level, there are 20 | boundaries of the holes. If there is another contour inside a hole of a connected component, it 21 | is still put at the top level. */ 22 | RETR_CCOMP = 2, 23 | /** retrieves all of the contours and reconstructs a full hierarchy of nested contours.*/ 24 | RETR_TREE = 3, 25 | RETR_FLOODFILL = 4 //!< 26 | }; 27 | } 28 | -------------------------------------------------------------------------------- /src/SharpCV/NativeAPIs/enum/cv2_native_api.ThresholdTypes.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | using System.Text; 5 | 6 | namespace SharpCV 7 | { 8 | /// 9 | /// modules\imgproc\include\opencv2\imgproc.hpp 10 | /// 11 | public enum ThresholdTypes 12 | { 13 | THRESH_BINARY = 0, //!< \f[\texttt{dst} (x,y) = \fork{\texttt{maxval}}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{0}{otherwise}\f] 14 | THRESH_BINARY_INV = 1, //!< \f[\texttt{dst} (x,y) = \fork{0}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{\texttt{maxval}}{otherwise}\f] 15 | THRESH_TRUNC = 2, //!< \f[\texttt{dst} (x,y) = \fork{\texttt{threshold}}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{\texttt{src}(x,y)}{otherwise}\f] 16 | THRESH_TOZERO = 3, //!< \f[\texttt{dst} (x,y) = \fork{\texttt{src}(x,y)}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{0}{otherwise}\f] 17 | THRESH_TOZERO_INV = 4, //!< \f[\texttt{dst} (x,y) = \fork{0}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{\texttt{src}(x,y)}{otherwise}\f] 18 | THRESH_MASK = 7, 19 | THRESH_OTSU = 8, //!< flag, use Otsu algorithm to choose the optimal threshold value 20 | THRESH_TRIANGLE = 16 //!< flag, use Triangle algorithm to choose the optimal threshold value 21 | }; 22 | } 23 | -------------------------------------------------------------------------------- /src/SharpCV/DisposableObject.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | using System.Text; 5 | 6 | namespace SharpCV 7 | { 8 | public class DisposableObject : IDisposable 9 | { 10 | protected IntPtr _handle; 11 | 12 | // Flag: Has Dispose already been called? 13 | bool disposed = false; 14 | 15 | // Public implementation of Dispose pattern callable by consumers. 16 | public void Dispose() 17 | { 18 | Dispose(true); 19 | GC.SuppressFinalize(this); 20 | } 21 | 22 | // Protected implementation of Dispose pattern. 23 | private void Dispose(bool disposing) 24 | { 25 | if (disposed) 26 | return; 27 | 28 | if (disposing) 29 | { 30 | // Free any other managed objects here. 31 | // 32 | } 33 | 34 | // Free any unmanaged objects here. 35 | FreeHandle(); 36 | 37 | _handle = IntPtr.Zero; 38 | 39 | disposed = true; 40 | } 41 | 42 | protected virtual void FreeHandle() 43 | { 44 | Marshal.FreeHGlobal(_handle); 45 | } 46 | 47 | ~DisposableObject() 48 | { 49 | Dispose(false); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /test/UnitTest/OCRImageEnhance.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using SharpCV; 3 | using System; 4 | using Tensorflow.NumPy; 5 | using static SharpCV.Binding; 6 | 7 | namespace UnitTest 8 | { 9 | [TestClass] 10 | public class OCRImageEnhance : Test 11 | { 12 | public Mat imread() 13 | { 14 | var img = cv2.imread(SmoothImage); 15 | var gray = cv2.cvtColor(img, ColorConversionCodes.COLOR_RGB2GRAY); 16 | return gray; 17 | } 18 | 19 | public void imwrite(Mat img) 20 | { 21 | var result = cv2.imwrite("EnhancedImage.jpg", img); 22 | Assert.IsTrue(result); 23 | } 24 | 25 | [TestMethod] 26 | public void enhanceImage() 27 | { 28 | Mat img = imread(); 29 | 30 | NDArray filter1_kernel = np.array(new float[3, 3] { { 0, -1, 0 }, { -1, 5, -1 }, { 0, -1, 0 } }); 31 | Mat filter1 = cv2.filter2D(img, MatType.CV_8UC1, new Mat(filter1_kernel), new Point(-1, -1), 0); 32 | var open_kernel = cv2.getStructuringElement(MorphShapes.MORPH_RECT, (3, 3)); 33 | var img_open = cv2.morphologyEx(filter1, MorphTypes.MORPH_OPEN, open_kernel, iterations: 1); 34 | // var img_median = cv2.medianBlur(img_open, 3); 35 | 36 | imwrite(img_open); 37 | } 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/SharpCV/NativeAPIs/cv2_native_api.imgcodecs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics.Contracts; 4 | using System.Runtime.InteropServices; 5 | using System.Text; 6 | 7 | namespace SharpCV 8 | { 9 | internal partial class cv2_native_api 10 | { 11 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 12 | internal static extern void imgcodecs_imread(string filename, int flags, out IntPtr output); 13 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 14 | internal static extern void imgcodecs_imwrite(string filename, IntPtr img, [In] int[] @params, int paramsLength, out int output); 15 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 16 | 17 | internal static unsafe extern void imgcodecs_imdecode_vector(byte* buf, int bufLength, IMREAD_COLOR flags, out IntPtr output); 18 | 19 | // Do not consider that "ext" may not be ASCII characters 20 | [Pure, DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl, BestFitMapping = false, ThrowOnUnmappableChar = true, ExactSpelling = true)] 21 | internal static extern int imgcodecs_imencode_vector( 22 | [MarshalAs(UnmanagedType.LPStr)] string ext, IntPtr img, IntPtr buf, [In] int[] @params, int paramsLength, out int returnValue); 23 | 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/SharpCV/APIs/cv2.photo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | using System.Text; 5 | 6 | namespace SharpCV 7 | { 8 | public partial class cv_api 9 | { 10 | /// 11 | /// Image Denoising 12 | /// Non-local Means Denoisin 13 | /// works with a single grayscale images 14 | /// https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_photo/py_non_local_means/py_non_local_means.html 15 | /// 16 | /// 17 | public Mat fastNlMeansDenoising(Mat src, 18 | float h = 3, 19 | int templateWindowSize = 7, 20 | int searchWindowSize = 21) 21 | { 22 | var dst = new Mat(); 23 | cv2_native_api.photo_fastNlMeansDenoising(src.InputArray, dst.OutputArray, h, templateWindowSize, searchWindowSize); 24 | return dst; 25 | } 26 | 27 | public Mat fastNlMeansDenoisingColored(Mat src, 28 | float h = 3, 29 | float hColor = 3, 30 | int templateWindowSize = 7, 31 | int searchWindowSize = 21) 32 | { 33 | var dst = new Mat(); 34 | cv2_native_api.photo_fastNlMeansDenoisingColored(src.InputArray, dst.OutputArray, h, hColor, templateWindowSize, searchWindowSize); 35 | return dst; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/SharpCV/Vectors/VectorOfMat.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace SharpCV 6 | { 7 | /// 8 | /// 9 | /// 10 | public class VectorOfMat : DisposableObject 11 | { 12 | public VectorOfMat() 13 | { 14 | _handle = cv2_native_api.vector_Mat_new1(); 15 | } 16 | 17 | public VectorOfMat(IntPtr ptr) => _handle = ptr; 18 | 19 | protected override void FreeHandle() 20 | { 21 | cv2_native_api.vector_Mat_delete(_handle); 22 | } 23 | 24 | public int Size => cv2_native_api.vector_Mat_getSize(_handle); 25 | 26 | public Mat[] ToArray() => ToArray(); 27 | 28 | public T[] ToArray() 29 | where T : Mat, new() 30 | { 31 | var size = Size; 32 | if (size == 0) 33 | return new T[0]; 34 | 35 | var dst = new T[size]; 36 | var dstPtr = new IntPtr[size]; 37 | for (var i = 0; i < size; i++) 38 | { 39 | var m = new T(); 40 | dst[i] = m; 41 | dstPtr[i] = m; 42 | } 43 | cv2_native_api.vector_Mat_assignToArray(_handle, dstPtr); 44 | 45 | return dst; 46 | } 47 | 48 | public static implicit operator IntPtr(VectorOfMat mat) 49 | => mat._handle; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /test/UnitTest/ImgCodecsTest.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using System.IO; 3 | using static SharpCV.Binding; 4 | 5 | namespace UnitTest 6 | { 7 | [TestClass] 8 | public class ImgCodecsTest : Test 9 | { 10 | [TestMethod] 11 | public void imread() 12 | { 13 | var img = cv2.imread(imgSolar); 14 | Assert.AreEqual(897900, img.size); 15 | Assert.AreEqual((410, 730, 3), img.shape); 16 | } 17 | 18 | [TestMethod] 19 | public void imwrite() 20 | { 21 | var img = cv2.imread(imgSolar); 22 | var result = cv2.imwrite("solar.jpg", img); 23 | Assert.IsTrue(result); 24 | } 25 | 26 | [TestMethod] 27 | public void imcrop() 28 | { 29 | var img = cv2.imread(imgSolar); 30 | var cropped1 = cv2.imcrop(img, (150, 50, 200, 350)); 31 | Assert.AreEqual((350, 200, 3), cropped1.shape); 32 | 33 | var cropped2 = img[(50, 400), (150, 350)]; 34 | Assert.AreEqual((350, 200, 3), cropped2.shape); 35 | } 36 | 37 | [TestMethod] 38 | public void imendecode() 39 | { 40 | var mat = cv2.imread(imgSolar); 41 | var fbs_png = mat.ImEncode(); 42 | var mat2 = SharpCV.Mat.ImDecode(fbs_png); 43 | 44 | CollectionAssert.AreEqual(mat.data.ToByteArray(), mat2.data.ToByteArray()); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/SharpCV/APIs/cv2.core.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Runtime.InteropServices; 5 | using System.Text; 6 | 7 | namespace SharpCV 8 | { 9 | public partial class cv_api 10 | { 11 | public Mat flip(Mat img, FLIP_MODE mode) 12 | { 13 | var dst = new Mat(); 14 | cv2_native_api.core_flip(img.InputArray, dst.OutputArray, (int)mode); 15 | return dst; 16 | } 17 | 18 | public Mat rotate(Mat img, RotateFlags flags) 19 | { 20 | var dst = new Mat(); 21 | cv2_native_api.core_rotate(img.InputArray, dst.OutputArray, (int)flags); 22 | return dst; 23 | } 24 | 25 | public Mat[] split(Mat img) 26 | { 27 | using (var vec = new VectorOfMat()) 28 | { 29 | cv2_native_api.core_split(img, vec); 30 | return vec.ToArray(); 31 | } 32 | } 33 | 34 | public Mat hconcat(params Mat[] imgs) 35 | { 36 | var dst = new Mat(); 37 | cv2_native_api.core_hconcat1(imgs.Select(x => (IntPtr)x).ToArray(), (uint)imgs.Length, dst.OutputArray); 38 | return dst; 39 | } 40 | 41 | public Mat vconcat(params Mat[] imgs) 42 | { 43 | var dst = new Mat(); 44 | cv2_native_api.core_vconcat1(imgs.Select(x => (IntPtr)x).ToArray(), (uint)imgs.Length, dst.OutputArray); 45 | return dst; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /test/UnitTest/VideoTest.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using SharpCV; 3 | using System.IO; 4 | using static SharpCV.Binding; 5 | 6 | namespace UnitTest 7 | { 8 | [TestClass] 9 | public class VideoTest : Test 10 | { 11 | [TestMethod] 12 | public void VideoCaptureFromFile() 13 | { 14 | int frameCnt = 0; 15 | Mat lastFrame = null; 16 | var vid = cv2.VideoCapture(mp4Road); 17 | var (loaded, frame) = vid.read(); 18 | while (loaded) 19 | { 20 | frameCnt++; 21 | lastFrame = frame; 22 | (loaded, frame) = vid.read(); 23 | /*if (loaded) 24 | { 25 | cv2.imshow("video frame", frame); 26 | cv2.waitKey(0); 27 | }*/ 28 | } 29 | Assert.AreEqual(38, frameCnt); 30 | Assert.AreEqual(720, lastFrame.shape[0]); 31 | Assert.AreEqual(1280, lastFrame.shape[1]); 32 | Assert.AreEqual(3, lastFrame.shape[2]); 33 | } 34 | 35 | [Ignore] 36 | [TestMethod] 37 | public void VideoCaptureFromCamera() 38 | { 39 | var vid = cv2.VideoCapture(0); 40 | var (loaded, frame) = vid.read(); 41 | while (loaded) 42 | { 43 | (loaded, frame) = vid.read(); 44 | cv2.imshow("camera capture", frame); 45 | cv2.waitKey(100); 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/SharpCV/NativeAPIs/enum/cv2_native_api.InterpolationFlags.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | using System.Text; 5 | 6 | namespace SharpCV 7 | { 8 | /// 9 | /// modules\imgproc\include\opencv2\imgproc.hpp 10 | /// 11 | public enum InterpolationFlags 12 | { 13 | /** nearest neighbor interpolation */ 14 | INTER_NEAREST = 0, 15 | /** bilinear interpolation */ 16 | INTER_LINEAR = 1, 17 | /** bicubic interpolation */ 18 | INTER_CUBIC = 2, 19 | /** resampling using pixel area relation. It may be a preferred method for image decimation, as 20 | it gives moire'-free results. But when the image is zoomed, it is similar to the INTER_NEAREST 21 | method. */ 22 | INTER_AREA = 3, 23 | /** Lanczos interpolation over 8x8 neighborhood */ 24 | INTER_LANCZOS4 = 4, 25 | /** Bit exact bilinear interpolation */ 26 | INTER_LINEAR_EXACT = 5, 27 | /** mask for interpolation codes */ 28 | INTER_MAX = 7, 29 | /** flag, fills all of the destination image pixels. If some of them correspond to outliers in the 30 | source image, they are set to zero */ 31 | WARP_FILL_OUTLIERS = 8, 32 | /** flag, inverse transformation 33 | 34 | For example, #linearPolar or #logPolar transforms: 35 | - flag is __not__ set: \f$dst( \rho , \phi ) = src(x,y)\f$ 36 | - flag is set: \f$dst(x,y) = src( \rho , \phi )\f$ 37 | */ 38 | WARP_INVERSE_MAP = 16 39 | }; 40 | } 41 | -------------------------------------------------------------------------------- /src/SharpCV/NativeAPIs/enum/cv2_native_api.MorphTypes.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | using System.Text; 5 | 6 | namespace SharpCV 7 | { 8 | /// 9 | /// opencv2\imgproc.hpp 10 | /// 11 | public enum MorphTypes 12 | { 13 | MORPH_ERODE = 0, //!< see #erode 14 | MORPH_DILATE = 1, //!< see #dilate 15 | MORPH_OPEN = 2, //!< an opening operation 16 | //!< \f[\texttt{dst} = \mathrm{open} ( \texttt{src} , \texttt{element} )= \mathrm{dilate} ( \mathrm{erode} ( \texttt{src} , \texttt{element} ))\f] 17 | MORPH_CLOSE = 3, //!< a closing operation 18 | //!< \f[\texttt{dst} = \mathrm{close} ( \texttt{src} , \texttt{element} )= \mathrm{erode} ( \mathrm{dilate} ( \texttt{src} , \texttt{element} ))\f] 19 | MORPH_GRADIENT = 4, //!< a morphological gradient 20 | //!< \f[\texttt{dst} = \mathrm{morph\_grad} ( \texttt{src} , \texttt{element} )= \mathrm{dilate} ( \texttt{src} , \texttt{element} )- \mathrm{erode} ( \texttt{src} , \texttt{element} )\f] 21 | MORPH_TOPHAT = 5, //!< "top hat" 22 | //!< \f[\texttt{dst} = \mathrm{tophat} ( \texttt{src} , \texttt{element} )= \texttt{src} - \mathrm{open} ( \texttt{src} , \texttt{element} )\f] 23 | MORPH_BLACKHAT = 6, //!< "black hat" 24 | //!< \f[\texttt{dst} = \mathrm{blackhat} ( \texttt{src} , \texttt{element} )= \mathrm{close} ( \texttt{src} , \texttt{element} )- \texttt{src}\f] 25 | MORPH_HITMISS = 7 //!< "hit or miss" 26 | //!< .- Only supported for CV_8UC1 binary images. A tutorial can be found in the documentation 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /test/UnitTest/CreationTest.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using SharpCV; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | using Tensorflow.NumPy; 7 | using static SharpCV.Binding; 8 | 9 | namespace UnitTest 10 | { 11 | [TestClass] 12 | public class CreationTest : Test 13 | { 14 | [TestMethod] 15 | public void ndarray_2dim_byte() 16 | { 17 | NDArray kernel = new byte[,] 18 | { 19 | { 172, 172, 173 }, 20 | { 174, 174, 174 }, 21 | { 175, 176, 173 } 22 | }; 23 | 24 | var mat = new Mat(kernel); 25 | 26 | Assert.AreEqual((3, 3), mat.shape); 27 | Assert.AreEqual(kernel[0], mat.data[0]); 28 | Assert.AreEqual(kernel[1], mat.data[1]); 29 | Assert.AreEqual(kernel[2], mat.data[2]); 30 | } 31 | 32 | [TestMethod] 33 | public void ndarray_2dim_float() 34 | { 35 | NDArray kernel = new float[,] 36 | { 37 | { 0, -1, 0 }, 38 | { -1, 5, -1 }, 39 | { -2, -1, 3 } 40 | }; 41 | 42 | var mat = new Mat(kernel); 43 | 44 | Assert.AreEqual((3, 3), mat.shape); 45 | Assert.AreEqual(kernel[0], mat.data[0]); 46 | Assert.AreEqual(kernel[1], mat.data[1]); 47 | Assert.AreEqual(kernel[2], mat.data[2]); 48 | } 49 | 50 | [TestMethod] 51 | public void ndarray_mat_3x5() 52 | { 53 | var img = cv2.imread(img3x5); 54 | var nd = img.data[":", ":", "0"]; 55 | var mat = new Mat(nd); 56 | 57 | Assert.AreEqual((5, 3), nd.shape); 58 | Assert.AreEqual(nd[0], mat.data[0]); 59 | Assert.AreEqual(nd[1], mat.data[1]); 60 | Assert.AreEqual(nd[2], mat.data[2]); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/SharpCV/NativeAPIs/enum/cv2_native_api.IMREAD_COLOR.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | using System.Text; 5 | 6 | namespace SharpCV 7 | { 8 | /// 9 | /// modules\imgcodecs\include\opencv2\imgcodecs.hpp 10 | /// 11 | public enum IMREAD_COLOR 12 | { 13 | IMREAD_UNCHANGED = -1, //!< If set, return the loaded image as is (with alpha channel, otherwise it gets cropped). 14 | IMREAD_GRAYSCALE = 0, //!< If set, always convert image to the single channel grayscale image (codec internal conversion). 15 | IMREAD_COLOR = 1, //!< If set, always convert image to the 3 channel BGR color image. 16 | IMREAD_ANYDEPTH = 2, //!< If set, return 16-bit/32-bit image when the input has the corresponding depth, otherwise convert it to 8-bit. 17 | IMREAD_ANYCOLOR = 4, //!< If set, the image is read in any possible color format. 18 | IMREAD_LOAD_GDAL = 8, //!< If set, use the gdal driver for loading the image. 19 | IMREAD_REDUCED_GRAYSCALE_2 = 16, //!< If set, always convert image to the single channel grayscale image and the image size reduced 1/2. 20 | IMREAD_REDUCED_COLOR_2 = 17, //!< If set, always convert image to the 3 channel BGR color image and the image size reduced 1/2. 21 | IMREAD_REDUCED_GRAYSCALE_4 = 32, //!< If set, always convert image to the single channel grayscale image and the image size reduced 1/4. 22 | IMREAD_REDUCED_COLOR_4 = 33, //!< If set, always convert image to the 3 channel BGR color image and the image size reduced 1/4. 23 | IMREAD_REDUCED_GRAYSCALE_8 = 64, //!< If set, always convert image to the single channel grayscale image and the image size reduced 1/8. 24 | IMREAD_REDUCED_COLOR_8 = 65, //!< If set, always convert image to the 3 channel BGR color image and the image size reduced 1/8. 25 | IMREAD_IGNORE_ORIENTATION = 128 //!< If set, do not rotate the image according to EXIF's orientation flag. 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/SharpCV/Modules/Dnn/Dnn.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace SharpCV 6 | { 7 | public class Dnn 8 | { 9 | public Net readNetFromTensorflow(string model, string config = null) 10 | { 11 | cv2_native_api.dnn_readNetFromTensorflow(model, config, out var handle); 12 | return new Net(handle); 13 | } 14 | 15 | public Net ReadNetFromTorch(string model, bool isBinary = true) 16 | { 17 | cv2_native_api.dnn_readNetFromTorch(model, isBinary, out var handle); 18 | return new Net(handle); 19 | } 20 | 21 | public Net ReadNetFromONNX(string model) 22 | { 23 | cv2_native_api.dnn_readNetFromONNX(model, out var handle); 24 | return new Net(handle); 25 | } 26 | 27 | /// 28 | /// Creates 4-dimensional blob from image. 29 | /// 30 | /// input image (with 1-, 3- or 4-channels). 31 | /// 32 | /// spatial size for output image 33 | /// scalar with mean values which are subtracted from channels. 34 | /// flag which indicates that swap first and last channels in 3-channel image is necessary. 35 | /// flag which indicates whether image will be cropped after resize or not 36 | /// 37 | public Mat blobFromImage(Mat image, double scaleFactor, (int, int) size, Scalar? mean = null, bool swapRB = true, bool crop = false) 38 | { 39 | cv2_native_api.dnn_blobFromImage(image, 40 | scaleFactor, 41 | new Size(size.Item1, size.Item2), 42 | mean ?? new Scalar(), 43 | swapRB, 44 | crop, 45 | out var handle); 46 | return new Mat(handle); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/SharpCV/Util/ArrayAddress2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Runtime.InteropServices; 5 | 6 | namespace SharpCV 7 | { 8 | public class ArrayAddress2 : DisposableObject 9 | where T : unmanaged 10 | { 11 | private readonly T[][] array; 12 | private readonly GCHandle[] gch; 13 | private readonly IntPtr[] ptr; 14 | 15 | public ArrayAddress2(T[][] array) 16 | { 17 | this.array = array ?? throw new ArgumentNullException(nameof(array)); 18 | 19 | ptr = new IntPtr[array.Length]; 20 | gch = new GCHandle[array.Length]; 21 | for (var i = 0; i < array.Length; i++) 22 | { 23 | var elem = array[i]; 24 | if (elem == null) 25 | throw new ArgumentException($"array[{i}] is not valid array object."); 26 | 27 | gch[i] = GCHandle.Alloc(elem, GCHandleType.Pinned); 28 | ptr[i] = gch[i].AddrOfPinnedObject(); 29 | } 30 | } 31 | 32 | public ArrayAddress2(IEnumerable> enumerable) 33 | : this(enumerable.Select(x => x.ToArray()).ToArray()) 34 | { 35 | } 36 | 37 | protected override void FreeHandle() 38 | { 39 | foreach (var h in gch) 40 | if (h.IsAllocated) 41 | h.Free(); 42 | } 43 | 44 | public IntPtr[] Pointer => ptr; 45 | 46 | public static implicit operator IntPtr[](ArrayAddress2 self) 47 | => self.Pointer; 48 | 49 | int[] _lengths = null; 50 | public int[] Dim2Lengths 51 | { 52 | get 53 | { 54 | if(_lengths == null) 55 | { 56 | _lengths = new int[array.Length]; 57 | for (var i = 0; i < array.Length; i++) 58 | _lengths[i] = array[i].Length; 59 | } 60 | 61 | return _lengths; 62 | } 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /src/SharpCV/NativeAPIs/cv2_native_api.dnn.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | using System.Text; 5 | 6 | namespace SharpCV 7 | { 8 | internal partial class cv2_native_api 9 | { 10 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 11 | internal static extern void dnn_readNetFromDarknet(string cfgFile, string darknetModel, out IntPtr returnValue); 12 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 13 | internal static extern void dnn_Net_new(out IntPtr net); 14 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 15 | internal static extern void dnn_readNetFromTensorflow(string model, string config, out IntPtr output); 16 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 17 | internal static extern void dnn_readNetFromTorch(string model, bool isBinary, out IntPtr output); 18 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 19 | internal static extern void dnn_readNetFromONNX(string model, out IntPtr output); 20 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 21 | internal static extern void dnn_readTensorFromONNX(string path, out IntPtr output); 22 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 23 | internal static extern void dnn_Net_delete(IntPtr net); 24 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 25 | internal static extern void dnn_blobFromImage(IntPtr image, double scalefactor, Size size, Scalar mean, bool swapRB, bool crop, out IntPtr output); 26 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 27 | internal static extern void dnn_Net_setInput(IntPtr net, IntPtr input, string name); 28 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 29 | internal static extern void dnn_Net_forward1(IntPtr net, string outputName, out IntPtr output); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/SharpCV/Vectors/VectorOfVectorPoint.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SharpCV 4 | { 5 | public class VectorOfVectorPoint : DisposableObject 6 | { 7 | public VectorOfVectorPoint() 8 | { 9 | _handle = cv2_native_api.vector_vector_Point_new1(); 10 | } 11 | 12 | public VectorOfVectorPoint(IntPtr ptr) 13 | { 14 | _handle = ptr; 15 | } 16 | 17 | protected override void FreeHandle() 18 | { 19 | cv2_native_api.vector_vector_Point_delete(_handle); 20 | } 21 | 22 | public int Size1 23 | { 24 | get 25 | { 26 | var res = cv2_native_api.vector_vector_Point_getSize1(_handle).ToInt32(); 27 | GC.KeepAlive(this); 28 | return res; 29 | } 30 | } 31 | 32 | public int Size => Size1; 33 | 34 | public long[] Size2 35 | { 36 | get 37 | { 38 | var size1 = Size1; 39 | var size2Org = new IntPtr[size1]; 40 | cv2_native_api.vector_vector_Point_getSize2(_handle, size2Org); 41 | GC.KeepAlive(this); 42 | var size2 = new long[size1]; 43 | for (var i = 0; i < size1; i++) 44 | { 45 | size2[i] = size2Org[i].ToInt64(); 46 | } 47 | return size2; 48 | } 49 | } 50 | 51 | public Point[][] ToArray() 52 | { 53 | var size1 = Size1; 54 | if (size1 == 0) 55 | return new Point[0][]; 56 | var size2 = Size2; 57 | 58 | var ret = new Point[size1][]; 59 | for (var i = 0; i < size1; i++) 60 | { 61 | ret[i] = new Point[size2[i]]; 62 | } 63 | using (var retPtr = new ArrayAddress2(ret)) 64 | { 65 | cv2_native_api.vector_vector_Point_copy(_handle, retPtr); 66 | GC.KeepAlive(this); 67 | } 68 | return ret; 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/SharpCV/Core/Mat.Index.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | using System.Text; 6 | using Tensorflow.NumPy; 7 | 8 | namespace SharpCV 9 | { 10 | public partial class Mat 11 | { 12 | public unsafe Mat this[(int, int) y, (int, int) x] 13 | { 14 | get 15 | { 16 | // var cropped = data[new Slice(y.Item1, y.Item2), new Slice(x.Item1, x.Item2)]; 17 | cv2_native_api.core_Mat_new7(_handle, new Rect(x.Item1, y.Item1, x.Item2 - x.Item1, y.Item2 - y.Item1), out var handle); 18 | // cv2_native_api.imgcodecs_imdecode_vector(cropped.GetData().ToArray(), cropped.size, IMREAD_COLOR.IMREAD_COLOR, out var handle); 19 | return new Mat(handle); 20 | } 21 | } 22 | 23 | public unsafe NDArray this[int row, int col] 24 | { 25 | get 26 | { 27 | cv2_native_api.core_Mat_ptr2d(_handle, row, col, out var output); 28 | return ndim switch 29 | { 30 | 2 => NDArray.Scalar(*(byte*)output), 31 | 3 => np.array(*(byte*)output, *((byte*)output + 1), *((byte*)output + 2)), 32 | _ => throw new NotImplementedException($"Can't found index access for ndim: {ndim}") 33 | }; 34 | } 35 | 36 | set 37 | { 38 | // BGR format 39 | } 40 | } 41 | 42 | public unsafe byte this[int row, int col, int channel] 43 | { 44 | get 45 | { 46 | cv2_native_api.core_Mat_ptr2d(_handle, row, col, out var output); 47 | return channel switch 48 | { 49 | 0 => *(byte*)output, 50 | 1 => *((byte*)output + 1), 51 | 2 => *((byte*)output + 2), 52 | _ => throw new NotImplementedException($"Channel can't exceed {channel}") 53 | }; 54 | } 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SharpCV 2 | 3 | A image library combines [OpenCV](https://github.com/opencv/opencv) and [NumSharp](https://github.com/SciSharp/NumSharp.Lite) together. `SharpCV` returns `Mat` object with `NDArray` supported, which makes it easier to do data manipulation like slicing. 4 | 5 | [![Join the chat at https://gitter.im/publiclab/publiclab](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/sci-sharp/community) [![NuGet](https://img.shields.io/nuget/dt/SharpCV.svg)](https://www.nuget.org/packages/SharpCV) 6 | 7 | ### How to use 8 | 9 | Install OpenCV prebuild binary 10 | 11 | ```powershell 12 | PM> Install-Package SharpCV 13 | PM> Install-Package OpenCvSharp4.runtime.win 14 | ``` 15 | Import SharpCV and OpenCV library 16 | ```csharp 17 | using SharpCV; 18 | using static SharpCV.Binding; 19 | ``` 20 | Interact with `NDArray` 21 | 22 | ```csharp 23 | NDArray kernel = new float[,] 24 | { 25 | { 0, -1, 0 }, 26 | { -1, 5, -1 }, 27 | { 0, -1, 0 } 28 | }; 29 | 30 | var mat = new Mat(kernel); 31 | 32 | Assert.AreEqual((3, 3), mat.shape); 33 | Assert.AreEqual(kernel[0], mat.data[0]); // { 0, -1, 0 } 34 | Assert.AreEqual(kernel[1], mat.data[1]); // { -1, 5, -1 } 35 | Assert.AreEqual(kernel[2], mat.data[2]); // { 0, -1, 0 } 36 | ``` 37 | 38 | Pixel level access 39 | 40 | ```csharp 41 | var img = cv2.imread(imgSolar, IMREAD_COLOR.IMREAD_GRAYSCALE); 42 | byte p = img[8, 8]; 43 | Assert.AreEqual(18, p); 44 | 45 | img = cv2.imread(imgSolar); 46 | var (b, g, r) = img[8, 8]; 47 | Assert.AreEqual((32, 19, 11), (b, g, r)); 48 | ``` 49 | 50 | Convert to black and white image 51 | 52 | ```csharp 53 | var img = cv2.imread("solar.jpg"); 54 | var gray = cv2.cvtColor(img, ColorConversionCodes.COLOR_RGB2GRAY); 55 | var (ret, binary) = cv2.threshold(gray, 0, 255, ThresholdTypes.THRESH_BINARY | ThresholdTypes.THRESH_TRIANGLE); 56 | cv2.imshow("black and white", binary); 57 | cv2.waitKey(0); 58 | ``` 59 | Video capture from file or camera 60 | ```csharp 61 | var vid = cv2.VideoCapture("road.mp4"); 62 | var (loaded, frame) = vid.read(); 63 | while (loaded) 64 | { 65 | (loaded, frame) = vid.read(); 66 | cv2.imshow("video", frame); 67 | } 68 | ``` 69 | 70 | If you want to learn more about the API implementation, please refer to the official [documentation](https://docs.opencv.org/). 71 | 72 | -------------------------------------------------------------------------------- /src/SharpCV/SharpCV.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0;net6.0 5 | 10.0 6 | SharpCV 7 | SharpCV 8 | SharpCV 9 | 0.14.0 10 | Haiping Chen 11 | SciSharp STACK 12 | SharpCV 13 | true 14 | A image library combines OpenCV and NumSharp together. 15 | https://github.com/SciSharp/SharpCV 16 | https://avatars3.githubusercontent.com/u/44989469?s=200&v=4 17 | https://github.com/SciSharp/SharpCV 18 | OpenCV 19 | git 20 | cv2.dnn, cv2.morphologyEx, cv2.findContours, cv2.drawContours, cv2.approxPolyDP, cv2.minAreaRect, cv2.split 21 | AnyCPU;x64 22 | 23 | 24 | 25 | DEBUG;TRACE 26 | true 27 | 28 | 29 | 30 | DEBUG;TRACE 31 | true 32 | 33 | 34 | 35 | true 36 | 37 | 38 | 39 | 40 | true 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /src/SharpCV/Modules/ImgProc/Moments.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace SharpCV 6 | { 7 | public partial class Moments 8 | { 9 | /// 10 | /// spatial moments 11 | /// 12 | public double M00, M10, M01, M20, M11, M02, M30, M21, M12, M03; 13 | 14 | /// 15 | /// central moments 16 | /// 17 | public double Mu20, Mu11, Mu02, Mu30, Mu21, Mu12, Mu03; 18 | 19 | /// 20 | /// central normalized moments 21 | /// 22 | public double Nu20, Nu11, Nu02, Nu30, Nu21, Nu12, Nu03; 23 | 24 | public Moments(Mat img, bool binaryImage = false) 25 | { 26 | cv2_native_api.imgproc_moments(img.InputArray, binaryImage ? 1 : 0, out var m); 27 | Initialize(m.m00, m.m10, m.m01, m.m20, m.m11, m.m02, m.m30, m.m21, m.m12, m.m03); 28 | } 29 | 30 | private void Initialize(double m00, double m10, double m01, double m20, double m11, 31 | double m02, double m30, double m21, double m12, double m03) 32 | { 33 | M00 = m00; 34 | M10 = m10; 35 | M01 = m01; 36 | M20 = m20; 37 | M11 = m11; 38 | M02 = m02; 39 | M30 = m30; 40 | M21 = m21; 41 | M12 = m12; 42 | M03 = m03; 43 | 44 | double cx = 0, cy = 0, invM00 = 0; 45 | if (Math.Abs(M00) > double.Epsilon) 46 | { 47 | invM00 = 1.0 / M00; 48 | cx = M10 * invM00; 49 | cy = M01 * invM00; 50 | } 51 | 52 | Mu20 = M20 - M10 * cx; 53 | Mu11 = M11 - M10 * cy; 54 | Mu02 = M02 - M01 * cy; 55 | 56 | Mu30 = M30 - cx * (3 * Mu20 + cx * M10); 57 | Mu21 = M21 - cx * (2 * Mu11 + cx * M01) - cy * Mu20; 58 | Mu12 = M12 - cy * (2 * Mu11 + cy * M10) - cx * Mu02; 59 | Mu03 = M03 - cy * (3 * Mu02 + cy * M01); 60 | 61 | var invSqrtM00 = Math.Sqrt(Math.Abs(invM00)); 62 | var s2 = invM00 * invM00; 63 | var s3 = s2 * invSqrtM00; 64 | 65 | Nu20 = Mu20 * s2; 66 | Nu11 = Mu11 * s2; 67 | Nu02 = Mu02 * s2; 68 | Nu30 = Mu30 * s3; 69 | Nu21 = Mu21 * s3; 70 | Nu12 = Mu12 * s3; 71 | Nu03 = Mu03 * s3; 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/SharpCV/Vectors/VectorOfByte.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Runtime.InteropServices; 5 | 6 | namespace SharpCV 7 | { 8 | /// 9 | /// 10 | public class VectorOfByte : DisposableObject, IStdVector 11 | { 12 | /// 13 | /// Constructor 14 | /// 15 | public VectorOfByte() 16 | { 17 | _handle = cv2_native_api.vector_uchar_new1(); 18 | } 19 | 20 | /// 21 | /// Constructor 22 | /// 23 | /// 24 | public VectorOfByte(nuint size) 25 | { 26 | if (size < 0) 27 | throw new ArgumentOutOfRangeException(nameof(size)); 28 | _handle = cv2_native_api.vector_uchar_new2(size); 29 | } 30 | 31 | /// 32 | /// Constructor 33 | /// 34 | /// 35 | public VectorOfByte(IEnumerable data) 36 | { 37 | if (data == null) 38 | throw new ArgumentNullException(nameof(data)); 39 | var array = data.ToArray(); 40 | _handle = cv2_native_api.vector_uchar_new3(array, (nuint)array.Length); 41 | } 42 | 43 | /// 44 | /// Releases unmanaged resources 45 | /// 46 | protected override void FreeHandle() 47 | { 48 | cv2_native_api.vector_uchar_delete(_handle); 49 | //base.DisposeUnmanaged(); 50 | } 51 | 52 | public IntPtr Handle => _handle; 53 | 54 | /// 55 | /// vector.size() 56 | /// 57 | public int Size 58 | { 59 | get 60 | { 61 | var res = cv2_native_api.vector_uchar_getSize(_handle); 62 | GC.KeepAlive(this); 63 | return (int)res; 64 | } 65 | } 66 | 67 | /// 68 | /// &vector[0] 69 | /// 70 | public IntPtr ElemPtr 71 | { 72 | get 73 | { 74 | var res = cv2_native_api.vector_uchar_getPointer(_handle); 75 | GC.KeepAlive(this); 76 | return res; 77 | } 78 | } 79 | 80 | /// 81 | /// Converts std::vector to managed array 82 | /// 83 | /// 84 | public byte[] ToArray() 85 | { 86 | var size = Size; 87 | if (size == 0) 88 | { 89 | return Array.Empty(); 90 | } 91 | var dst = new byte[size]; 92 | Marshal.Copy(ElemPtr, dst, 0, dst.Length); 93 | GC.KeepAlive(this); // ElemPtr is IntPtr to memory held by this object, so 94 | // make sure we are not disposed until finished with copy. 95 | return dst; 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/SharpCV.Examples/Program.cs: -------------------------------------------------------------------------------- 1 | using SharpCV; 2 | using System; 3 | using System.IO; 4 | using static SharpCV.Binding; 5 | 6 | namespace AppConsole 7 | { 8 | class Program 9 | { 10 | static void Main(string[] args) 11 | { 12 | string dataDir = Path.GetFullPath("../../../../../data"); 13 | /*string file = Path.GetFullPath("/solar.jpg"); 14 | var temp = cv2.imread(file); 15 | 16 | var img = cv2.imread(file); 17 | 18 | var cropped1 = cv2.imcrop(img, (150, 50, 200, 350)); 19 | cv2.imwrite("cropped1.jpg", cropped1); 20 | var cropped2 = img[(50, 400), (150, 350)]; 21 | cv2.imwrite("cropped2.jpg", cropped2);*/ 22 | 23 | // remove border 24 | var image = cv2.imread(Path.Combine(dataDir, "invoice.jpg")); 25 | var gray = cv2.cvtColor(image, ColorConversionCodes.COLOR_BGR2GRAY); 26 | var (_, thresh) = cv2.threshold(gray, 0, 255, ThresholdTypes.THRESH_BINARY_INV | ThresholdTypes.THRESH_OTSU); 27 | 28 | // Remove horizontal lines 29 | var horizontal_kernel = cv2.getStructuringElement(MorphShapes.MORPH_RECT, (20, 1)); 30 | var remove_horizontal = cv2.morphologyEx(thresh, MorphTypes.MORPH_OPEN, horizontal_kernel, iterations: 2); 31 | var cnts = cv2.findContoursAsPoints(remove_horizontal, RetrievalModes.RETR_EXTERNAL, ContourApproximationModes.CHAIN_APPROX_SIMPLE); 32 | foreach (var c in cnts) 33 | cv2.drawContours(image, new[] { c }, -1, (255, 255, 255), 5); 34 | 35 | // remove vertical border 36 | var vertical_kernel = cv2.getStructuringElement(MorphShapes.MORPH_RECT, (1, 20)); 37 | var remove_vertical = cv2.morphologyEx(thresh, MorphTypes.MORPH_OPEN, vertical_kernel, iterations: 2); 38 | cnts = cv2.findContoursAsPoints(remove_vertical, RetrievalModes.RETR_EXTERNAL, ContourApproximationModes.CHAIN_APPROX_SIMPLE); 39 | foreach (var c in cnts) 40 | cv2.drawContours(image, new[] { c }, -1, (255, 255, 255), 5); 41 | 42 | cv2.imwrite("result-sharpcv.png", image); 43 | 44 | /*for (var i =0; i < 3; i++) 45 | { 46 | temp = cv2.pyrDown(temp); 47 | cv2.imshow("a", temp); 48 | cv2.waitKey(0); 49 | }*/ 50 | 51 | // GC will dispose automatically 52 | /*for (int i = 0; i < 10000; i++) 53 | { 54 | using var img = cv2.imread(file); 55 | }*/ 56 | 57 | Console.WriteLine("Completed"); 58 | Console.ReadLine(); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/SharpCV/NativeAPIs/enum/cv2_native_api.VideoCaptureAPIs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | using System.Text; 5 | 6 | namespace SharpCV 7 | { 8 | /// 9 | /// modules\videoio\include\opencv2\videoio.hpp 10 | /// 11 | public enum VideoCaptureAPIs 12 | { 13 | CAP_ANY = 0, //!< Auto detect == 0 14 | CAP_VFW = 200, //!< Video For Windows (obsolete, removed) 15 | CAP_V4L = 200, //!< V4L/V4L2 capturing support 16 | CAP_V4L2 = CAP_V4L, //!< Same as CAP_V4L 17 | CAP_FIREWIRE = 300, //!< IEEE 1394 drivers 18 | CAP_FIREWARE = CAP_FIREWIRE, //!< Same value as CAP_FIREWIRE 19 | CAP_IEEE1394 = CAP_FIREWIRE, //!< Same value as CAP_FIREWIRE 20 | CAP_DC1394 = CAP_FIREWIRE, //!< Same value as CAP_FIREWIRE 21 | CAP_CMU1394 = CAP_FIREWIRE, //!< Same value as CAP_FIREWIRE 22 | CAP_QT = 500, //!< QuickTime (obsolete, removed) 23 | CAP_UNICAP = 600, //!< Unicap drivers (obsolete, removed) 24 | CAP_DSHOW = 700, //!< DirectShow (via videoInput) 25 | CAP_PVAPI = 800, //!< PvAPI, Prosilica GigE SDK 26 | CAP_OPENNI = 900, //!< OpenNI (for Kinect) 27 | CAP_OPENNI_ASUS = 910, //!< OpenNI (for Asus Xtion) 28 | CAP_ANDROID = 1000, //!< Android - not used 29 | CAP_XIAPI = 1100, //!< XIMEA Camera API 30 | CAP_AVFOUNDATION = 1200, //!< AVFoundation framework for iOS (OS X Lion will have the same API) 31 | CAP_GIGANETIX = 1300, //!< Smartek Giganetix GigEVisionSDK 32 | CAP_MSMF = 1400, //!< Microsoft Media Foundation (via videoInput) 33 | CAP_WINRT = 1410, //!< Microsoft Windows Runtime using Media Foundation 34 | CAP_INTELPERC = 1500, //!< RealSense (former Intel Perceptual Computing SDK) 35 | CAP_REALSENSE = 1500, //!< Synonym for CAP_INTELPERC 36 | CAP_OPENNI2 = 1600, //!< OpenNI2 (for Kinect) 37 | CAP_OPENNI2_ASUS = 1610, //!< OpenNI2 (for Asus Xtion and Occipital Structure sensors) 38 | CAP_GPHOTO2 = 1700, //!< gPhoto2 connection 39 | CAP_GSTREAMER = 1800, //!< GStreamer 40 | CAP_FFMPEG = 1900, //!< Open and record video file or stream using the FFMPEG library 41 | CAP_IMAGES = 2000, //!< OpenCV Image Sequence (e.g. img_%02d.jpg) 42 | CAP_ARAVIS = 2100, //!< Aravis SDK 43 | CAP_OPENCV_MJPEG = 2200, //!< Built-in OpenCV MotionJPEG codec 44 | CAP_INTEL_MFX = 2300, //!< Intel MediaSDK 45 | CAP_XINE = 2400, //!< XINE engine (Linux) 46 | }; 47 | } 48 | -------------------------------------------------------------------------------- /src/SharpCV/Core/Mat.Creation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using Tensorflow; 5 | using Tensorflow.NumPy; 6 | 7 | namespace SharpCV 8 | { 9 | public partial class Mat 10 | { 11 | public Mat() 12 | { 13 | cv2_native_api.core_Mat_new1(out _handle); 14 | } 15 | 16 | public Mat(IntPtr handle) 17 | { 18 | _handle = handle; 19 | } 20 | 21 | public unsafe Mat(NDArray nd) 22 | { 23 | switch (nd.ndim) 24 | { 25 | case 2: 26 | cv2_native_api.core_Mat_new8((int)nd.shape[0], (int)nd.shape[1], FromType(nd.dtype), nd.data, new IntPtr(0), out _handle); 27 | break; 28 | default: 29 | throw new NotImplementedException("Not supported"); 30 | } 31 | } 32 | 33 | //this method copies Mat to a new NDArray 34 | private unsafe NDArray CopyToNDArray() 35 | { 36 | cv2_native_api.core_Mat_cols(_handle, out var width); 37 | cv2_native_api.core_Mat_rows(_handle, out var height); 38 | cv2_native_api.core_Mat_data(_handle, out byte* data); 39 | 40 | /*var nd = new NDArray(NPTypeCode.Byte, (1, height, width, type), fillZeros: false); 41 | new UnmanagedMemoryBlock(data, nd.size) 42 | .CopyTo(nd.Unsafe.Address); 43 | 44 | return nd;*/ 45 | // return new NDArray(np.@byte); 46 | throw new NotImplementedException(""); 47 | } 48 | 49 | //this method wraps without copying Mat. 50 | private unsafe NDArray WrapWithNDArray() 51 | { 52 | cv2_native_api.core_Mat_cols(_handle, out var width); 53 | cv2_native_api.core_Mat_rows(_handle, out var height); 54 | cv2_native_api.core_Mat_channels(_handle, out var channels); 55 | 56 | Shape shape = (height, width, channels); 57 | 58 | // we pass donothing as it keeps reference to src preventing its disposal by GC 59 | switch (dtype) 60 | { 61 | case TF_DataType.TF_FLOAT: 62 | { 63 | cv2_native_api.core_Mat_data(_handle, out float* dataPtr); 64 | dtype = TF_DataType.TF_FLOAT; 65 | return new NDArray(new IntPtr(dataPtr), shape, dtype); 66 | } 67 | default: 68 | { 69 | cv2_native_api.core_Mat_data(_handle, out byte* dataPtr); 70 | dtype = TF_DataType.TF_UINT8; 71 | return new NDArray(new IntPtr(dataPtr), shape, dtype); 72 | } 73 | } 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /data/mnist_image_5.txt: -------------------------------------------------------------------------------- 1 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.011764706 0.07058824 0.07058824 0.07058824 0.49411765 0.53333336 0.6862745 0.101960786 0.6509804 1 0.96862745 0.49803922 0 0 0 0 0 0 0 0 0 0 0 0 0.11764706 0.14117648 0.36862746 0.6039216 0.6666667 0.99215686 0.99215686 0.99215686 0.99215686 0.99215686 0.88235295 0.6745098 0.99215686 0.9490196 0.7647059 0.2509804 0 0 0 0 0 0 0 0 0 0 0 0.19215687 0.93333334 0.99215686 0.99215686 0.99215686 0.99215686 0.99215686 0.99215686 0.99215686 0.99215686 0.9843137 0.3647059 0.32156864 0.32156864 0.21960784 0.15294118 0 0 0 0 0 0 0 0 0 0 0 0 0.07058824 0.85882354 0.99215686 0.99215686 0.99215686 0.99215686 0.99215686 0.7764706 0.7137255 0.96862745 0.94509804 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.3137255 0.6117647 0.41960785 0.99215686 0.99215686 0.8039216 0.043137256 0 0.16862746 0.6039216 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.05490196 0.003921569 0.6039216 0.99215686 0.3529412 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.54509807 0.99215686 0.74509805 0.007843138 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.043137256 0.74509805 0.99215686 0.27450982 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.13725491 0.94509804 0.88235295 0.627451 0.42352942 0.003921569 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.31764707 0.9411765 0.99215686 0.99215686 0.46666667 0.09803922 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1764706 0.7294118 0.99215686 0.99215686 0.5882353 0.105882354 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0627451 0.3647059 0.9882353 0.99215686 0.73333335 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.9764706 0.99215686 0.9764706 0.2509804 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.18039216 0.50980395 0.7176471 0.99215686 0.99215686 0.8117647 0.007843138 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15294118 0.5803922 0.8980392 0.99215686 0.99215686 0.99215686 0.98039216 0.7137255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.09411765 0.44705883 0.8666667 0.99215686 0.99215686 0.99215686 0.99215686 0.7882353 0.30588236 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.09019608 0.25882354 0.8352941 0.99215686 0.99215686 0.99215686 0.99215686 0.7764706 0.31764707 0.007843138 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.07058824 0.67058825 0.85882354 0.99215686 0.99215686 0.99215686 0.99215686 0.7647059 0.3137255 0.03529412 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.21568628 0.6745098 0.8862745 0.99215686 0.99215686 0.99215686 0.99215686 0.95686275 0.52156866 0.043137256 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.53333336 0.99215686 0.99215686 0.99215686 0.83137256 0.5294118 0.5176471 0.0627451 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -------------------------------------------------------------------------------- /test/UnitTest/CorrectImageTest.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using SharpCV; 3 | using System; 4 | using static SharpCV.Binding; 5 | 6 | 7 | namespace UnitTest 8 | { 9 | [TestClass] 10 | public class CorrectImageTest : Test 11 | { 12 | 13 | public Mat imread() 14 | { 15 | var img = cv2.imread(UncorrectedImage); 16 | //Assert.AreEqual(1760094, img.size); 17 | //Assert.AreEqual((854, 687, 3), img.shape); 18 | var gray = cv2.cvtColor(img, ColorConversionCodes.COLOR_RGB2GRAY); 19 | return gray; 20 | } 21 | 22 | public void imwrite(Mat img) 23 | { 24 | var result = cv2.imwrite("CorrectedImage.png", img); 25 | Assert.IsTrue(result); 26 | } 27 | 28 | [TestMethod] 29 | public void correctImage() 30 | { 31 | Mat img = imread(); 32 | var angle = findAngle(img); 33 | Mat correctedImage = new Mat(); 34 | var center = ((int)img.shape[0] / 2, (int)img.shape[1] / 2); 35 | correctedImage = cv2.rotate(img, center, angle, 1.0, InterpolationFlags.INTER_LINEAR, BorderTypes.BORDER_DEFAULT); 36 | imwrite(correctedImage); 37 | } 38 | 39 | public float findAngle(Mat img) 40 | { 41 | float angle = 0; 42 | var (_, thresh) = cv2.threshold(img, 0, 255, ThresholdTypes.THRESH_BINARY_INV | ThresholdTypes.THRESH_OTSU); 43 | var dilate_kernel = cv2.getStructuringElement(MorphShapes.MORPH_RECT, (3, 3)); 44 | var dilate = cv2.morphologyEx(thresh, MorphTypes.MORPH_DILATE, dilate_kernel, iterations: 2); 45 | 46 | //var cnts = cv2.findContoursAsPoints(dilate, RetrievalModes.RETR_EXTERNAL, ContourApproximationModes.CHAIN_APPROX_NONE); 47 | //Point[] max_contour = new Point[] { }; 48 | //foreach (var c in cnts)//TODO: use length filter here,but area filter is better 49 | // if (c.Length > max_contour.Length) max_contour = c; 50 | var (cnts, _) = cv2.findContours(dilate, RetrievalModes.RETR_EXTERNAL, ContourApproximationModes.CHAIN_APPROX_NONE); 51 | Mat max_contour = new Mat(); 52 | foreach (var c in cnts)//TODO: use length filter here,but area filter is better 53 | if (c.size > max_contour.size) max_contour = c; 54 | 55 | Mat contours_poly = cv2.approxPolyDP(max_contour, 30, true); 56 | RotatedRect rotatedRect = cv2.minAreaRect(contours_poly); 57 | angle = rotatedRect.Angle; 58 | if (Math.Abs(angle) > 45.0) 59 | angle = 90.0f + rotatedRect.Angle; 60 | 61 | //var color = cv2.cvtColor(img, ColorConversionCodes.COLOR_GRAY2RGB); 62 | //cv2.drawContours(color, new[] { max_contour }, -1, (255, 0, 0), 5); 63 | //cv2.imwrite("test1.jpg", color); 64 | 65 | return angle; 66 | } 67 | 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/SharpCV/APIs/cv2.imgcodecs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | using System.Text; 5 | 6 | namespace SharpCV 7 | { 8 | public partial class cv_api 9 | { 10 | public Mat imread(string filename, IMREAD_COLOR flags = IMREAD_COLOR.IMREAD_COLOR) 11 | { 12 | cv2_native_api.imgcodecs_imread(filename, (int)flags, out var handle); 13 | return new Mat(handle); 14 | } 15 | 16 | public bool imwrite(string filename, Mat img, params int[] @params) 17 | { 18 | cv2_native_api.imgcodecs_imwrite(filename, img, @params, @params.Length, out var output); 19 | return output != 0; 20 | } 21 | 22 | public Mat imcrop(Mat src, Rect rect) 23 | { 24 | cv2_native_api.core_Mat_new7(src, rect, out var handle); 25 | return new Mat(handle); 26 | } 27 | 28 | /// 29 | /// Reads image from the specified buffer in memory. 30 | /// 31 | /// The input slice of bytes. 32 | /// The same flags as in imread 33 | /// 34 | public static Mat ImDecode(byte[] span, IMREAD_COLOR flags = IMREAD_COLOR.IMREAD_COLOR) 35 | { 36 | if (span.Length == 0) 37 | throw new ArgumentException("Empty span", nameof(span)); 38 | 39 | unsafe 40 | { 41 | fixed (byte* pBuf = span) 42 | { 43 | cv2_native_api.imgcodecs_imdecode_vector(pBuf, span.Length, flags, out var ret); 44 | return new Mat(ret); 45 | } 46 | } 47 | } 48 | 49 | /// 50 | /// Compresses the image and stores it in the memory buffer 51 | /// 52 | /// The file extension that defines the output format 53 | /// The image to be written 54 | /// Output buffer resized to fit the compressed image. 55 | /// Format-specific parameters. 56 | public static bool ImEncode(string ext, Mat img, out byte[] buf, int[]? prms = null) 57 | { 58 | if (string.IsNullOrEmpty(ext)) 59 | throw new ArgumentNullException(nameof(ext)); 60 | if (img == null) 61 | throw new ArgumentNullException(nameof(img)); 62 | if (prms == null) 63 | prms = Array.Empty(); 64 | //img.ThrowIfDisposed(); 65 | 66 | using var bufVec = new VectorOfByte(); 67 | var exe_result = 68 | cv2_native_api.imgcodecs_imencode_vector(ext, img.OutputArray, bufVec.Handle, prms, prms.Length, out var ret); 69 | GC.KeepAlive(img); 70 | 71 | buf = bufVec.ToArray(); 72 | 73 | return ret != 0; 74 | } 75 | 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /test/UnitTest/CoreTest.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using SharpCV; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | using static SharpCV.Binding; 7 | using Tensorflow.NumPy; 8 | using System.IO; 9 | using System.Linq; 10 | 11 | namespace UnitTest 12 | { 13 | [TestClass] 14 | public class CoreTest : Test 15 | { 16 | [TestMethod] 17 | public void pixel_getter() 18 | { 19 | // getter 20 | var img1 = cv2.imread(imgSolar); 21 | var (b, g, r) = img1[8, 8]; 22 | Assert.AreEqual((32, 19, 11), (b, g, r)); 23 | 24 | // access specific channel 25 | b = img1[8, 8, 0]; 26 | g = img1[8, 8, 1]; 27 | r = img1[8, 8, 2]; 28 | Assert.AreEqual((32, 19, 11), (b, g, r)); 29 | 30 | var img2 = cv2.imread(imgSolar, IMREAD_COLOR.IMREAD_GRAYSCALE); 31 | byte p = img2[8, 8]; 32 | Assert.AreEqual(18, p); 33 | } 34 | 35 | [TestMethod] 36 | public void pixel_setter() 37 | { 38 | var img = cv2.imread(imgSolar); 39 | // img[8, 8] = (0, 0, 255); 40 | } 41 | 42 | [TestMethod] 43 | public void hconcat() 44 | { 45 | var img = cv2.imread(imgSolar); 46 | var hconcated = cv2.hconcat(img, img); 47 | Assert.AreEqual(410, hconcated.shape[0]); 48 | Assert.AreEqual(1460, hconcated.shape[1]); 49 | Assert.AreEqual(3, hconcated.shape[2]); 50 | } 51 | 52 | [TestMethod] 53 | public void vconcat() 54 | { 55 | var img = cv2.imread(imgSolar); 56 | var hconcated = cv2.vconcat(img, img); 57 | Assert.AreEqual(820, hconcated.shape[0]); 58 | Assert.AreEqual(730, hconcated.shape[1]); 59 | Assert.AreEqual(3, hconcated.shape[2]); 60 | } 61 | 62 | [TestMethod] 63 | public void rotate() 64 | { 65 | var img = cv2.imread(imgSolar); 66 | var rotated = cv2.rotate(img, RotateFlags.ROTATE_90_CLOCKWISE); 67 | Assert.AreEqual(730, rotated.shape[0]); 68 | Assert.AreEqual(410, rotated.shape[1]); 69 | Assert.AreEqual(3, rotated.shape[2]); 70 | } 71 | 72 | [TestMethod] 73 | public void flip() 74 | { 75 | var img = cv2.imread(imgSolar); 76 | var flipped = cv2.flip(img, FLIP_MODE.FLIP_HORIZONTAL_MODE); 77 | Assert.AreEqual(410, flipped.shape[0]); 78 | Assert.AreEqual(730, flipped.shape[1]); 79 | Assert.AreEqual(3, flipped.shape[2]); 80 | } 81 | 82 | [TestMethod] 83 | public void imshow_from_ndarray() 84 | { 85 | var mnist_image_5 = np.load(MNIST_Image_5); 86 | mnist_image_5 = mnist_image_5.reshape((28, 28)); 87 | //cv2.imshow("Show MNIST 5", mnist_image_5); 88 | //cv2.waitKey(0); 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/SharpCV/NativeAPIs/cv2_native_api.stdvector.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics.Contracts; 4 | using System.Runtime.InteropServices; 5 | using System.Text; 6 | 7 | namespace SharpCV 8 | { 9 | internal partial class cv2_native_api 10 | { 11 | #region uchar 12 | [Pure, DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] 13 | public static extern IntPtr vector_uchar_new1(); 14 | [Pure, DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] 15 | public static extern IntPtr vector_uchar_new2(nuint size); 16 | [Pure, DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] 17 | public static extern IntPtr vector_uchar_new3([In] byte[] data, nuint dataLength); 18 | [Pure, DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] 19 | public static extern nuint vector_uchar_getSize(IntPtr vector); 20 | [Pure, DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] 21 | public static extern IntPtr vector_uchar_getPointer(IntPtr vector); 22 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] 23 | public static extern void vector_uchar_copy(IntPtr vector, IntPtr dst); 24 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] 25 | public static extern void vector_uchar_delete(IntPtr vector); 26 | #endregion 27 | 28 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 29 | internal static extern IntPtr vector_vector_Point_new1(); 30 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 31 | internal static extern IntPtr vector_vector_Point_getSize1(IntPtr vector); 32 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 33 | internal static extern void vector_vector_Point_delete(IntPtr vector); 34 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 35 | internal static extern void vector_vector_Point_getSize2(IntPtr vector, [In, Out] IntPtr[] size); 36 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 37 | internal static extern void vector_vector_Point_copy(IntPtr vec, IntPtr[] dst); 38 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 39 | internal static extern IntPtr vector_Mat_new1(); 40 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 41 | internal static extern void vector_Mat_delete(IntPtr vector); 42 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 43 | internal static extern int vector_Mat_getSize(IntPtr vector); 44 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 45 | internal static extern void vector_Mat_assignToArray(IntPtr vector, IntPtr[] array); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /test/UnitTest/ImgProcTest.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using SharpCV; 3 | using System.IO; 4 | using static SharpCV.Binding; 5 | 6 | namespace UnitTest 7 | { 8 | [TestClass] 9 | public class ImgProcTest : Test 10 | { 11 | [TestMethod] 12 | public void cvtColor() 13 | { 14 | var img = cv2.imread(imgSolar); 15 | var gray = cv2.cvtColor(img, ColorConversionCodes.COLOR_RGB2GRAY); 16 | Assert.AreEqual(299300, gray.size); 17 | } 18 | 19 | [TestMethod] 20 | public void threshold() 21 | { 22 | var img = cv2.imread(imgSolar); 23 | var gray = cv2.cvtColor(img, ColorConversionCodes.COLOR_RGB2GRAY); 24 | var (ret, binary) = cv2.threshold(gray, 0, 255, ThresholdTypes.THRESH_BINARY | ThresholdTypes.THRESH_TRIANGLE); 25 | Assert.AreEqual(299300, binary.size); 26 | // python version is 80.0 27 | Assert.AreEqual(81, ret); 28 | } 29 | 30 | [TestMethod] 31 | public void adaptiveThreshold() 32 | { 33 | var img = cv2.imread(imgSolar); 34 | var gray = cv2.cvtColor(img, ColorConversionCodes.COLOR_RGB2GRAY); 35 | var binary = cv2.adaptiveThreshold(gray, 255, AdaptiveThresholdTypes.ADAPTIVE_THRESH_GAUSSIAN_C, ThresholdTypes.THRESH_BINARY, 25, 10); 36 | Assert.AreEqual(299300, binary.size); 37 | } 38 | 39 | [TestMethod] 40 | public void pyrDown() 41 | { 42 | var img = cv2.imread(imgSolar); 43 | var dst = cv2.pyrDown(img); 44 | } 45 | 46 | [TestMethod] 47 | public void pyrUp() 48 | { 49 | var img = cv2.imread(imgSolar); 50 | var dst = cv2.pyrUp(img); 51 | } 52 | 53 | [TestMethod] 54 | public void resize() 55 | { 56 | var img = cv2.imread(imgSolar); 57 | var r = 200.0 / img.shape[1]; 58 | var size = (200, (int)(img.shape[0] * r)); 59 | var resized = cv2.resize(img, size, interpolation: InterpolationFlags.INTER_AREA); 60 | Assert.AreEqual(112, resized.shape[0]); 61 | Assert.AreEqual(200, resized.shape[1]); 62 | Assert.AreEqual(3, resized.shape[2]); 63 | } 64 | 65 | [TestMethod] 66 | public void rotate() 67 | { 68 | var img = cv2.imread(imgSolar); 69 | var rotated = cv2.rotate(img, ((int)img.shape[1] / 2, (int)img.shape[0] / 2), 180, 1.0); 70 | Assert.AreEqual(410, rotated.shape[0]); 71 | Assert.AreEqual(730, rotated.shape[1]); 72 | Assert.AreEqual(3, rotated.shape[2]); 73 | } 74 | 75 | [TestMethod] 76 | public void rectangle() 77 | { 78 | var img = cv2.imread(imgSolar); 79 | cv2.rectangle(img, (0, 0), (img.shape[1] / 2, img.shape[0] / 2), (255, 0, 0)); 80 | cv2.imwrite("rectangle.jpg", img); 81 | } 82 | 83 | [TestMethod] 84 | public void minAreaRect() 85 | { 86 | var img = cv2.imread(imgSolar, IMREAD_COLOR.IMREAD_GRAYSCALE); 87 | var (ret, thresh) = cv2.threshold(img, 127, 255, 0); 88 | var (contours, hierarchy) = cv2.findContours(thresh, RetrievalModes.RETR_LIST, ContourApproximationModes.CHAIN_APPROX_SIMPLE); 89 | var cnt = contours[0]; 90 | var rect = cv2.minAreaRect(cnt); 91 | Assert.AreEqual(-90, rect.Angle); 92 | Assert.AreEqual((1, 1), rect.Size); 93 | Assert.AreEqual((367.5f, 408.5f), rect.Center); 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/SharpCV/NativeAPIs/enum/cv2_native_api.VideoCaptureProperties.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | using System.Text; 5 | 6 | namespace SharpCV 7 | { 8 | /// 9 | /// modules\videoio\include\opencv2\videoio.hpp 10 | /// 11 | public enum VideoCaptureProperties 12 | { 13 | CAP_PROP_POS_MSEC = 0, //!< Current position of the video file in milliseconds. 14 | CAP_PROP_POS_FRAMES = 1, //!< 0-based index of the frame to be decoded/captured next. 15 | CAP_PROP_POS_AVI_RATIO = 2, //!< Relative position of the video file: 0=start of the film, 1=end of the film. 16 | CAP_PROP_FRAME_WIDTH = 3, //!< Width of the frames in the video stream. 17 | CAP_PROP_FRAME_HEIGHT = 4, //!< Height of the frames in the video stream. 18 | CAP_PROP_FPS = 5, //!< Frame rate. 19 | CAP_PROP_FOURCC = 6, //!< 4-character code of codec. see VideoWriter::fourcc . 20 | CAP_PROP_FRAME_COUNT = 7, //!< Number of frames in the video file. 21 | CAP_PROP_FORMAT = 8, //!< Format of the %Mat objects (see Mat::type()) returned by VideoCapture::retrieve(). 22 | //!< Set value -1 to fetch undecoded RAW video streams (as Mat 8UC1). 23 | CAP_PROP_MODE = 9, //!< Backend-specific value indicating the current capture mode. 24 | CAP_PROP_BRIGHTNESS = 10, //!< Brightness of the image (only for those cameras that support). 25 | CAP_PROP_CONTRAST = 11, //!< Contrast of the image (only for cameras). 26 | CAP_PROP_SATURATION = 12, //!< Saturation of the image (only for cameras). 27 | CAP_PROP_HUE = 13, //!< Hue of the image (only for cameras). 28 | CAP_PROP_GAIN = 14, //!< Gain of the image (only for those cameras that support). 29 | CAP_PROP_EXPOSURE = 15, //!< Exposure (only for those cameras that support). 30 | CAP_PROP_CONVERT_RGB = 16, //!< Boolean flags indicating whether images should be converted to RGB. 31 | CAP_PROP_WHITE_BALANCE_BLUE_U = 17, //!< Currently unsupported. 32 | CAP_PROP_RECTIFICATION = 18, //!< Rectification flag for stereo cameras (note: only supported by DC1394 v 2.x backend currently). 33 | CAP_PROP_MONOCHROME = 19, 34 | CAP_PROP_SHARPNESS = 20, 35 | CAP_PROP_AUTO_EXPOSURE = 21, //!< DC1394: exposure control done by camera, user can adjust reference level using this feature. 36 | CAP_PROP_GAMMA = 22, 37 | CAP_PROP_TEMPERATURE = 23, 38 | CAP_PROP_TRIGGER = 24, 39 | CAP_PROP_TRIGGER_DELAY = 25, 40 | CAP_PROP_WHITE_BALANCE_RED_V = 26, 41 | CAP_PROP_ZOOM = 27, 42 | CAP_PROP_FOCUS = 28, 43 | CAP_PROP_GUID = 29, 44 | CAP_PROP_ISO_SPEED = 30, 45 | CAP_PROP_BACKLIGHT = 32, 46 | CAP_PROP_PAN = 33, 47 | CAP_PROP_TILT = 34, 48 | CAP_PROP_ROLL = 35, 49 | CAP_PROP_IRIS = 36, 50 | CAP_PROP_SETTINGS = 37, //!< Pop up video/camera filter dialog (note: only supported by DSHOW backend currently. The property value is ignored) 51 | CAP_PROP_BUFFERSIZE = 38, 52 | CAP_PROP_AUTOFOCUS = 39, 53 | CAP_PROP_SAR_NUM = 40, //!< Sample aspect ratio: num/den (num) 54 | CAP_PROP_SAR_DEN = 41, //!< Sample aspect ratio: num/den (den) 55 | CAP_PROP_BACKEND = 42, //!< Current backend (enum VideoCaptureAPIs). Read-only property 56 | CAP_PROP_CHANNEL = 43, //!< Video input or Channel Number (only for those cameras that support) 57 | CAP_PROP_AUTO_WB = 44, //!< enable/ disable auto white-balance 58 | CAP_PROP_WB_TEMPERATURE = 45, //!< white-balance color temperature 59 | CAP_PROP_CODEC_PIXEL_FORMAT = 46, //!< (read-only) codec's pixel format. 4-character code - see VideoWriter::fourcc . Subset of [AV_PIX_FMT_*](https://github.com/FFmpeg/FFmpeg/blob/master/libavcodec/raw.c) or -1 if unknown 60 | }; 61 | } 62 | -------------------------------------------------------------------------------- /SharpCV.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.4.33213.308 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTest", "test\UnitTest\UnitTest.csproj", "{91851135-0E0C-4B39-A057-DE8A510BA98F}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SharpCV.Examples", "src\SharpCV.Examples\SharpCV.Examples.csproj", "{116F9A46-51E1-44D5-B780-15CE5458C5D7}" 9 | EndProject 10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SharpCV", "src\SharpCV\SharpCV.csproj", "{3EACFB88-65CC-43A4-B21A-949475694341}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Debug|x64 = Debug|x64 16 | Debug|x86 = Debug|x86 17 | Release|Any CPU = Release|Any CPU 18 | Release|x64 = Release|x64 19 | Release|x86 = Release|x86 20 | EndGlobalSection 21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 22 | {91851135-0E0C-4B39-A057-DE8A510BA98F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {91851135-0E0C-4B39-A057-DE8A510BA98F}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {91851135-0E0C-4B39-A057-DE8A510BA98F}.Debug|x64.ActiveCfg = Debug|x64 25 | {91851135-0E0C-4B39-A057-DE8A510BA98F}.Debug|x64.Build.0 = Debug|x64 26 | {91851135-0E0C-4B39-A057-DE8A510BA98F}.Debug|x86.ActiveCfg = Debug|Any CPU 27 | {91851135-0E0C-4B39-A057-DE8A510BA98F}.Debug|x86.Build.0 = Debug|Any CPU 28 | {91851135-0E0C-4B39-A057-DE8A510BA98F}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {91851135-0E0C-4B39-A057-DE8A510BA98F}.Release|Any CPU.Build.0 = Release|Any CPU 30 | {91851135-0E0C-4B39-A057-DE8A510BA98F}.Release|x64.ActiveCfg = Release|Any CPU 31 | {91851135-0E0C-4B39-A057-DE8A510BA98F}.Release|x64.Build.0 = Release|Any CPU 32 | {91851135-0E0C-4B39-A057-DE8A510BA98F}.Release|x86.ActiveCfg = Release|Any CPU 33 | {91851135-0E0C-4B39-A057-DE8A510BA98F}.Release|x86.Build.0 = Release|Any CPU 34 | {116F9A46-51E1-44D5-B780-15CE5458C5D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 35 | {116F9A46-51E1-44D5-B780-15CE5458C5D7}.Debug|Any CPU.Build.0 = Debug|Any CPU 36 | {116F9A46-51E1-44D5-B780-15CE5458C5D7}.Debug|x64.ActiveCfg = Debug|x64 37 | {116F9A46-51E1-44D5-B780-15CE5458C5D7}.Debug|x64.Build.0 = Debug|x64 38 | {116F9A46-51E1-44D5-B780-15CE5458C5D7}.Debug|x86.ActiveCfg = Debug|Any CPU 39 | {116F9A46-51E1-44D5-B780-15CE5458C5D7}.Debug|x86.Build.0 = Debug|Any CPU 40 | {116F9A46-51E1-44D5-B780-15CE5458C5D7}.Release|Any CPU.ActiveCfg = Release|Any CPU 41 | {116F9A46-51E1-44D5-B780-15CE5458C5D7}.Release|Any CPU.Build.0 = Release|Any CPU 42 | {116F9A46-51E1-44D5-B780-15CE5458C5D7}.Release|x64.ActiveCfg = Release|Any CPU 43 | {116F9A46-51E1-44D5-B780-15CE5458C5D7}.Release|x64.Build.0 = Release|Any CPU 44 | {116F9A46-51E1-44D5-B780-15CE5458C5D7}.Release|x86.ActiveCfg = Release|Any CPU 45 | {116F9A46-51E1-44D5-B780-15CE5458C5D7}.Release|x86.Build.0 = Release|Any CPU 46 | {3EACFB88-65CC-43A4-B21A-949475694341}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 47 | {3EACFB88-65CC-43A4-B21A-949475694341}.Debug|Any CPU.Build.0 = Debug|Any CPU 48 | {3EACFB88-65CC-43A4-B21A-949475694341}.Debug|x64.ActiveCfg = Debug|x64 49 | {3EACFB88-65CC-43A4-B21A-949475694341}.Debug|x64.Build.0 = Debug|x64 50 | {3EACFB88-65CC-43A4-B21A-949475694341}.Debug|x86.ActiveCfg = Debug|Any CPU 51 | {3EACFB88-65CC-43A4-B21A-949475694341}.Debug|x86.Build.0 = Debug|Any CPU 52 | {3EACFB88-65CC-43A4-B21A-949475694341}.Release|Any CPU.ActiveCfg = Release|Any CPU 53 | {3EACFB88-65CC-43A4-B21A-949475694341}.Release|Any CPU.Build.0 = Release|Any CPU 54 | {3EACFB88-65CC-43A4-B21A-949475694341}.Release|x64.ActiveCfg = Release|Any CPU 55 | {3EACFB88-65CC-43A4-B21A-949475694341}.Release|x64.Build.0 = Release|Any CPU 56 | {3EACFB88-65CC-43A4-B21A-949475694341}.Release|x86.ActiveCfg = Release|Any CPU 57 | {3EACFB88-65CC-43A4-B21A-949475694341}.Release|x86.Build.0 = Release|Any CPU 58 | EndGlobalSection 59 | GlobalSection(SolutionProperties) = preSolution 60 | HideSolutionNode = FALSE 61 | EndGlobalSection 62 | GlobalSection(ExtensibilityGlobals) = postSolution 63 | SolutionGuid = {4227A3A2-A554-4D2E-854D-5CB9F330DB72} 64 | EndGlobalSection 65 | EndGlobal 66 | -------------------------------------------------------------------------------- /src/SharpCV/NativeAPIs/cv2_native_api.core.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | using System.Text; 5 | 6 | namespace SharpCV 7 | { 8 | internal partial class cv2_native_api 9 | { 10 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 11 | internal static extern void core_Mat_new1(out IntPtr returnValue); 12 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 13 | internal static extern void core_Mat_new7(IntPtr mat, Rect rect, out IntPtr returnValue); 14 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 15 | internal static extern void core_Mat_new8(int rows, int cols, MatType type, IntPtr data, IntPtr step, out IntPtr returnValue); 16 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 17 | internal static extern void core_Mat_cols(IntPtr mat, out int output); 18 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 19 | internal static extern void core_Mat_rows(IntPtr mat, out int output); 20 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 21 | internal static extern void core_Mat_ptr2d(IntPtr mat, int row, int col, out IntPtr output); 22 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 23 | internal static extern void core_Mat_dims(IntPtr mat, out int output); 24 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 25 | internal static extern void core_Mat_sizeAt(IntPtr mat, int dim, out int output); 26 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 27 | internal static extern void core_Mat_type(IntPtr mat, out MatType output); 28 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 29 | internal static extern unsafe void core_Mat_data(IntPtr mat, out byte* output); 30 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 31 | internal static extern unsafe void core_Mat_data(IntPtr mat, out int* output); 32 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 33 | internal static extern unsafe void core_Mat_data(IntPtr mat, out float* output); 34 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 35 | internal static extern void core_Mat_channels(IntPtr mat, out int output); 36 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 37 | internal static extern void core_Mat_depth(IntPtr mat, out int output); 38 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 39 | internal static extern void core_Mat_delete(IntPtr mat); 40 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 41 | internal static extern void core_Mat_size(IntPtr mat, out Size output); 42 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 43 | internal static extern void core_Mat_elemSize(IntPtr mat, out int output); 44 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 45 | internal static extern void core_InputArray_new_byMat(IntPtr mat, out IntPtr output); 46 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 47 | internal static extern void core_OutputArray_new_byMat(IntPtr mat, out IntPtr output); 48 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 49 | internal static extern void core_rotate(IntPtr mat, IntPtr dst, int flags); 50 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 51 | internal static extern void core_flip(IntPtr mat, IntPtr dst, int mode); 52 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 53 | internal static extern void core_hconcat1([MarshalAs(UnmanagedType.LPArray)] IntPtr[] src, uint nsrc, IntPtr dst); 54 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 55 | internal static extern void core_vconcat1([MarshalAs(UnmanagedType.LPArray)] IntPtr[] src, uint nsrc, IntPtr dst); 56 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 57 | internal static extern void core_hconcat2(IntPtr mat1, IntPtr mat2, IntPtr dst); 58 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 59 | internal static extern void core_split(IntPtr src, IntPtr mv); 60 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 61 | internal static extern void core_vconcat2(IntPtr mat1, IntPtr mat2, IntPtr dst); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/SharpCV/NativeAPIs/cv2_native_api.imgproc.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Numerics; 4 | using System.Runtime.InteropServices; 5 | using System.Text; 6 | 7 | namespace SharpCV 8 | { 9 | internal partial class cv2_native_api 10 | { 11 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 12 | internal static extern void imgproc_cvtColor(IntPtr src, IntPtr dst, int code, int dstCnt); 13 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 14 | internal static extern void imgproc_contourArea_InputArray(IntPtr contour, int oriented, out double output); 15 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 16 | internal static extern void imgproc_threshold(IntPtr src, IntPtr dst, double thresh, double maxval, int type, out double output); 17 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 18 | internal static extern void imgproc_resize(IntPtr src, IntPtr dst, Size dsize, double fx, double fy, int interpolation); 19 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 20 | internal static extern void imgproc_getRotationMatrix2D(Point center, double angle, double scale, out IntPtr output); 21 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 22 | internal static extern void imgproc_warpAffine(IntPtr src, IntPtr dst, IntPtr m, Size dsize, int flags, int borderMode, Scalar borderValue); 23 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 24 | internal static extern void imgproc_adaptiveThreshold(IntPtr src, IntPtr dst, double maxValue, int method, int type, int blockSize, double delta); 25 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 26 | internal static extern void imgproc_pyrUp(IntPtr src, IntPtr dst, Size dstsize, int borderType); 27 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 28 | internal static extern void imgproc_pyrDown(IntPtr src, IntPtr dst, Size dstsize, int borderType); 29 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 30 | internal static extern void imgproc_calcBackProject(IntPtr[] images, int nimages, int[] channels, IntPtr hist, IntPtr backProject, IntPtr[] ranges, int uniform); 31 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 32 | internal static extern void imgproc_rectangle_InputOutputArray_Point(IntPtr img, Point pt1, Point pt2, Scalar color, int thickness, LineTypes lineType, int shift); 33 | 34 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl, BestFitMapping = false, ThrowOnUnmappableChar = true)] 35 | public static extern void imgproc_putText(IntPtr img, string text, Point org, 36 | int fontFace, double fontScale, Scalar color, 37 | int thickness, int lineType, int bottomLeftOrigin); 38 | 39 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl, BestFitMapping = false, ThrowOnUnmappableChar = true)] 40 | internal static extern void imgproc_getTextSize(string text, int fontFace, 41 | double fontScale, int thickness, out int baseLine, out Size returnValue); 42 | 43 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 44 | internal static extern void imgproc_getStructuringElement(int shape, Size ksize, Point anchor, out IntPtr output); 45 | 46 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 47 | internal static extern void imgproc_morphologyEx(IntPtr src, IntPtr dst, int op, IntPtr kernel, Point anchor, 48 | int iterations, int borderType, Scalar borderValue); 49 | 50 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 51 | internal static extern void imgproc_findContours1_vector(IntPtr image, out IntPtr contours, 52 | out IntPtr hierarchy, int mode, int method, Point offset); 53 | 54 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 55 | internal static extern void imgproc_findContours1_OutputArray(IntPtr image, out IntPtr contours, 56 | IntPtr hierarchy, int mode, int method, Point offset); 57 | 58 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 59 | internal static extern void imgproc_drawContours_vector(IntPtr image, 60 | IntPtr[] contours, int contoursSize1, int[] contoursSize2, 61 | int contourIdx, Scalar color, int thickness, int lineType, 62 | IntPtr hierarchy, int hiearchyLength, int maxLevel, Point offset); 63 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 64 | public static extern void imgproc_drawContours_InputArray(IntPtr image, 65 | IntPtr[] contours, int contoursLength, 66 | int contourIdx, Scalar color, int thickness, LineTypes lineType, 67 | IntPtr hierarchy, int maxLevel, Point offset); 68 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 69 | internal static extern void imgproc_approxPolyDP_InputArray(IntPtr curve, IntPtr approxCurve, 70 | double epsilon, bool closed); 71 | 72 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 73 | internal static extern void imgproc_minAreaRect_InputArray(IntPtr points, out RotatedRect output); 74 | 75 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 76 | internal static extern void imgproc_moments(IntPtr arr, int binaryImage, out Moments.NativeStruct output); 77 | 78 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 79 | internal static extern void imgproc_medianBlur(IntPtr src, IntPtr dst, int kSize); 80 | 81 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 82 | internal static extern void imgproc_filter2D(IntPtr src, IntPtr dst, MatType ddepth, IntPtr kernel, Point anchor, 83 | double delta, BorderTypes borderType); 84 | 85 | [DllImport(OpenCvDllName, CallingConvention = CallingConvention.Cdecl)] 86 | internal static extern void imgproc_blur(IntPtr src, IntPtr dst, Size kSize, Point anchor, BorderTypes borderType); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Aa][Rr][Mm]/ 27 | [Aa][Rr][Mm]64/ 28 | bld/ 29 | [Bb]in/ 30 | [Oo]bj/ 31 | [Ll]og/ 32 | [Ll]ogs/ 33 | 34 | # Visual Studio 2015/2017 cache/options directory 35 | .vs/ 36 | # Uncomment if you have tasks that create the project's static files in wwwroot 37 | #wwwroot/ 38 | 39 | # Visual Studio 2017 auto generated files 40 | Generated\ Files/ 41 | 42 | # MSTest test Results 43 | [Tt]est[Rr]esult*/ 44 | [Bb]uild[Ll]og.* 45 | 46 | # NUnit 47 | *.VisualState.xml 48 | TestResult.xml 49 | nunit-*.xml 50 | 51 | # Build Results of an ATL Project 52 | [Dd]ebugPS/ 53 | [Rr]eleasePS/ 54 | dlldata.c 55 | 56 | # Benchmark Results 57 | BenchmarkDotNet.Artifacts/ 58 | 59 | # .NET Core 60 | project.lock.json 61 | project.fragment.lock.json 62 | artifacts/ 63 | 64 | # StyleCop 65 | StyleCopReport.xml 66 | 67 | # Files built by Visual Studio 68 | *_i.c 69 | *_p.c 70 | *_h.h 71 | *.ilk 72 | *.meta 73 | *.obj 74 | *.iobj 75 | *.pch 76 | *.pdb 77 | *.ipdb 78 | *.pgc 79 | *.pgd 80 | *.rsp 81 | *.sbr 82 | *.tlb 83 | *.tli 84 | *.tlh 85 | *.tmp 86 | *.tmp_proj 87 | *_wpftmp.csproj 88 | *.log 89 | *.vspscc 90 | *.vssscc 91 | .builds 92 | *.pidb 93 | *.svclog 94 | *.scc 95 | 96 | # Chutzpah Test files 97 | _Chutzpah* 98 | 99 | # Visual C++ cache files 100 | ipch/ 101 | *.aps 102 | *.ncb 103 | *.opendb 104 | *.opensdf 105 | *.sdf 106 | *.cachefile 107 | *.VC.db 108 | *.VC.VC.opendb 109 | 110 | # Visual Studio profiler 111 | *.psess 112 | *.vsp 113 | *.vspx 114 | *.sap 115 | 116 | # Visual Studio Trace Files 117 | *.e2e 118 | 119 | # TFS 2012 Local Workspace 120 | $tf/ 121 | 122 | # Guidance Automation Toolkit 123 | *.gpState 124 | 125 | # ReSharper is a .NET coding add-in 126 | _ReSharper*/ 127 | *.[Rr]e[Ss]harper 128 | *.DotSettings.user 129 | 130 | # TeamCity is a build add-in 131 | _TeamCity* 132 | 133 | # DotCover is a Code Coverage Tool 134 | *.dotCover 135 | 136 | # AxoCover is a Code Coverage Tool 137 | .axoCover/* 138 | !.axoCover/settings.json 139 | 140 | # Visual Studio code coverage results 141 | *.coverage 142 | *.coveragexml 143 | 144 | # NCrunch 145 | _NCrunch_* 146 | .*crunch*.local.xml 147 | nCrunchTemp_* 148 | 149 | # MightyMoose 150 | *.mm.* 151 | AutoTest.Net/ 152 | 153 | # Web workbench (sass) 154 | .sass-cache/ 155 | 156 | # Installshield output folder 157 | [Ee]xpress/ 158 | 159 | # DocProject is a documentation generator add-in 160 | DocProject/buildhelp/ 161 | DocProject/Help/*.HxT 162 | DocProject/Help/*.HxC 163 | DocProject/Help/*.hhc 164 | DocProject/Help/*.hhk 165 | DocProject/Help/*.hhp 166 | DocProject/Help/Html2 167 | DocProject/Help/html 168 | 169 | # Click-Once directory 170 | publish/ 171 | 172 | # Publish Web Output 173 | *.[Pp]ublish.xml 174 | *.azurePubxml 175 | # Note: Comment the next line if you want to checkin your web deploy settings, 176 | # but database connection strings (with potential passwords) will be unencrypted 177 | *.pubxml 178 | *.publishproj 179 | 180 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 181 | # checkin your Azure Web App publish settings, but sensitive information contained 182 | # in these scripts will be unencrypted 183 | PublishScripts/ 184 | 185 | # NuGet Packages 186 | *.nupkg 187 | # NuGet Symbol Packages 188 | *.snupkg 189 | # The packages folder can be ignored because of Package Restore 190 | **/[Pp]ackages/* 191 | # except build/, which is used as an MSBuild target. 192 | !**/[Pp]ackages/build/ 193 | # Uncomment if necessary however generally it will be regenerated when needed 194 | #!**/[Pp]ackages/repositories.config 195 | # NuGet v3's project.json files produces more ignorable files 196 | *.nuget.props 197 | *.nuget.targets 198 | 199 | # Microsoft Azure Build Output 200 | csx/ 201 | *.build.csdef 202 | 203 | # Microsoft Azure Emulator 204 | ecf/ 205 | rcf/ 206 | 207 | # Windows Store app package directories and files 208 | AppPackages/ 209 | BundleArtifacts/ 210 | Package.StoreAssociation.xml 211 | _pkginfo.txt 212 | *.appx 213 | *.appxbundle 214 | *.appxupload 215 | 216 | # Visual Studio cache files 217 | # files ending in .cache can be ignored 218 | *.[Cc]ache 219 | # but keep track of directories ending in .cache 220 | !?*.[Cc]ache/ 221 | 222 | # Others 223 | ClientBin/ 224 | ~$* 225 | *~ 226 | *.dbmdl 227 | *.dbproj.schemaview 228 | *.jfm 229 | *.pfx 230 | *.publishsettings 231 | orleans.codegen.cs 232 | 233 | # Including strong name files can present a security risk 234 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 235 | #*.snk 236 | 237 | # Since there are multiple workflows, uncomment next line to ignore bower_components 238 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 239 | #bower_components/ 240 | 241 | # RIA/Silverlight projects 242 | Generated_Code/ 243 | 244 | # Backup & report files from converting an old project file 245 | # to a newer Visual Studio version. Backup files are not needed, 246 | # because we have git ;-) 247 | _UpgradeReport_Files/ 248 | Backup*/ 249 | UpgradeLog*.XML 250 | UpgradeLog*.htm 251 | ServiceFabricBackup/ 252 | *.rptproj.bak 253 | 254 | # SQL Server files 255 | *.mdf 256 | *.ldf 257 | *.ndf 258 | 259 | # Business Intelligence projects 260 | *.rdl.data 261 | *.bim.layout 262 | *.bim_*.settings 263 | *.rptproj.rsuser 264 | *- [Bb]ackup.rdl 265 | *- [Bb]ackup ([0-9]).rdl 266 | *- [Bb]ackup ([0-9][0-9]).rdl 267 | 268 | # Microsoft Fakes 269 | FakesAssemblies/ 270 | 271 | # GhostDoc plugin setting file 272 | *.GhostDoc.xml 273 | 274 | # Node.js Tools for Visual Studio 275 | .ntvs_analysis.dat 276 | node_modules/ 277 | 278 | # Visual Studio 6 build log 279 | *.plg 280 | 281 | # Visual Studio 6 workspace options file 282 | *.opt 283 | 284 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 285 | *.vbw 286 | 287 | # Visual Studio LightSwitch build output 288 | **/*.HTMLClient/GeneratedArtifacts 289 | **/*.DesktopClient/GeneratedArtifacts 290 | **/*.DesktopClient/ModelManifest.xml 291 | **/*.Server/GeneratedArtifacts 292 | **/*.Server/ModelManifest.xml 293 | _Pvt_Extensions 294 | 295 | # Paket dependency manager 296 | .paket/paket.exe 297 | paket-files/ 298 | 299 | # FAKE - F# Make 300 | .fake/ 301 | 302 | # CodeRush personal settings 303 | .cr/personal 304 | 305 | # Python Tools for Visual Studio (PTVS) 306 | __pycache__/ 307 | *.pyc 308 | 309 | # Cake - Uncomment if you are using it 310 | # tools/** 311 | # !tools/packages.config 312 | 313 | # Tabs Studio 314 | *.tss 315 | 316 | # Telerik's JustMock configuration file 317 | *.jmconfig 318 | 319 | # BizTalk build output 320 | *.btp.cs 321 | *.btm.cs 322 | *.odx.cs 323 | *.xsd.cs 324 | 325 | # OpenCover UI analysis results 326 | OpenCover/ 327 | 328 | # Azure Stream Analytics local run output 329 | ASALocalRun/ 330 | 331 | # MSBuild Binary and Structured Log 332 | *.binlog 333 | 334 | # NVidia Nsight GPU debugger configuration file 335 | *.nvuser 336 | 337 | # MFractors (Xamarin productivity tool) working folder 338 | .mfractor/ 339 | 340 | # Local History for Visual Studio 341 | .localhistory/ 342 | 343 | # BeatPulse healthcheck temp database 344 | healthchecksdb 345 | 346 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 347 | MigrationBackup/ 348 | 349 | # Ionide (cross platform F# VS Code tools) working folder 350 | .ionide/ 351 | -------------------------------------------------------------------------------- /test/UnitTest/data/mnist_first_image_data.txt: -------------------------------------------------------------------------------- 1 | 0 2 | 0 3 | 0 4 | 0 5 | 0 6 | 0 7 | 0 8 | 0 9 | 0 10 | 0 11 | 0 12 | 0 13 | 0 14 | 0 15 | 0 16 | 0 17 | 0 18 | 0 19 | 0 20 | 0 21 | 0 22 | 0 23 | 0 24 | 0 25 | 0 26 | 0 27 | 0 28 | 0 29 | 0 30 | 0 31 | 0 32 | 0 33 | 0 34 | 0 35 | 0 36 | 0 37 | 0 38 | 0 39 | 0 40 | 0 41 | 0 42 | 0 43 | 0 44 | 0 45 | 0 46 | 0 47 | 0 48 | 0 49 | 0 50 | 0 51 | 0 52 | 0 53 | 0 54 | 0 55 | 0 56 | 0 57 | 0 58 | 0 59 | 0 60 | 0 61 | 0 62 | 0 63 | 0 64 | 0 65 | 0 66 | 0 67 | 0 68 | 0 69 | 0 70 | 0 71 | 0 72 | 0 73 | 0 74 | 0 75 | 0 76 | 0 77 | 0 78 | 0 79 | 0 80 | 0 81 | 0 82 | 0 83 | 0 84 | 0 85 | 0 86 | 0 87 | 0 88 | 0 89 | 0 90 | 0 91 | 0 92 | 0 93 | 0 94 | 0 95 | 0 96 | 0 97 | 0 98 | 0 99 | 0 100 | 0 101 | 0 102 | 0 103 | 0 104 | 0 105 | 0 106 | 0 107 | 0 108 | 0 109 | 0 110 | 0 111 | 0 112 | 0 113 | 0 114 | 0 115 | 0 116 | 0 117 | 0 118 | 0 119 | 0 120 | 0 121 | 0 122 | 0 123 | 0 124 | 0 125 | 0 126 | 0 127 | 0 128 | 0 129 | 0 130 | 0 131 | 0 132 | 0 133 | 0 134 | 0 135 | 0 136 | 0 137 | 0 138 | 0 139 | 0 140 | 0 141 | 0 142 | 0 143 | 0 144 | 0 145 | 0 146 | 0 147 | 0 148 | 0 149 | 0 150 | 0 151 | 0 152 | 0 153 | 0.011764706 154 | 0.07058824 155 | 0.07058824 156 | 0.07058824 157 | 0.49411765 158 | 0.53333336 159 | 0.6862745 160 | 0.101960786 161 | 0.6509804 162 | 1 163 | 0.96862745 164 | 0.49803922 165 | 0 166 | 0 167 | 0 168 | 0 169 | 0 170 | 0 171 | 0 172 | 0 173 | 0 174 | 0 175 | 0 176 | 0 177 | 0.11764706 178 | 0.14117648 179 | 0.36862746 180 | 0.6039216 181 | 0.6666667 182 | 0.99215686 183 | 0.99215686 184 | 0.99215686 185 | 0.99215686 186 | 0.99215686 187 | 0.88235295 188 | 0.6745098 189 | 0.99215686 190 | 0.9490196 191 | 0.7647059 192 | 0.2509804 193 | 0 194 | 0 195 | 0 196 | 0 197 | 0 198 | 0 199 | 0 200 | 0 201 | 0 202 | 0 203 | 0 204 | 0.19215687 205 | 0.93333334 206 | 0.99215686 207 | 0.99215686 208 | 0.99215686 209 | 0.99215686 210 | 0.99215686 211 | 0.99215686 212 | 0.99215686 213 | 0.99215686 214 | 0.9843137 215 | 0.3647059 216 | 0.32156864 217 | 0.32156864 218 | 0.21960784 219 | 0.15294118 220 | 0 221 | 0 222 | 0 223 | 0 224 | 0 225 | 0 226 | 0 227 | 0 228 | 0 229 | 0 230 | 0 231 | 0 232 | 0.07058824 233 | 0.85882354 234 | 0.99215686 235 | 0.99215686 236 | 0.99215686 237 | 0.99215686 238 | 0.99215686 239 | 0.7764706 240 | 0.7137255 241 | 0.96862745 242 | 0.94509804 243 | 0 244 | 0 245 | 0 246 | 0 247 | 0 248 | 0 249 | 0 250 | 0 251 | 0 252 | 0 253 | 0 254 | 0 255 | 0 256 | 0 257 | 0 258 | 0 259 | 0 260 | 0 261 | 0.3137255 262 | 0.6117647 263 | 0.41960785 264 | 0.99215686 265 | 0.99215686 266 | 0.8039216 267 | 0.043137256 268 | 0 269 | 0.16862746 270 | 0.6039216 271 | 0 272 | 0 273 | 0 274 | 0 275 | 0 276 | 0 277 | 0 278 | 0 279 | 0 280 | 0 281 | 0 282 | 0 283 | 0 284 | 0 285 | 0 286 | 0 287 | 0 288 | 0 289 | 0 290 | 0.05490196 291 | 0.003921569 292 | 0.6039216 293 | 0.99215686 294 | 0.3529412 295 | 0 296 | 0 297 | 0 298 | 0 299 | 0 300 | 0 301 | 0 302 | 0 303 | 0 304 | 0 305 | 0 306 | 0 307 | 0 308 | 0 309 | 0 310 | 0 311 | 0 312 | 0 313 | 0 314 | 0 315 | 0 316 | 0 317 | 0 318 | 0 319 | 0 320 | 0.54509807 321 | 0.99215686 322 | 0.74509805 323 | 0.007843138 324 | 0 325 | 0 326 | 0 327 | 0 328 | 0 329 | 0 330 | 0 331 | 0 332 | 0 333 | 0 334 | 0 335 | 0 336 | 0 337 | 0 338 | 0 339 | 0 340 | 0 341 | 0 342 | 0 343 | 0 344 | 0 345 | 0 346 | 0 347 | 0 348 | 0.043137256 349 | 0.74509805 350 | 0.99215686 351 | 0.27450982 352 | 0 353 | 0 354 | 0 355 | 0 356 | 0 357 | 0 358 | 0 359 | 0 360 | 0 361 | 0 362 | 0 363 | 0 364 | 0 365 | 0 366 | 0 367 | 0 368 | 0 369 | 0 370 | 0 371 | 0 372 | 0 373 | 0 374 | 0 375 | 0 376 | 0 377 | 0.13725491 378 | 0.94509804 379 | 0.88235295 380 | 0.627451 381 | 0.42352942 382 | 0.003921569 383 | 0 384 | 0 385 | 0 386 | 0 387 | 0 388 | 0 389 | 0 390 | 0 391 | 0 392 | 0 393 | 0 394 | 0 395 | 0 396 | 0 397 | 0 398 | 0 399 | 0 400 | 0 401 | 0 402 | 0 403 | 0 404 | 0 405 | 0 406 | 0.31764707 407 | 0.9411765 408 | 0.99215686 409 | 0.99215686 410 | 0.46666667 411 | 0.09803922 412 | 0 413 | 0 414 | 0 415 | 0 416 | 0 417 | 0 418 | 0 419 | 0 420 | 0 421 | 0 422 | 0 423 | 0 424 | 0 425 | 0 426 | 0 427 | 0 428 | 0 429 | 0 430 | 0 431 | 0 432 | 0 433 | 0 434 | 0 435 | 0.1764706 436 | 0.7294118 437 | 0.99215686 438 | 0.99215686 439 | 0.5882353 440 | 0.105882354 441 | 0 442 | 0 443 | 0 444 | 0 445 | 0 446 | 0 447 | 0 448 | 0 449 | 0 450 | 0 451 | 0 452 | 0 453 | 0 454 | 0 455 | 0 456 | 0 457 | 0 458 | 0 459 | 0 460 | 0 461 | 0 462 | 0 463 | 0 464 | 0.0627451 465 | 0.3647059 466 | 0.9882353 467 | 0.99215686 468 | 0.73333335 469 | 0 470 | 0 471 | 0 472 | 0 473 | 0 474 | 0 475 | 0 476 | 0 477 | 0 478 | 0 479 | 0 480 | 0 481 | 0 482 | 0 483 | 0 484 | 0 485 | 0 486 | 0 487 | 0 488 | 0 489 | 0 490 | 0 491 | 0 492 | 0 493 | 0 494 | 0.9764706 495 | 0.99215686 496 | 0.9764706 497 | 0.2509804 498 | 0 499 | 0 500 | 0 501 | 0 502 | 0 503 | 0 504 | 0 505 | 0 506 | 0 507 | 0 508 | 0 509 | 0 510 | 0 511 | 0 512 | 0 513 | 0 514 | 0 515 | 0 516 | 0 517 | 0 518 | 0 519 | 0.18039216 520 | 0.50980395 521 | 0.7176471 522 | 0.99215686 523 | 0.99215686 524 | 0.8117647 525 | 0.007843138 526 | 0 527 | 0 528 | 0 529 | 0 530 | 0 531 | 0 532 | 0 533 | 0 534 | 0 535 | 0 536 | 0 537 | 0 538 | 0 539 | 0 540 | 0 541 | 0 542 | 0 543 | 0 544 | 0 545 | 0.15294118 546 | 0.5803922 547 | 0.8980392 548 | 0.99215686 549 | 0.99215686 550 | 0.99215686 551 | 0.98039216 552 | 0.7137255 553 | 0 554 | 0 555 | 0 556 | 0 557 | 0 558 | 0 559 | 0 560 | 0 561 | 0 562 | 0 563 | 0 564 | 0 565 | 0 566 | 0 567 | 0 568 | 0 569 | 0 570 | 0 571 | 0.09411765 572 | 0.44705883 573 | 0.8666667 574 | 0.99215686 575 | 0.99215686 576 | 0.99215686 577 | 0.99215686 578 | 0.7882353 579 | 0.30588236 580 | 0 581 | 0 582 | 0 583 | 0 584 | 0 585 | 0 586 | 0 587 | 0 588 | 0 589 | 0 590 | 0 591 | 0 592 | 0 593 | 0 594 | 0 595 | 0 596 | 0 597 | 0.09019608 598 | 0.25882354 599 | 0.8352941 600 | 0.99215686 601 | 0.99215686 602 | 0.99215686 603 | 0.99215686 604 | 0.7764706 605 | 0.31764707 606 | 0.007843138 607 | 0 608 | 0 609 | 0 610 | 0 611 | 0 612 | 0 613 | 0 614 | 0 615 | 0 616 | 0 617 | 0 618 | 0 619 | 0 620 | 0 621 | 0 622 | 0 623 | 0.07058824 624 | 0.67058825 625 | 0.85882354 626 | 0.99215686 627 | 0.99215686 628 | 0.99215686 629 | 0.99215686 630 | 0.7647059 631 | 0.3137255 632 | 0.03529412 633 | 0 634 | 0 635 | 0 636 | 0 637 | 0 638 | 0 639 | 0 640 | 0 641 | 0 642 | 0 643 | 0 644 | 0 645 | 0 646 | 0 647 | 0 648 | 0 649 | 0.21568628 650 | 0.6745098 651 | 0.8862745 652 | 0.99215686 653 | 0.99215686 654 | 0.99215686 655 | 0.99215686 656 | 0.95686275 657 | 0.52156866 658 | 0.043137256 659 | 0 660 | 0 661 | 0 662 | 0 663 | 0 664 | 0 665 | 0 666 | 0 667 | 0 668 | 0 669 | 0 670 | 0 671 | 0 672 | 0 673 | 0 674 | 0 675 | 0 676 | 0 677 | 0.53333336 678 | 0.99215686 679 | 0.99215686 680 | 0.99215686 681 | 0.83137256 682 | 0.5294118 683 | 0.5176471 684 | 0.0627451 685 | 0 686 | 0 687 | 0 688 | 0 689 | 0 690 | 0 691 | 0 692 | 0 693 | 0 694 | 0 695 | 0 696 | 0 697 | 0 698 | 0 699 | 0 700 | 0 701 | 0 702 | 0 703 | 0 704 | 0 705 | 0 706 | 0 707 | 0 708 | 0 709 | 0 710 | 0 711 | 0 712 | 0 713 | 0 714 | 0 715 | 0 716 | 0 717 | 0 718 | 0 719 | 0 720 | 0 721 | 0 722 | 0 723 | 0 724 | 0 725 | 0 726 | 0 727 | 0 728 | 0 729 | 0 730 | 0 731 | 0 732 | 0 733 | 0 734 | 0 735 | 0 736 | 0 737 | 0 738 | 0 739 | 0 740 | 0 741 | 0 742 | 0 743 | 0 744 | 0 745 | 0 746 | 0 747 | 0 748 | 0 749 | 0 750 | 0 751 | 0 752 | 0 753 | 0 754 | 0 755 | 0 756 | 0 757 | 0 758 | 0 759 | 0 760 | 0 761 | 0 762 | 0 763 | 0 764 | 0 765 | 0 766 | 0 767 | 0 768 | 0 769 | 0 770 | 0 771 | 0 772 | 0 773 | 0 774 | 0 775 | 0 776 | 0 777 | 0 778 | 0 779 | 0 780 | 0 781 | 0 782 | 0 783 | 0 784 | 0 -------------------------------------------------------------------------------- /src/SharpCV/Core/Mat.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.CompilerServices; 4 | using System.Text; 5 | using Tensorflow; 6 | using Tensorflow.NumPy; 7 | 8 | namespace SharpCV 9 | { 10 | public partial class Mat : DisposableObject 11 | { 12 | NDArray _nd; 13 | public NDArray data 14 | { 15 | get 16 | { 17 | if (_nd is null) 18 | _nd = GetData(); 19 | 20 | return _nd; 21 | } 22 | } 23 | 24 | int _ndim; 25 | public int ndim 26 | { 27 | get 28 | { 29 | cv2_native_api.core_Mat_dims(_handle, out _ndim); 30 | return _ndim + (Channels > 1 ? 1 : 0); 31 | } 32 | } 33 | 34 | public TF_DataType dtype { get; set; } = np.@byte; 35 | 36 | MatType _matType = MatType.Unknown; 37 | public MatType MatType 38 | { 39 | get 40 | { 41 | if (_matType != MatType.Unknown) 42 | return _matType; 43 | 44 | cv2_native_api.core_Mat_type(_handle, out _matType); 45 | return _matType; 46 | } 47 | } 48 | 49 | int[] _dims; 50 | Shape _shape; 51 | /// 52 | /// HWC 53 | /// height * width * channel 54 | /// 55 | public Shape shape 56 | { 57 | get 58 | { 59 | if(_dims != null) 60 | return _shape; 61 | 62 | _dims = new int[ndim]; 63 | cv2_native_api.core_Mat_dims(_handle, out _ndim); 64 | 65 | for (int i = 0; i < _ndim; i++) 66 | cv2_native_api.core_Mat_sizeAt(_handle, i, out _dims[i]); 67 | 68 | if(Channels > 1) 69 | _dims[_ndim] = Channels; 70 | 71 | _shape = new Shape(_dims); 72 | return _shape; 73 | } 74 | } 75 | 76 | public long size => shape.size; 77 | 78 | IntPtr _intputArray; 79 | public IntPtr InputArray 80 | { 81 | get 82 | { 83 | if(_intputArray == IntPtr.Zero) 84 | cv2_native_api.core_InputArray_new_byMat(_handle, out _intputArray); 85 | return _intputArray; 86 | } 87 | } 88 | 89 | IntPtr _outputArray; 90 | public IntPtr OutputArray 91 | { 92 | get 93 | { 94 | if(_outputArray == IntPtr.Zero) 95 | cv2_native_api.core_OutputArray_new_byMat(_handle, out _outputArray); 96 | return _outputArray; 97 | } 98 | } 99 | 100 | int _channels = -1; 101 | public int Channels 102 | { 103 | get 104 | { 105 | if (_channels > -1) 106 | return _channels; 107 | 108 | cv2_native_api.core_Mat_channels(_handle, out _channels); 109 | return _channels; 110 | } 111 | } 112 | 113 | public unsafe NDArray GetData() 114 | { 115 | // we pass donothing as it keeps reference to src preventing its disposal by GC 116 | switch (MatType) 117 | { 118 | case MatType.CV_32SC1: 119 | case MatType.CV_32SC2: 120 | { 121 | cv2_native_api.core_Mat_data(_handle, out int* dataPtr); 122 | dtype = TF_DataType.TF_INT32; 123 | return new NDArray(new IntPtr(dataPtr), shape, dtype); 124 | } 125 | case MatType.CV_32FC1: 126 | { 127 | cv2_native_api.core_Mat_data(_handle, out float* dataPtr); 128 | dtype = TF_DataType.TF_FLOAT; 129 | return new NDArray(new IntPtr(dataPtr), shape, dtype); 130 | } 131 | case MatType.CV_8UC1: 132 | case MatType.CV_8UC3: 133 | { 134 | cv2_native_api.core_Mat_data(_handle, out byte* dataPtr); 135 | dtype = TF_DataType.TF_UINT8; 136 | return new NDArray(new IntPtr(dataPtr), shape, dtype); 137 | } 138 | default: 139 | throw new NotImplementedException($"Can't find type: {_matType}"); 140 | } 141 | } 142 | 143 | [MethodImpl(MethodImplOptions.NoOptimization)] 144 | private void DoNothing(IntPtr ptr) 145 | { 146 | var p = ptr; 147 | } 148 | 149 | public NDArray astype(TF_DataType dtype) 150 | => data.astype(dtype); 151 | 152 | public NDArray astype() 153 | => data.astype(typeof(T).as_tf_dtype()); 154 | 155 | protected override void FreeHandle() 156 | { 157 | cv2_native_api.core_Mat_delete(_handle); 158 | } 159 | 160 | public override string ToString() 161 | { 162 | return $"{shape} {MatType}"; 163 | } 164 | 165 | public MatType FromType(Type type) 166 | => Type.GetTypeCode(type) switch 167 | { 168 | TypeCode.Int32 => MatType.CV_32SC1, 169 | TypeCode.Single => MatType.CV_32FC1, 170 | TypeCode.Double => MatType.CV_64FC1, 171 | _ => MatType.CV_8UC1 172 | }; 173 | 174 | public MatType FromType(TF_DataType dtype) 175 | => dtype switch 176 | { 177 | TF_DataType.TF_INT32 => MatType.CV_32SC1, 178 | TF_DataType.TF_FLOAT => MatType.CV_32FC1, 179 | TF_DataType.TF_DOUBLE => MatType.CV_64FC1, 180 | _ => MatType.CV_8UC1 181 | }; 182 | 183 | #region ImEncode / ToBytes 184 | 185 | /// 186 | /// Encodes an image into a memory buffer. 187 | /// 188 | /// Encodes an image into a memory buffer. 189 | /// Format-specific parameters. 190 | /// 191 | public byte[] ImEncode(string ext = ".png", int[]? prms = null) 192 | { 193 | //ThrowIfDisposed(); 194 | SharpCV.cv_api.ImEncode(ext, this, out var buf, prms); 195 | return buf; 196 | } 197 | 198 | ///// 199 | ///// Encodes an image into a memory buffer. 200 | ///// 201 | ///// Encodes an image into a memory buffer. 202 | ///// Format-specific parameters. 203 | ///// 204 | //public byte[] ImEncode(string ext = ".png", params ImageEncodingParam[] prms) 205 | //{ 206 | // //ThrowIfDisposed(); 207 | // SharpCV.cv_api.ImEncode(ext, this, out var buf, prms); 208 | // return buf; 209 | //} 210 | 211 | #endregion 212 | 213 | #region Static Initializers 214 | 215 | /// 216 | /// Creates the Mat instance from System.IO.Stream 217 | /// 218 | /// 219 | /// 220 | /// 221 | public static Mat FromStream(System.IO.Stream stream, IMREAD_COLOR mode = IMREAD_COLOR.IMREAD_COLOR) 222 | { 223 | if (stream == null) 224 | throw new ArgumentNullException(nameof(stream)); 225 | if (stream.Length > int.MaxValue) 226 | throw new ArgumentException("Not supported stream (too long)"); 227 | 228 | using var memoryStream = new System.IO.MemoryStream(); 229 | stream.CopyTo(memoryStream); 230 | 231 | return FromImageData(memoryStream.ToArray(), mode); 232 | } 233 | 234 | /// 235 | /// Creates the Mat instance from image data (using cv::decode) 236 | /// 237 | /// 238 | /// 239 | /// 240 | public static Mat ImDecode(byte[] imageBytes, IMREAD_COLOR mode = IMREAD_COLOR.IMREAD_COLOR) 241 | { 242 | if (imageBytes == null) 243 | throw new ArgumentNullException(nameof(imageBytes)); 244 | return cv_api.ImDecode(imageBytes, mode); 245 | } 246 | 247 | /// 248 | /// Creates the Mat instance from image data (using cv::decode) 249 | /// 250 | /// 251 | /// 252 | /// 253 | public static Mat FromImageData(byte[] imageBytes, IMREAD_COLOR mode = IMREAD_COLOR.IMREAD_COLOR) 254 | { 255 | return ImDecode(imageBytes, mode); 256 | } 257 | 258 | #endregion 259 | 260 | 261 | } 262 | } 263 | -------------------------------------------------------------------------------- /src/SharpCV/NativeAPIs/enum/cv2_native_api.ColorConversionCodes.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | using System.Text; 5 | 6 | namespace SharpCV 7 | { 8 | /// 9 | /// modules\imgproc\include\opencv2\imgproc.hpp 10 | /// 11 | public enum ColorConversionCodes 12 | { 13 | COLOR_BGR2BGRA = 0, //!< add alpha channel to RGB or BGR image 14 | COLOR_RGB2RGBA = COLOR_BGR2BGRA, 15 | 16 | COLOR_BGRA2BGR = 1, //!< remove alpha channel from RGB or BGR image 17 | COLOR_RGBA2RGB = COLOR_BGRA2BGR, 18 | 19 | COLOR_BGR2RGBA = 2, //!< convert between RGB and BGR color spaces (with or without alpha channel) 20 | COLOR_RGB2BGRA = COLOR_BGR2RGBA, 21 | 22 | COLOR_RGBA2BGR = 3, 23 | COLOR_BGRA2RGB = COLOR_RGBA2BGR, 24 | 25 | COLOR_BGR2RGB = 4, 26 | COLOR_RGB2BGR = COLOR_BGR2RGB, 27 | 28 | COLOR_BGRA2RGBA = 5, 29 | COLOR_RGBA2BGRA = COLOR_BGRA2RGBA, 30 | 31 | COLOR_BGR2GRAY = 6, //!< convert between RGB/BGR and grayscale, @ref color_convert_rgb_gray "color conversions" 32 | COLOR_RGB2GRAY = 7, 33 | COLOR_GRAY2BGR = 8, 34 | COLOR_GRAY2RGB = COLOR_GRAY2BGR, 35 | COLOR_GRAY2BGRA = 9, 36 | COLOR_GRAY2RGBA = COLOR_GRAY2BGRA, 37 | COLOR_BGRA2GRAY = 10, 38 | COLOR_RGBA2GRAY = 11, 39 | 40 | COLOR_BGR2BGR565 = 12, //!< convert between RGB/BGR and BGR565 (16-bit images) 41 | COLOR_RGB2BGR565 = 13, 42 | COLOR_BGR5652BGR = 14, 43 | COLOR_BGR5652RGB = 15, 44 | COLOR_BGRA2BGR565 = 16, 45 | COLOR_RGBA2BGR565 = 17, 46 | COLOR_BGR5652BGRA = 18, 47 | COLOR_BGR5652RGBA = 19, 48 | 49 | COLOR_GRAY2BGR565 = 20, //!< convert between grayscale to BGR565 (16-bit images) 50 | COLOR_BGR5652GRAY = 21, 51 | 52 | COLOR_BGR2BGR555 = 22, //!< convert between RGB/BGR and BGR555 (16-bit images) 53 | COLOR_RGB2BGR555 = 23, 54 | COLOR_BGR5552BGR = 24, 55 | COLOR_BGR5552RGB = 25, 56 | COLOR_BGRA2BGR555 = 26, 57 | COLOR_RGBA2BGR555 = 27, 58 | COLOR_BGR5552BGRA = 28, 59 | COLOR_BGR5552RGBA = 29, 60 | 61 | COLOR_GRAY2BGR555 = 30, //!< convert between grayscale and BGR555 (16-bit images) 62 | COLOR_BGR5552GRAY = 31, 63 | 64 | COLOR_BGR2XYZ = 32, //!< convert RGB/BGR to CIE XYZ, @ref color_convert_rgb_xyz "color conversions" 65 | COLOR_RGB2XYZ = 33, 66 | COLOR_XYZ2BGR = 34, 67 | COLOR_XYZ2RGB = 35, 68 | 69 | COLOR_BGR2YCrCb = 36, //!< convert RGB/BGR to luma-chroma (aka YCC), @ref color_convert_rgb_ycrcb "color conversions" 70 | COLOR_RGB2YCrCb = 37, 71 | COLOR_YCrCb2BGR = 38, 72 | COLOR_YCrCb2RGB = 39, 73 | 74 | COLOR_BGR2HSV = 40, //!< convert RGB/BGR to HSV (hue saturation value), @ref color_convert_rgb_hsv "color conversions" 75 | COLOR_RGB2HSV = 41, 76 | 77 | COLOR_BGR2Lab = 44, //!< convert RGB/BGR to CIE Lab, @ref color_convert_rgb_lab "color conversions" 78 | COLOR_RGB2Lab = 45, 79 | 80 | COLOR_BGR2Luv = 50, //!< convert RGB/BGR to CIE Luv, @ref color_convert_rgb_luv "color conversions" 81 | COLOR_RGB2Luv = 51, 82 | COLOR_BGR2HLS = 52, //!< convert RGB/BGR to HLS (hue lightness saturation), @ref color_convert_rgb_hls "color conversions" 83 | COLOR_RGB2HLS = 53, 84 | 85 | COLOR_HSV2BGR = 54, //!< backward conversions to RGB/BGR 86 | COLOR_HSV2RGB = 55, 87 | 88 | COLOR_Lab2BGR = 56, 89 | COLOR_Lab2RGB = 57, 90 | COLOR_Luv2BGR = 58, 91 | COLOR_Luv2RGB = 59, 92 | COLOR_HLS2BGR = 60, 93 | COLOR_HLS2RGB = 61, 94 | 95 | COLOR_BGR2HSV_FULL = 66, 96 | COLOR_RGB2HSV_FULL = 67, 97 | COLOR_BGR2HLS_FULL = 68, 98 | COLOR_RGB2HLS_FULL = 69, 99 | 100 | COLOR_HSV2BGR_FULL = 70, 101 | COLOR_HSV2RGB_FULL = 71, 102 | COLOR_HLS2BGR_FULL = 72, 103 | COLOR_HLS2RGB_FULL = 73, 104 | 105 | COLOR_LBGR2Lab = 74, 106 | COLOR_LRGB2Lab = 75, 107 | COLOR_LBGR2Luv = 76, 108 | COLOR_LRGB2Luv = 77, 109 | 110 | COLOR_Lab2LBGR = 78, 111 | COLOR_Lab2LRGB = 79, 112 | COLOR_Luv2LBGR = 80, 113 | COLOR_Luv2LRGB = 81, 114 | 115 | COLOR_BGR2YUV = 82, //!< convert between RGB/BGR and YUV 116 | COLOR_RGB2YUV = 83, 117 | COLOR_YUV2BGR = 84, 118 | COLOR_YUV2RGB = 85, 119 | 120 | //! YUV 4:2:0 family to RGB 121 | COLOR_YUV2RGB_NV12 = 90, 122 | COLOR_YUV2BGR_NV12 = 91, 123 | COLOR_YUV2RGB_NV21 = 92, 124 | COLOR_YUV2BGR_NV21 = 93, 125 | COLOR_YUV420sp2RGB = COLOR_YUV2RGB_NV21, 126 | COLOR_YUV420sp2BGR = COLOR_YUV2BGR_NV21, 127 | 128 | COLOR_YUV2RGBA_NV12 = 94, 129 | COLOR_YUV2BGRA_NV12 = 95, 130 | COLOR_YUV2RGBA_NV21 = 96, 131 | COLOR_YUV2BGRA_NV21 = 97, 132 | COLOR_YUV420sp2RGBA = COLOR_YUV2RGBA_NV21, 133 | COLOR_YUV420sp2BGRA = COLOR_YUV2BGRA_NV21, 134 | 135 | COLOR_YUV2RGB_YV12 = 98, 136 | COLOR_YUV2BGR_YV12 = 99, 137 | COLOR_YUV2RGB_IYUV = 100, 138 | COLOR_YUV2BGR_IYUV = 101, 139 | COLOR_YUV2RGB_I420 = COLOR_YUV2RGB_IYUV, 140 | COLOR_YUV2BGR_I420 = COLOR_YUV2BGR_IYUV, 141 | COLOR_YUV420p2RGB = COLOR_YUV2RGB_YV12, 142 | COLOR_YUV420p2BGR = COLOR_YUV2BGR_YV12, 143 | 144 | COLOR_YUV2RGBA_YV12 = 102, 145 | COLOR_YUV2BGRA_YV12 = 103, 146 | COLOR_YUV2RGBA_IYUV = 104, 147 | COLOR_YUV2BGRA_IYUV = 105, 148 | COLOR_YUV2RGBA_I420 = COLOR_YUV2RGBA_IYUV, 149 | COLOR_YUV2BGRA_I420 = COLOR_YUV2BGRA_IYUV, 150 | COLOR_YUV420p2RGBA = COLOR_YUV2RGBA_YV12, 151 | COLOR_YUV420p2BGRA = COLOR_YUV2BGRA_YV12, 152 | 153 | COLOR_YUV2GRAY_420 = 106, 154 | COLOR_YUV2GRAY_NV21 = COLOR_YUV2GRAY_420, 155 | COLOR_YUV2GRAY_NV12 = COLOR_YUV2GRAY_420, 156 | COLOR_YUV2GRAY_YV12 = COLOR_YUV2GRAY_420, 157 | COLOR_YUV2GRAY_IYUV = COLOR_YUV2GRAY_420, 158 | COLOR_YUV2GRAY_I420 = COLOR_YUV2GRAY_420, 159 | COLOR_YUV420sp2GRAY = COLOR_YUV2GRAY_420, 160 | COLOR_YUV420p2GRAY = COLOR_YUV2GRAY_420, 161 | 162 | //! YUV 4:2:2 family to RGB 163 | COLOR_YUV2RGB_UYVY = 107, 164 | COLOR_YUV2BGR_UYVY = 108, 165 | //COLOR_YUV2RGB_VYUY = 109, 166 | //COLOR_YUV2BGR_VYUY = 110, 167 | COLOR_YUV2RGB_Y422 = COLOR_YUV2RGB_UYVY, 168 | COLOR_YUV2BGR_Y422 = COLOR_YUV2BGR_UYVY, 169 | COLOR_YUV2RGB_UYNV = COLOR_YUV2RGB_UYVY, 170 | COLOR_YUV2BGR_UYNV = COLOR_YUV2BGR_UYVY, 171 | 172 | COLOR_YUV2RGBA_UYVY = 111, 173 | COLOR_YUV2BGRA_UYVY = 112, 174 | //COLOR_YUV2RGBA_VYUY = 113, 175 | //COLOR_YUV2BGRA_VYUY = 114, 176 | COLOR_YUV2RGBA_Y422 = COLOR_YUV2RGBA_UYVY, 177 | COLOR_YUV2BGRA_Y422 = COLOR_YUV2BGRA_UYVY, 178 | COLOR_YUV2RGBA_UYNV = COLOR_YUV2RGBA_UYVY, 179 | COLOR_YUV2BGRA_UYNV = COLOR_YUV2BGRA_UYVY, 180 | 181 | COLOR_YUV2RGB_YUY2 = 115, 182 | COLOR_YUV2BGR_YUY2 = 116, 183 | COLOR_YUV2RGB_YVYU = 117, 184 | COLOR_YUV2BGR_YVYU = 118, 185 | COLOR_YUV2RGB_YUYV = COLOR_YUV2RGB_YUY2, 186 | COLOR_YUV2BGR_YUYV = COLOR_YUV2BGR_YUY2, 187 | COLOR_YUV2RGB_YUNV = COLOR_YUV2RGB_YUY2, 188 | COLOR_YUV2BGR_YUNV = COLOR_YUV2BGR_YUY2, 189 | 190 | COLOR_YUV2RGBA_YUY2 = 119, 191 | COLOR_YUV2BGRA_YUY2 = 120, 192 | COLOR_YUV2RGBA_YVYU = 121, 193 | COLOR_YUV2BGRA_YVYU = 122, 194 | COLOR_YUV2RGBA_YUYV = COLOR_YUV2RGBA_YUY2, 195 | COLOR_YUV2BGRA_YUYV = COLOR_YUV2BGRA_YUY2, 196 | COLOR_YUV2RGBA_YUNV = COLOR_YUV2RGBA_YUY2, 197 | COLOR_YUV2BGRA_YUNV = COLOR_YUV2BGRA_YUY2, 198 | 199 | COLOR_YUV2GRAY_UYVY = 123, 200 | COLOR_YUV2GRAY_YUY2 = 124, 201 | //CV_YUV2GRAY_VYUY = CV_YUV2GRAY_UYVY, 202 | COLOR_YUV2GRAY_Y422 = COLOR_YUV2GRAY_UYVY, 203 | COLOR_YUV2GRAY_UYNV = COLOR_YUV2GRAY_UYVY, 204 | COLOR_YUV2GRAY_YVYU = COLOR_YUV2GRAY_YUY2, 205 | COLOR_YUV2GRAY_YUYV = COLOR_YUV2GRAY_YUY2, 206 | COLOR_YUV2GRAY_YUNV = COLOR_YUV2GRAY_YUY2, 207 | 208 | //! alpha premultiplication 209 | COLOR_RGBA2mRGBA = 125, 210 | COLOR_mRGBA2RGBA = 126, 211 | 212 | //! RGB to YUV 4:2:0 family 213 | COLOR_RGB2YUV_I420 = 127, 214 | COLOR_BGR2YUV_I420 = 128, 215 | COLOR_RGB2YUV_IYUV = COLOR_RGB2YUV_I420, 216 | COLOR_BGR2YUV_IYUV = COLOR_BGR2YUV_I420, 217 | 218 | COLOR_RGBA2YUV_I420 = 129, 219 | COLOR_BGRA2YUV_I420 = 130, 220 | COLOR_RGBA2YUV_IYUV = COLOR_RGBA2YUV_I420, 221 | COLOR_BGRA2YUV_IYUV = COLOR_BGRA2YUV_I420, 222 | COLOR_RGB2YUV_YV12 = 131, 223 | COLOR_BGR2YUV_YV12 = 132, 224 | COLOR_RGBA2YUV_YV12 = 133, 225 | COLOR_BGRA2YUV_YV12 = 134, 226 | 227 | //! Demosaicing 228 | COLOR_BayerBG2BGR = 46, 229 | COLOR_BayerGB2BGR = 47, 230 | COLOR_BayerRG2BGR = 48, 231 | COLOR_BayerGR2BGR = 49, 232 | 233 | COLOR_BayerBG2RGB = COLOR_BayerRG2BGR, 234 | COLOR_BayerGB2RGB = COLOR_BayerGR2BGR, 235 | COLOR_BayerRG2RGB = COLOR_BayerBG2BGR, 236 | COLOR_BayerGR2RGB = COLOR_BayerGB2BGR, 237 | 238 | COLOR_BayerBG2GRAY = 86, 239 | COLOR_BayerGB2GRAY = 87, 240 | COLOR_BayerRG2GRAY = 88, 241 | COLOR_BayerGR2GRAY = 89, 242 | 243 | //! Demosaicing using Variable Number of Gradients 244 | COLOR_BayerBG2BGR_VNG = 62, 245 | COLOR_BayerGB2BGR_VNG = 63, 246 | COLOR_BayerRG2BGR_VNG = 64, 247 | COLOR_BayerGR2BGR_VNG = 65, 248 | 249 | COLOR_BayerBG2RGB_VNG = COLOR_BayerRG2BGR_VNG, 250 | COLOR_BayerGB2RGB_VNG = COLOR_BayerGR2BGR_VNG, 251 | COLOR_BayerRG2RGB_VNG = COLOR_BayerBG2BGR_VNG, 252 | COLOR_BayerGR2RGB_VNG = COLOR_BayerGB2BGR_VNG, 253 | 254 | //! Edge-Aware Demosaicing 255 | COLOR_BayerBG2BGR_EA = 135, 256 | COLOR_BayerGB2BGR_EA = 136, 257 | COLOR_BayerRG2BGR_EA = 137, 258 | COLOR_BayerGR2BGR_EA = 138, 259 | 260 | COLOR_BayerBG2RGB_EA = COLOR_BayerRG2BGR_EA, 261 | COLOR_BayerGB2RGB_EA = COLOR_BayerGR2BGR_EA, 262 | COLOR_BayerRG2RGB_EA = COLOR_BayerBG2BGR_EA, 263 | COLOR_BayerGR2RGB_EA = COLOR_BayerGB2BGR_EA, 264 | 265 | //! Demosaicing with alpha channel 266 | COLOR_BayerBG2BGRA = 139, 267 | COLOR_BayerGB2BGRA = 140, 268 | COLOR_BayerRG2BGRA = 141, 269 | COLOR_BayerGR2BGRA = 142, 270 | 271 | COLOR_BayerBG2RGBA = COLOR_BayerRG2BGRA, 272 | COLOR_BayerGB2RGBA = COLOR_BayerGR2BGRA, 273 | COLOR_BayerRG2RGBA = COLOR_BayerBG2BGRA, 274 | COLOR_BayerGR2RGBA = COLOR_BayerGB2BGRA, 275 | 276 | COLOR_COLORCVT_MAX = 143 277 | }; 278 | } 279 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /src/SharpCV/APIs/cv2.imgproc.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Numerics; 5 | using System.Runtime.InteropServices; 6 | using System.Text; 7 | 8 | namespace SharpCV 9 | { 10 | public partial class cv_api 11 | { 12 | public Mat cvtColor(Mat img, 13 | ColorConversionCodes code, 14 | int dstCnt = 0) 15 | { 16 | var dst = new Mat(); 17 | cv2_native_api.imgproc_cvtColor(img.InputArray, dst.OutputArray, (int)code, dstCnt); 18 | return dst; 19 | } 20 | 21 | public double contourArea(Mat img, 22 | bool oriented = false) 23 | { 24 | cv2_native_api.imgproc_contourArea_InputArray(img.InputArray, oriented ? 1 : 0, out var output); 25 | return output; 26 | } 27 | 28 | public Mat adaptiveThreshold(Mat img, 29 | double maxValue, 30 | AdaptiveThresholdTypes method, 31 | ThresholdTypes type, 32 | int blockSize, 33 | double delta) 34 | { 35 | var dst = new Mat(); 36 | cv2_native_api.imgproc_adaptiveThreshold(img.InputArray, 37 | dst.OutputArray, 38 | maxValue, 39 | (int)method, 40 | (int)type, 41 | blockSize, 42 | delta); 43 | return dst; 44 | } 45 | 46 | public (double, Mat) threshold(Mat img, double thresh, double maxval, ThresholdTypes type) 47 | { 48 | var dst = new Mat(); 49 | cv2_native_api.imgproc_threshold(img.InputArray, dst.OutputArray, thresh, maxval, (int)type, out var ret); 50 | return (ret, dst); 51 | } 52 | 53 | public Mat pyrUp(Mat img) 54 | { 55 | var dst = new Mat(); 56 | cv2_native_api.imgproc_pyrUp(img.InputArray, 57 | dst.OutputArray, 58 | new Size(), 59 | (int)BorderTypes.BORDER_DEFAULT); 60 | return dst; 61 | } 62 | 63 | public Mat pyrUp(Mat img, 64 | (int, int) dstSize, 65 | BorderTypes borderType = BorderTypes.BORDER_DEFAULT) 66 | { 67 | var dst = new Mat(); 68 | cv2_native_api.imgproc_pyrUp(img.InputArray, 69 | dst.OutputArray, 70 | new Size(dstSize.Item1, dstSize.Item2), 71 | (int)borderType); 72 | return dst; 73 | } 74 | 75 | public Mat pyrDown(Mat img, 76 | (int, int) dstSize, 77 | BorderTypes borderType = BorderTypes.BORDER_DEFAULT) 78 | { 79 | var dst = new Mat(); 80 | cv2_native_api.imgproc_pyrDown(img.InputArray, 81 | dst.OutputArray, 82 | new Size(dstSize.Item1, dstSize.Item2), 83 | (int)borderType); 84 | return dst; 85 | } 86 | 87 | public Mat pyrDown(Mat img) 88 | { 89 | var dst = new Mat(); 90 | cv2_native_api.imgproc_pyrDown(img.InputArray, 91 | dst.OutputArray, 92 | new Size(), 93 | (int)BorderTypes.BORDER_DEFAULT); 94 | return dst; 95 | } 96 | 97 | public Mat resize(Mat img, 98 | (int, int) dsize, 99 | double fx = 0, 100 | double fy = 0, 101 | InterpolationFlags interpolation = InterpolationFlags.INTER_LINEAR) 102 | { 103 | var dst = new Mat(); 104 | cv2_native_api.imgproc_resize(img.InputArray, 105 | dst.OutputArray, 106 | new Size(dsize.Item1, dsize.Item2), 107 | fx, 108 | fy, 109 | (int)interpolation); 110 | 111 | return dst; 112 | } 113 | 114 | /// 115 | /// Using rotation matrix to rotate a image. 116 | /// https://en.wikipedia.org/wiki/Rotation_matrix 117 | /// 118 | /// 119 | /// 120 | /// 121 | /// 122 | /// 123 | public Mat rotate(Mat img, 124 | (int, int) center, 125 | double angle, 126 | double scale, 127 | InterpolationFlags flags = InterpolationFlags.INTER_LINEAR, 128 | BorderTypes borderMode = BorderTypes.BORDER_CONSTANT) 129 | { 130 | cv2_native_api.imgproc_getRotationMatrix2D(new Point(center.Item1, center.Item2), 131 | angle, 132 | scale, 133 | out var handle); 134 | 135 | cv2_native_api.core_Mat_size(img, out var size); 136 | 137 | var scalar = new Scalar(); 138 | var dst = new Mat(); 139 | var matrix2d = new Mat(handle); 140 | 141 | cv2_native_api.imgproc_warpAffine(img.InputArray, 142 | dst.OutputArray, 143 | matrix2d.InputArray, 144 | size, 145 | (int)flags, 146 | (int)borderMode, scalar); 147 | 148 | return dst; 149 | } 150 | 151 | public void rectangle(Mat img, 152 | Point leftTop, 153 | Point rightBottom, 154 | Scalar color, 155 | int thickness = 1, 156 | LineTypes type = LineTypes.LINE_8, 157 | int shift = 0) 158 | { 159 | cv2_native_api.imgproc_rectangle_InputOutputArray_Point(img.OutputArray, 160 | leftTop, 161 | rightBottom, 162 | color, 163 | thickness, 164 | type, 165 | shift); 166 | } 167 | 168 | public void putText(Mat img, string text, Point org, 169 | HersheyFonts fontFace, double fontScale, Scalar color, 170 | int thickness = 1, LineTypes lineType = LineTypes.LINE_8, bool bottomLeftOrigin = false) 171 | { 172 | if (img == null) 173 | throw new ArgumentNullException(nameof(img)); 174 | if (string.IsNullOrEmpty(text)) 175 | throw new ArgumentNullException(text); 176 | 177 | 178 | cv2_native_api.imgproc_putText(img.InputArray, text, org, (int)fontFace, fontScale, color, 179 | thickness, (int)lineType, bottomLeftOrigin ? 1 : 0); 180 | } 181 | 182 | public Size getTextSize(string text, HersheyFonts fontFace, 183 | double fontScale, int thickness, out int baseLine) 184 | { 185 | if (string.IsNullOrEmpty(text)) 186 | throw new ArgumentNullException(text); 187 | 188 | cv2_native_api.imgproc_getTextSize(text, (int)fontFace, fontScale, thickness, out baseLine, out var ret); 189 | return ret; 190 | } 191 | 192 | public Size getTextSize(string text, HersheyFonts fontFace, double fontScale, int thickness) 193 | { 194 | return getTextSize(text, fontFace, fontScale, thickness, out _); 195 | } 196 | 197 | public Mat getStructuringElement(MorphShapes shape, Size ksize) 198 | { 199 | cv2_native_api.imgproc_getStructuringElement((int)shape, ksize, new Point(), out var handle); 200 | return new Mat(handle); 201 | } 202 | 203 | public Mat morphologyEx(Mat src, 204 | MorphTypes type, 205 | Mat kernel, 206 | Point? anchor = null, 207 | int iterations = 1, 208 | BorderTypes borderType = BorderTypes.BORDER_CONSTANT, 209 | Scalar borderValue = default) 210 | { 211 | var output = new Mat(); 212 | if (anchor is null) 213 | anchor = new Point(-1, -1); 214 | cv2_native_api.imgproc_morphologyEx(src.InputArray, 215 | output.OutputArray, 216 | (int)type, 217 | kernel.InputArray, 218 | anchor.Value, 219 | iterations, 220 | (int)borderType, 221 | borderValue); 222 | return output; 223 | } 224 | 225 | public Point[][] findContoursAsPoints(Mat src, 226 | RetrievalModes mode, 227 | ContourApproximationModes method, 228 | Point offset = default) 229 | { 230 | cv2_native_api.imgproc_findContours1_vector(src.OutputArray, 231 | out var contoursPtr, 232 | out var hierarchyPtr, 233 | (int)mode, 234 | (int)method, 235 | offset); 236 | 237 | using (var contoursVec = new VectorOfVectorPoint(contoursPtr)) 238 | return contoursVec.ToArray(); 239 | } 240 | 241 | public (Mat[], Mat) findContours(Mat src, 242 | RetrievalModes mode, 243 | ContourApproximationModes method, 244 | Point offset = default) 245 | { 246 | var hierarchy = new Mat(); 247 | cv2_native_api.imgproc_findContours1_OutputArray(src.OutputArray, 248 | out var contoursPtr, 249 | hierarchy.OutputArray, 250 | (int)mode, 251 | (int)method, 252 | offset); 253 | 254 | using (var contoursVec = new VectorOfMat(contoursPtr)) 255 | return (contoursVec.ToArray(), hierarchy); 256 | } 257 | 258 | public void drawContours(Mat image, 259 | Point[][] contours, 260 | int contourIdx, 261 | Scalar color, 262 | int thickness = 1, 263 | LineTypes lineType = LineTypes.LINE_8, 264 | int maxLevel = int.MaxValue, 265 | Point offset = default) 266 | { 267 | var contourSize2 = contours.Select(pts => pts.Length).ToArray(); 268 | using (var contoursPtr = new ArrayAddress2(contours)) 269 | { 270 | cv2_native_api.imgproc_drawContours_vector( 271 | image.OutputArray, contoursPtr.Pointer, contours.Length, contourSize2, 272 | contourIdx, color, thickness, (int)lineType, IntPtr.Zero, 0, maxLevel, offset); 273 | } 274 | 275 | GC.KeepAlive(image); 276 | } 277 | 278 | public void drawContours(Mat image, 279 | Mat contour, 280 | int contourIdx, 281 | Scalar color, 282 | int thickness = 1, 283 | LineTypes lineType = LineTypes.LINE_8, 284 | Mat? hierarchy = null, 285 | int maxLevel = int.MaxValue, 286 | Point? offset = null) 287 | { 288 | if (offset is null) 289 | offset = new Point(-1, -1); 290 | var contoursPtr = new IntPtr[] { contour }; 291 | 292 | cv2_native_api.imgproc_drawContours_InputArray( 293 | image.OutputArray, contoursPtr, 1, 294 | contourIdx, color, thickness, lineType, 295 | hierarchy ?? IntPtr.Zero, maxLevel, offset.Value); 296 | 297 | GC.KeepAlive(image); 298 | } 299 | 300 | public Mat approxPolyDP(Mat curve, double epsilon, bool closed) 301 | { 302 | var approxCurve = new Mat(); 303 | cv2_native_api.imgproc_approxPolyDP_InputArray(curve.InputArray, 304 | approxCurve.OutputArray, 305 | epsilon, 306 | closed); 307 | return approxCurve; 308 | } 309 | 310 | public RotatedRect minAreaRect(Mat points) 311 | { 312 | cv2_native_api.imgproc_minAreaRect_InputArray(points.InputArray, out var rect); 313 | return rect; 314 | } 315 | 316 | public Moments moments(Mat src, bool binaryImage = false) 317 | => new Moments(src, binaryImage); 318 | 319 | public Mat medianBlur(Mat src, int kSize) 320 | { 321 | var dst = new Mat(); 322 | cv2_native_api.imgproc_medianBlur(src.InputArray, dst.OutputArray, kSize); 323 | return dst; 324 | } 325 | 326 | public Mat filter2D(Mat src, 327 | MatType ddepth, 328 | Mat kernel, 329 | Point? anchor = null, 330 | double delta = 0, 331 | BorderTypes borderType = BorderTypes.BORDER_DEFAULT) 332 | { 333 | var dst = new Mat(); 334 | if (anchor is null) 335 | anchor = new Point(-1, -1); 336 | cv2_native_api.imgproc_filter2D(src.InputArray, 337 | dst.OutputArray, 338 | ddepth, 339 | kernel.InputArray, 340 | anchor.Value, 341 | delta, 342 | borderType); 343 | return dst; 344 | } 345 | 346 | public Mat blur(Mat src, 347 | Size kSize, 348 | Point? anchor = null, 349 | BorderTypes borderType = BorderTypes.BORDER_DEFAULT) 350 | { 351 | var dst = new Mat(); 352 | if (anchor is null) 353 | anchor = new Point(-1, -1); 354 | cv2_native_api.imgproc_blur(src.InputArray, 355 | dst.OutputArray, 356 | kSize, 357 | anchor.Value, 358 | borderType); 359 | return dst; 360 | } 361 | } 362 | } 363 | --------------------------------------------------------------------------------