Mat Basic Processing1

These codes are included in the OpenCVForUnity Example Unity scenes. (MatBasicProcessingExample)

Initialization

Example Code:


            //
            // initialization example
            //
            // Showcase initialization methods for different matrix types and sizes.
            //

            // 3x3 matrix (set array value)
            Mat mat1 = new Mat (3, 3, CvType.CV_64FC1);
            mat1.put (0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
            Debug.Log ("mat1=" + mat1.dump());

            // 2x2 rotation matrix
            double angle = 30, a = Math.Cos(angle*Math.PI/180), b = Math.Sin(angle*Math.PI/180);
            Mat mat2 = new Mat (2, 2, CvType.CV_64FC1);
            mat2.put (0, 0, a, -b, b, a);
            Debug.Log ("mat2=" + mat2.dump());

            // 5x5 all 1's matrix
            Mat mat3 = Mat.ones(5, 5, CvType.CV_64FC1);
            Debug.Log ("mat3=" + mat3.dump());

            // 5x5 all zero's matrix
            Mat mat4 = Mat.zeros(5, 5, CvType.CV_64FC1);
            Debug.Log ("mat4=" + mat4.dump());

            // 5x5 identity matrix
            Mat mat5 = Mat.eye(5, 5, CvType.CV_64FC1);
            Debug.Log ("mat5=" + mat5.dump());

            // 3x3 initialize with a constant
            Mat mat6 = new Mat (3, 3, CvType.CV_64FC1, new Scalar(5));
            Debug.Log ("mat6=" + mat6.dump());

            // 3x2 initialize with a uniform distribution random number
            Mat mat7 = new Mat (3, 2, CvType.CV_8UC1);
            Core.randu (mat7, 0, 256);
            Debug.Log ("mat7=" + mat7.dump());

            // 3x2 initialize with a normal distribution random number
            Mat mat8 = new Mat (3, 2, CvType.CV_8UC1);
            Core.randn (mat8, 128, 10);
            Debug.Log ("mat8=" + mat8.dump());

            // 2x2x3x4 matrix (4 dimensional array)
            int[] sizes = new int[]{ 2, 2, 3, 4 };
            Mat mat9 = new Mat (sizes, CvType.CV_8UC1, Scalar.all (0));
            Debug.Log ("mat9.dims=" + mat9.dims());
            Debug.Log ("mat9.rows=" + mat9.rows () + " //When the matrix is more than 2-dimensional, the returned size is (-1, -1).");
            Debug.Log ("mat9.cols=" + mat9.cols ());
            

Execution Result:

mat1=[1, 2, 3;
 4, 5, 6;
 7, 8, 9]
mat2=[0.8660254037844387, -0.4999999999999999;
 0.4999999999999999, 0.8660254037844387]
mat3=[1, 1, 1, 1, 1;
 1, 1, 1, 1, 1;
 1, 1, 1, 1, 1;
 1, 1, 1, 1, 1;
 1, 1, 1, 1, 1]
mat4=[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]
mat5=[1, 0, 0, 0, 0;
 0, 1, 0, 0, 0;
 0, 0, 1, 0, 0;
 0, 0, 0, 1, 0;
 0, 0, 0, 0, 1]
mat6=[5, 5, 5;
 5, 5, 5;
 5, 5, 5]
mat7=[246, 156;
 192,   7;
 165, 231]
mat8=[124, 140;
 125, 122;
 131, 133]
mat9.dims=4
mat9.rows=-1 //When the matrix is more than 2-dimensional, the returned size is (-1, -1).
mat9.cols=-1

Multi Channel

Example Code:


            //
            // multi channel example
            //
            // Initialization of matrices with various numbers of channels, including those with four or more channels.
            //

            // 64F, channels=1, 3x3
            Mat mat1 = new Mat (3, 3, CvType.CV_64FC1);
            Debug.Log ("mat1");
            Debug.Log ("   dim:" + mat1.dims() + " elemSize1:" + mat1.elemSize1() + " channel:" + mat1.channels());

            // 64F, channels=10, 3x3
            Debug.Log ("mat2");
            Mat mat2 = new Mat (3, 3, CvType.CV_64FC(10));
            Debug.Log ("   dim:" + mat2.dims() + " elemSize1:" + mat2.elemSize1() + " channels:" + mat2.channels());

            // 64F, channles=1, 2x2x3x4 (4 dimensional array)
            Debug.Log ("mat3");
            int[] sizes = new int[]{ 2, 2, 3, 4 };
            Mat mat3 = new Mat (sizes, CvType.CV_64FC1);
            Debug.Log ("   dim:" + mat3.dims() + " elemSize1:" + mat3.elemSize1() + " channels:" + mat3.channels());
            

Execution Result:

mat1
   dim:2 elemSize1:8 channels:1
mat2
   dim:2 elemSize1:8 channels:10
mat3
   dim:4 elemSize1:8 channels:1

Dump

Example Code:

            //
            // dump example
            //

            // 8U, channels=1, 3x3
            Mat mat1 = new Mat (3, 3, CvType.CV_8UC1, new Scalar(1));

            // 8U, channels=4, 3x3
            Mat mat2 = new Mat (3, 3, CvType.CV_8UC4, new Scalar(1, 2, 3, 4));

            // dump
            Debug.Log (""mat1="" + mat1);
            Debug.Log (""mat1.dump()="" + mat1.dump());
            Debug.Log (""mat2="" + mat2);
            Debug.Log (""mat2.dump()="" + mat2.dump());

Execution Result:

mat1=Mat [ 3*3*CV_8UC1, isCont=True, isSubmat=False, nativeObj=0x793787296, dataAddr=0x794435328 ]
mat1.dump()=[  1,   1,   1;
   1,   1,   1;
   1,   1,   1]
mat2=Mat [ 3*3*CV_8UC4, isCont=True, isSubmat=False, nativeObj=0x793789648, dataAddr=0x799875584 ]
mat2.dump()=[  1,   2,   3,   4,   1,   2,   3,   4,   1,   2,   3,   4;
   1,   2,   3,   4,   1,   2,   3,   4,   1,   2,   3,   4;
   1,   2,   3,   4,   1,   2,   3,   4,   1,   2,   3,   4]

CVException handling

Example Code:


            // CVException handling example
            //
            // How to display Native-side OpenCV error logs in the Unity Editor Console.
            //

            // 32F, channels=1, 3x3
            Mat m1 = new Mat (3, 3, CvType.CV_32FC1);
            m1.put (0, 0, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f);

            // 8U, channels=1, 3x3
            Mat m2 = new Mat (3, 3, CvType.CV_8UC1);
            m2.put (0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);

            // dump
            Debug.Log ("m1=" + m1);
            Debug.Log ("m1.dump()=" + m1.dump ());
            Debug.Log ("m2=" + m2);
            Debug.Log ("m2.dump()=" + m2.dump ());

            // CVException handling
            // Publish CVException to Debug.LogError.
            Utils.setDebugMode (true, false);

            Mat m3 = m1 / m2;
            Debug.Log("m3=" + m3);

            Utils.setDebugMode (false);

            // Throw CVException.
            Utils.setDebugMode (true, true);
            try
            {
                Mat m4 = m1 / m2;
                Debug.Log("m4=" + m4);
            }
            catch (Exception e)
            {
                Debug.Log ("CVException: " + e);
            }
            Utils.setDebugMode (false);
            

Execution Result:

m1=Mat [ 3*3*CV_32FC1, isCont=True, isSubmat=False, nativeObj=0x1771604426912, dataAddr=0x1773914507648 ]
m1.dump()=[1, 2, 3;
 4, 5, 6;
 7, 8, 9]
m2=Mat [ 3*3*CV_8UC1, isCont=True, isSubmat=False, nativeObj=0x1771604425456, dataAddr=0x1770973091648 ]
m2.dump()=[  1,   2,   3;
   4,   5,   6;
   7,   8,   9]
m3=Mat [ -1*-1*CV_8UC1, isCont=False, isSubmat=False, nativeObj=0x1771604426688, dataAddr=0x0 ]
CVException: OpenCVForUnity.CoreModule.CvException: core::divide_12() : OpenCV(4.10.0-dev) C:\Users\xxxxxxxx\Desktop\opencv\modules\core\src\arithm.cpp:685: error: (-5:Bad argument) When the input arrays in add/subtract/multiply/divide functions have different types, the output array type must be explicitly specified in function 'cv::arithm_op'

  at OpenCVForUnity.UnityUtils.Utils.debugLogFunc (System.String str) [0x00026] in D:\_DESCTOP\Update_OpenCVForUnity\Assets\OpenCVForUnity\org\opencv\unity\Utils.cs:2128 
  at (wrapper native-to-managed) OpenCVForUnity.UnityUtils.Utils.debugLogFunc(intptr)
  at (wrapper managed-to-native) OpenCVForUnity.CoreModule.Core.core_Core_divide_12(intptr,intptr,intptr)
  at OpenCVForUnity.CoreModule.Core.divide (OpenCVForUnity.CoreModule.Mat src1, OpenCVForUnity.CoreModule.Mat src2, OpenCVForUnity.CoreModule.Mat dst) [0x0001b] in D:\_DESCTOP\Update_OpenCVForUnity\Assets\OpenCVForUnity\org\opencv\core\Core.cs:1217 
  at OpenCVForUnity.CoreModule.Mat.op_Division (OpenCVForUnity.CoreModule.Mat a, OpenCVForUnity.CoreModule.Mat b) [0x00006] in D:\_DESCTOP\Update_OpenCVForUnity\Assets\OpenCVForUnity\org\opencv\core\Mat_Ex.cs:9219 
  at OpenCVForUnityExample.MatBasicProcessingExample.OnCVExceptionHandlingExampleButtonClick () [0x001bb] in D:\_DESCTOP\Update_OpenCVForUnity\Assets\OpenCVForUnity\Examples\Basic\MatBasicProcessingExample\MatBasicProcessingExample.cs:337 

Property

Example Code:


            //
            // property example
            //
            // List the properties of an OpenCV matrix.
            //

            // 64F, channels=1, 3x4
            Mat mat1 = new Mat (3, 4, CvType.CV_64FC1);

            // number of rows
            Debug.Log ("rows:" + mat1.rows ());
            // number of columns
            Debug.Log ("cols:" + mat1.cols ());
            // number of dimensions
            Debug.Log ("dims:" + mat1.dims ());
            // size
            Debug.Log ("size[]:" + mat1.size ().width + ", " + mat1.size ().height);
            // bit depth ID
            Debug.Log ("depth (ID):" + mat1.depth () + "(=" + CvType.CV_64F + ")");
            // number of channels
            Debug.Log ("channels:" + mat1.channels ());
            // size of one element
            Debug.Log ("elemSize:" + mat1.elemSize () + "[byte]");
            // size for one channel in one element
            Debug.Log ("elemSize1 (elemSize/channels):" + mat1.elemSize1 () + "[byte]");
            // total number of elements
            Debug.Log ("total:" + mat1.total ());
            // size of step
            Debug.Log ("step (step1*elemSize1):" + mat1.step1 () * mat1.elemSize1 () + "[byte]");
            // total number of channels within one step
            Debug.Log ("step1 (step/elemSize1):" + mat1.step1 ());
            // is the data continuous?
            Debug.Log ("isContinuous:" + mat1.isContinuous ());
            // is it a submatrix?
            Debug.Log ("isSubmatrix:" + mat1.isSubmatrix ());
            // is the data empty?
            Debug.Log ("empty:" + mat1.empty ());

            Debug.Log ("==============================");


            // 32FC, channels=5, 4x5, 3x4 Submatrix
            Mat mat2 = new Mat (4, 5, CvType.CV_32FC (5));
            OpenCVForUnity.CoreModule.Rect roi_rect = new OpenCVForUnity.CoreModule.Rect (0, 0, 3, 4);
            Mat r1 = new Mat (mat2, roi_rect);

            // number of rows
            Debug.Log ("rows:" + r1.rows ());
            // number of columns
            Debug.Log ("cols:" + r1.cols ());
            // number of dimensions
            Debug.Log ("dims:" + r1.dims ());
            // size
            Debug.Log ("size[]:" + r1.size ().width + ", " + r1.size ().height);
            // bit depth ID
            Debug.Log ("depth (ID):" + r1.depth () + "(=" + CvType.CV_32F + ")");
            // number of channels
            Debug.Log ("channels:" + r1.channels ());
            // size of one element
            Debug.Log ("elemSize:" + r1.elemSize () + "[byte]");
            // size for one channel in one element
            Debug.Log ("elemSize1 (elemSize/channels):" + r1.elemSize1 () + "[byte]");
            // total number of elements
            Debug.Log ("total:" + r1.total ());
            // size of step
            Debug.Log ("step (step1*elemSize1):" + r1.step1 () * r1.elemSize1 () + "[byte]");
            // total number of channels within one step
            Debug.Log ("step1 (step/elemSize1):" + r1.step1 ());
            // is the data continuous?
            Debug.Log ("isContinuous:" + r1.isContinuous ());
            // is it a submatrix?
            Debug.Log ("isSubmatrix:" + r1.isSubmatrix ());
            // is the data empty?
            Debug.Log ("empty:" + r1.empty ());

            Debug.Log ("==============================");


            // 32S, channles=2, 2x3x3x4x6 (5 dimensional array)
            int[] sizes = new int[]{ 2, 3, 3, 4, 6 };
            Mat mat3 = new Mat (sizes, CvType.CV_32SC2);

            // number of rows
            Debug.Log ("rows:" + mat3.rows ());
            // number of columns
            Debug.Log ("cols:" + mat3.cols ());
            // number of dimensions
            Debug.Log ("dims:" + mat3.dims ());
            // size
            string size = "";
            for (int i = 0; i < mat3.dims (); ++i) {
                size += mat3.size (i) + ", ";
            }                
            Debug.Log ("size[]:" + size);
            // bit depth ID
            Debug.Log ("depth (ID):" + mat3.depth () + "(=" + CvType.CV_32S + ")");
            // number of channels
            Debug.Log ("channels:" + mat3.channels ());
            // size of one element
            Debug.Log ("elemSize:" + mat3.elemSize () + "[byte]");
            // size for one channel in one element
            Debug.Log ("elemSize1 (elemSize/channels):" + mat3.elemSize1 () + "[byte]");
            // total number of elements
            Debug.Log ("total:" + mat3.total ());
            // size of step
            string step = "";
            for (int i = 0; i < mat3.dims (); ++i) {
                step += mat3.step1 (i) * mat3.elemSize1 () + ", ";
            } 
            Debug.Log ("step (step1*elemSize1):" + step + "[byte]");
            // total number of channels within one step
            Debug.Log ("step1 (step/elemSize1):" + mat3.step1 ());
            // is the data continuous?
            Debug.Log ("isContinuous:" + mat3.isContinuous ());
            // is it a submatrix?
            Debug.Log ("isSubmatrix:" + mat3.isSubmatrix ());
            // is the data empty?
            Debug.Log ("empty:" + mat3.empty ());
            

Execution Result:

rows:3
cols:4
dims:2
size[]:4, 3
depth (ID):6(=6)
channels:1
elemSize:8[byte]
elemSize1 (elemSize/channels):8[byte]
total:12
step (step1*elemSize1):32[byte]
step1 (step/elemSize1):4
isContinuous:True
isSubmatrix:False
empty:False
==============================
rows:4
cols:3
dims:2
size[]:3, 4
depth (ID):5(=5)
channels:5
elemSize:20[byte]
elemSize1 (elemSize/channels):4[byte]
total:12
step (step1*elemSize1):100[byte]
step1 (step/elemSize1):25
isContinuous:False
isSubmatrix:True
empty:False
==============================
rows:-1
cols:-1
dims:5
size[]:2, 3, 3, 4, 6, 
depth (ID):4(=4)
channels:2
elemSize:8[byte]
elemSize1 (elemSize/channels):4[byte]
total:432
step (step1*elemSize1):1728, 576, 192, 48, 8, [byte]
step1 (step/elemSize1):432
isContinuous:True
isSubmatrix:False
empty:False

Four arithmetic operation

Example Code:


            //
            // four arithmetic operation example
            //
            // Performs four arithmetic methods on matrices.
            //

            // 3x3 matrix
            Mat m1 = new Mat(3, 3, CvType.CV_64FC1);
            m1.put(0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
            Mat m2 = new Mat(3, 3, CvType.CV_64FC1);
            m2.put(0, 0, 10, 11, 12, 13, 14, 15, 16, 17, 18);
            // Scalar
            Scalar s = new Scalar(5);
            // alpha
            double alpha = 3;

            Debug.Log("m1 = " + m1.dump());
            Debug.Log("m2=" + m2.dump());
            Debug.Log("s=" + s);
            Debug.Log("alpha=" + alpha);

            Mat m_dst = new Mat();

            // Addition, subtraction, negation: A+B, A-B, A+s, A-s, s+A, s-A, -A
            Core.add(m1, m2, m_dst);
            Debug.Log("m1+m2=" + m_dst.dump());
            Core.add(m1, s, m_dst);
            Debug.Log("m1+s=" + m_dst.dump());

            Core.subtract(m1, m2, m_dst);
            Debug.Log("m1-m2=" + m_dst.dump());
            Core.subtract(m1, s, m_dst);
            Debug.Log("m1-s=" + m_dst.dump());

            Core.multiply(m1, Scalar.all(-1), m_dst);
            Debug.Log("-m1=" + m_dst.dump());


            // Scaling: A*alpha A/alpha
            Core.multiply(m1, Scalar.all(3), m_dst);
            Debug.Log("m1*alpha=" + m_dst.dump());
            Core.divide(m1, Scalar.all(3), m_dst);
            Debug.Log("m1/alpha=" + m_dst.dump());


            // Per-element multiplication and division: A.mul(B), A/B, alpha/A
            Debug.Log("m1.mul(m2)=" + (m1.mul(m2)).dump());

            Core.divide(m1, m2, m_dst);
            Debug.Log("m1/m2=" + m_dst.dump());

            Core.divide(new Mat(m1.size(), m1.type(), Scalar.all(3)), m1, m_dst);
            Debug.Log("alpha/m2=" + m_dst.dump());


            // Matrix multiplication: A*B
            Core.gemm(m1, m2, 1, new Mat(), 0, m_dst);
            Debug.Log("m1*m2=" + m_dst.dump());


            // Bitwise logical operations: A logicop B, A logicop s, s logicop A, ~A, where logicop is one of :  &, |, ^.
            Core.bitwise_and(m1, m2, m_dst);
            Debug.Log("m1&m2=" + m_dst.dump());

            Core.bitwise_or(m1, m2, m_dst);
            Debug.Log("m1|m2=" + m_dst.dump());

            Core.bitwise_xor(m1, m2, m_dst);
            Debug.Log("m1^m2=" + m_dst.dump());

            Core.bitwise_not(m1, m_dst);
            Debug.Log("~m1=" + m_dst.dump());
            

Execution Result:

m1=[1, 2, 3;
 4, 5, 6;
 7, 8, 9]
m2=[10, 11, 12;
 13, 14, 15;
 16, 17, 18]
s=[5, 0, 0, 0]
alpha=3
m1+m2=[11, 13, 15;
 17, 19, 21;
 23, 25, 27]
m1+s=[6, 7, 8;
 9, 10, 11;
 12, 13, 14]
m1-m2=[-9, -9, -9;
 -9, -9, -9;
 -9, -9, -9]
m1-s=[-4, -3, -2;
 -1, 0, 1;
 2, 3, 4]
-m1=[-1, -2, -3;
 -4, -5, -6;
 -7, -8, -9]
m1*alpha=[3, 6, 9;
 12, 15, 18;
 21, 24, 27]
m1/alpha=[0.3333333333333333, 0.6666666666666666, 1;
 1.333333333333333, 1.666666666666667, 2;
 2.333333333333333, 2.666666666666667, 3]
m1.mul(m2)=[10, 22, 36;
 52, 70, 90;
 112, 136, 162]
m1/m2=[0.1, 0.1818181818181818, 0.25;
 0.3076923076923077, 0.3571428571428572, 0.4;
 0.4375, 0.4705882352941176, 0.5]
alpha/m2=[3, 1.5, 1;
 0.75, 0.6, 0.5;
 0.4285714285714285, 0.375, 0.3333333333333333]
m1*m2=[84, 90, 96;
 201, 216, 231;
 318, 342, 366]
m1&m2=[4.450147717014403e-308, 2, 3;
 2, 2.5, 3;
 4, 8, 9]
m1|m2=[nan(snan), 11, 12;
 26, 28, 30;
 28, 17, 18]
m1^m2=[5.617791046444737e+307, 6.118953110894804e-308, 4.450147717014403e-308;
 1.446298008029681e-307, 1.335044315104321e-307, 1.223790622178961e-307;
 7.787758504775205e-308, 2.364140974663901e-308, 2.225073858507201e-308]
~m1=[-4, -2, -1.5;
 -0.9999999999999999, -0.8749999999999999, -0.7499999999999999;
 -0.6249999999999999, -0.4999999999999999, -0.4687499999999999]

ConvertTo

Example Code:


            //
            // convertTo example
            //
            // The Core.convertTo function changes the data type or scale of a Mat object.
            // It is used in various situations in image processing, such as converting between different data types or adjusting the brightness of an image.
            //

            // 64F, channels=1, 3x3
            Mat m1 = new Mat (3, 3, CvType.CV_64FC1);
            m1.put (0, 0, 1.1, 1.2, 1.3, 2.1, 2.2, 2.3, 3.1, 3.2, 3.3);
            Debug.Log ("m1=" + m1.dump());

            // 64F -> 8U (dst mat, type)
            Mat m2 = new Mat ();
            m1.convertTo (m2, CvType.CV_8U);
            Debug.Log ("m2=" + m2.dump());

            // 64F -> 8U (dst mat, type, scale factor, added to the scaled value)
            Mat m3 = new Mat ();
            m1.convertTo (m3, CvType.CV_8U, 2, 10);
            Debug.Log ("m3=" + m3.dump());
            

Execution Result:

m1=[1.1, 1.2, 1.3;
 2.1, 2.2, 2.3;
 3.1, 3.2, 3.3]
m2=[  1,   1,   1;
   2,   2,   2;
   3,   3,   3]
m3=[ 12,  12,  13;
  14,  14,  15;
  16,  16,  17]

Reshape

Example Code:


            //
            // reshape example
            //
            // Changes the shape and/or the number of channels of a  matrix without copying the data.
            // The method makes a new matrix header for this elements.The new matrix may have a different size and / or different number of channels.Any combination is possible if:
            // - No extra elements are included into the new matrix and no elements are excluded.Consequently, the product rows* cols*channels() must stay the same after the transformation.
            // - No data is copied.That is, this is an O(1) operation.Consequently, if you change the number of rows, or the operation changes the indices of elements row in some other way, the matrix must be continuous.See "Mat.isContinuous".
            //

            // 64F, channels=1, 3x4
            Mat m1 = new Mat (3, 4, CvType.CV_64FC1);
            m1.put (0, 0, 1,2,3,4,5,6,7,8,9,10,11,12);
            Debug.Log ("m1=" + m1.dump());
            Debug.Log ("ch=" + m1.channels());

            // channels=1, 3x4 -> channels=2, 3x2
            Mat m2 = m1.reshape (2);
            Debug.Log ("m2=" + m2.dump ());
            Debug.Log ("ch=" + m2.channels ());

            // channels=1, 3x4 -> channels=1, 2x6
            Mat m3 = m1.reshape (1, 2);
            Debug.Log ("m3=" + m3.dump ());
            Debug.Log ("ch=" + m3.channels ());

            // 2D -> 4D
            Mat src = new Mat (6, 5, CvType.CV_8UC3, new Scalar (0));
            Mat m4 = src.reshape (1, new int[]{ 1, src.channels () * src.cols (), 1, src.rows () });
            Debug.Log ("m4.dims=" + m4.dims ());
            string size = "";
            for (int i = 0; i < m4.dims (); ++i) {
                size += m4.size (i) + ", ";
            }                
            Debug.Log ("size[]=" + size);
            Debug.Log ("ch=" + m4.channels ());

            // 3D -> 2D
            src = new Mat (new int[]{ 4, 6, 7 }, CvType.CV_8UC3, new Scalar (0));
            Mat m5 = src.reshape (1, new int[]{ src.channels () * src.size (2), src.size (0) * src.size (1) });
            Debug.Log ("m5=" + m5);           
            Debug.Log ("ch=" + m5.channels ());
            

Execution Result:

m1=[1, 2, 3, 4;
 5, 6, 7, 8;
 9, 10, 11, 12]
ch=1
m2=[1, 2, 3, 4;
 5, 6, 7, 8;
 9, 10, 11, 12]
ch=2
m3=[1, 2, 3, 4, 5, 6;
 7, 8, 9, 10, 11, 12]
ch=1
m4.dims=4
m4.size[]=1, 15, 1, 6, 
ch=1
m5=Mat [ 21*24*CV_8UC1, isCont=True, isSubmat=False, nativeObj=0x1771604425120, dataAddr=0x1771008921216 ]
ch=1

Transpose

Example Code:


            //
            // transpose example
            //
            // The Core.transpose function can be used for various image processing tasks such as rotating images by 90 degrees and changing the shape of matrices by swapping rows and columns of Mat.
            // - The Core.transpose function is a function that performs a transposition operation on a two-dimensional matrix.
            // - The Core.transposeND function is a function that performs a transposition operation on a tensor of arbitrary dimensions.For example, it can be used to swap specific dimensions of a 3D tensor(such as video data).
            //

            // Transposes a matrix.
            // 8U, channels=1, 3x4
            Mat m1 = new Mat(3, 4, CvType.CV_8UC1);
            m1.put(0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
            Debug.Log("m1 = " + m1.dump());

            // [3x4] -> [4x3]
            Mat m1_t = new Mat();
            Core.transpose(m1, m1_t);
            Debug.Log("Core.transpose(m1, m1_t)=" + m1_t.dump());

            // Transpose for n-dimensional matrices.
            // 32F, channels=1, 1x3x4x3
            Mat m2 = new Mat(new int[] { 1, 3, 4, 3 }, CvType.CV_32FC1);
            m2.put(new int[] { 0, 0, 0, 0 }, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
            string m2_size = ";
            for (int i = 0; i < m2.dims(); ++i)
            {
                m2_size += m2.size(i) + ", ";
            }
            Debug.Log("m2=" + m2.reshape(3, new int[] { 3, 4 }).dump());
            Debug.Log("m2 size[]=" + m2_size);

            // [1x3x4x3] -> [1x4x3x3]
            Mat m2_t = new Mat();
            MatOfInt order = new MatOfInt(0, 2, 1, 3); // Transpose order
            Core.transposeND(m2, order, m2_t);
            string m2_t_size = ";
            for (int i = 0; i < m2_t.dims(); ++i)
            {
                m2_t_size += m2_t.size(i) + ", ";
            }
            Debug.Log("Core.transposeND(m2, m2_t)=" + m2_t.reshape(3, new int[] { 4, 3 }).dump());
            Debug.Log("m2_t size[]=" + m2_t_size);
            

Execution Result:

m1=[  1,   2,   3,   4;
   5,   6,   7,   8;
   9,  10,  11,  12]
Core.transpose(m1, m1_t)=[  1,   5,   9;
   2,   6,  10;
   3,   7,  11;
   4,   8,  12]
m2=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12;
 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12;
 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
m2 size[]=1, 3, 4, 3, 
Core.transposeND(m2, m2_t)=[1, 2, 3, 1, 2, 3, 1, 2, 3;
 4, 5, 6, 4, 5, 6, 4, 5, 6;
 7, 8, 9, 7, 8, 9, 7, 8, 9;
 10, 11, 12, 10, 11, 12, 10, 11, 12]
m2_t size[]=1, 4, 3, 3, 

Range

Example Code:


            //
            // range example
            //
            // Mat.rowRange and Mat.colRange efficiently extract submatrices from a Mat by creating new Mat headers that point to specified row or column ranges of the original data, without copying the underlying data.
            //

            // 64F, channels=1, 3x3
            Mat m1 = new Mat (3, 3, CvType.CV_64FC1);
            m1.put (0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
            Debug.Log ("m1=" + m1.dump());

            // all rows
            Debug.Log ("m1.rowRange(Range.all())=" + m1.rowRange(Range.all()).dump());

            // rowRange(0,2)
            Debug.Log ("m1.rowRange(new Range(0,2))=" + m1.rowRange(new Range(0,2)).dump());

            // row(0)
            Debug.Log ("m1.row(0)=" + m1.row(0).dump());

            // all cols
            Debug.Log ("m1.colRange(Range.all())=" + m1.colRange(Range.all()).dump());

            // colRange(0,2)
            Debug.Log ("m1.colRange(new Range(0,2))=" + m1.colRange(new Range(0,2)).dump());

            // col(0)
            Debug.Log ("m1.col(0)=" + m1.col(0).dump());
            

Execution Result:

m1=[1, 2, 3;
 4, 5, 6;
 7, 8, 9]
m1.rowRange(Range.all())=[1, 2, 3;
 4, 5, 6;
 7, 8, 9]
m1.rowRange(new Range(0,2))=[1, 2, 3;
 4, 5, 6]
m1.row(0)=[1, 2, 3]
m1.colRange(Range.all())=[1, 2, 3;
 4, 5, 6;
 7, 8, 9]
m1.colRange(new Range(0,2))=[1, 2;
 4, 5;
 7, 8]
m1.col(0)=[1;
 4;
 7]

submatrix (ROI)

Example Code:


            //
            // submatrix (ROI) example
            //
            // A submatrix (Region of Interest, ROI) is a region cut out of an image or matrix. OpenCV allows you to create a submatrix that manipulates only that region without copying the original data.
            //

            // 3x3 matrix
            Mat m1 = new Mat (3, 3, CvType.CV_64FC1);
            m1.put (0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
            Debug.Log ("m1=" + m1.dump ());

            // get submatrix (ROI) of range (row[0_2] col[0_2])
            Mat m2 = new Mat (m1, new OpenCVForUnity.CoreModule.Rect(0,0,2,2));
            Debug.Log ("m2=" + m2.dump());
            Debug.Log ("m2.submat()=" + m2.submat(0,2,0,2).dump());

            // find the parent matrix size of the submatrix (ROI) m2 and its position in it
            Size wholeSize = new Size ();
            Point ofs = new Point ();
            m2.locateROI (wholeSize, ofs);
            Debug.Log ("wholeSize:" + wholeSize.width + "x" + wholeSize.height);
            Debug.Log ("offset:" + ofs.x + ", " + ofs.y);

            // expand the range of submatrix (ROI)
            m2.adjustROI(0, 1, 0, 1);
            Debug.Log ("rows=" + m2.rows() + ", " + "cols=" + m2.cols());
            Debug.Log ("m2=" + m2.dump());
            

Execution Result:

m1=[1, 2, 3;
 4, 5, 6;
 7, 8, 9]
m2=[1, 2;
 4, 5]
m2.submat()=[1, 2;
 4, 5]
wholeSize:3x3
offset:0, 0
rows=3, cols=3
m2=[1, 2, 3;
 4, 5, 6;
 7, 8, 9]