Mat Basic Processing1

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

Initialization

Example Code:

            //
            // initialization example
            //

            // 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 () + "" //For Mats of 3 dimensions or more, rows == cols == -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 //For Mats of 3 dimensions or more, rows == cols == -1
mat9.cols=-1

Malti Channel

Example Code:

            //
            // multi channel example
            //

            // 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 channel:1
mat2
   dim:2 elemSize1:8 channels:10
mat2
   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
            //

            // 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 ());

            #if UNITY_STANDALONE || UNITY_EDITOR
            // Publish CVException to Debug.LogError.
            Utils.setDebugMode (true, false);
            Mat m3 = m1 / m2;
            Utils.setDebugMode (false);

            // Throw CVException.
            Utils.setDebugMode (true, true);
            try
            {
                Mat m4 = m1 / m2;
            }
            catch (Exception e)
            {
                Debug.Log (""CVException: "" + e);
            }
            Utils.setDebugMode (false);
            #else
            Debug.Log (""The setDebugMode method is only supported on WIN, MAC and LINUX."");
            #endif

Execution Result:

m1=Mat [ 3*3*CV_32FC1, isCont=True, isSubmat=False, nativeObj=0x820637680, dataAddr=0x820295296 ]
m1.dump()=[1, 2, 3;
 4, 5, 6;
 7, 8, 9]
m2=Mat [ 3*3*CV_8UC1, isCont=True, isSubmat=False, nativeObj=0x820637792, dataAddr=0x820619712 ]
m2.dump()=[  1,   2,   3;
   4,   5,   6;
   7,   8,   9]
core::divide_12() : OpenCV(3.4.1-dev) C:\Users\xxxxx\Desktop\opencv\modules\core\src\arithm.cpp:683: error: (-5) 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
m3=Mat [ 0*0*CV_8UC1, isCont=False, isSubmat=False, nativeObj=0x820637568, dataAddr=0x0 ]
CVException: OpenCVForUnity.CvException: core::divide_12() : OpenCV(3.4.1-dev) C:\Users\satoo\Desktop\opencv\modules\core\src\arithm.cpp:683: error: (-5) 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

Property

Example Code:

            //
            // property example
            //

            // 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
            //

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

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

            // matrix and scalar
            Mat m2 = m1 + new Scalar (3);
            Mat m3 = m1 - new Scalar (3);
            Mat m4 = m1 * 3; //scaling
            Mat m5 = m1 / 3;

            Debug.Log (""m1+3="" + m2.dump ());
            Debug.Log (""m1-3="" + m3.dump ());
            Debug.Log (""m1*3="" + m4.dump ());
            Debug.Log (""m1/3="" + m5.dump ());

            // matrix and matrix
            Mat m6 = m1 + m1;
            Mat m7 = m1.mul(m2);
            Mat m8 = m1.mul(m2, 2); //add scaling factor

            // CVException handling
            // 8U, channels=1, 3x3
            Mat m9 = new Mat (3, 3, CvType.CV_8UC1);
            m9.put (0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
            // 64F, channels=1, 3x3
            Mat m10 = new Mat (2, 2, CvType.CV_64FC1);
            m10.put (0, 0, 1.0, 2.0, 3.0, 4.0);

            #if UNITY_STANDALONE || UNITY_EDITOR
            // Publish CVException to Debug.LogError.
            Utils.setDebugMode (true, false);			
            Mat m11 = m1 / m9; // element type is different.
            Mat m12 = m1 / m10; // matrix size is different.
            Utils.setDebugMode (false);
            #else
            Debug.Log (""The setDebugMode method is only supported on WIN, MAC and LINUX."");
            #endif

Execution Result:

m1=[1, 2, 3;
 4, 5, 6;
 7, 8, 9]
m1+3=[4, 5, 6;
 7, 8, 9;
 10, 11, 12]
m1-3=[-2, -1, 0;
 1, 2, 3;
 4, 5, 6]
m1*3=[3, 6, 9;
 12, 15, 18;
 21, 24, 27]
m1/3=[0.3333333333333333, 0.6666666666666666, 1;
 1.333333333333333, 1.666666666666667, 2;
 2.333333333333333, 2.666666666666667, 3]
m1+m1=[2, 4, 6;
 8, 10, 12;
 14, 16, 18]
m1.mul(m2)=[4, 10, 18;
 28, 40, 54;
 70, 88, 108]
m1.mul(m2, 2)=[8, 20, 36;
 56, 80, 108;
 140, 176, 216]
core::divide_12() : OpenCV(3.4.1-dev) C:\Users\xxxxx\Desktop\opencv\modules\core\src\arithm.cpp:683: error: (-5) 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
m1/m9=Mat [ 0*0*CV_8UC1, isCont=False, isSubmat=False, nativeObj=0x362016240, dataAddr=0x0 ]
core::divide_12() : OpenCV(3.4.1-dev) C:\Users\xxxxx\Desktop\opencv\modules\core\src\arithm.cpp:659: error: (-209) The operation is neither 'array op array' (where arrays have the same size and the same number of channels), nor 'array op scalar', nor 'scalar op array' in function cv::arithm_op
m1/m10=Mat [ 0*0*CV_8UC1, isCont=False, isSubmat=False, nativeObj=0x362017248, dataAddr=0x0 ]

ConvertTo

Example Code:

            //
            // convertTo example
            //

            // 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());

            // dst mat, type
            Mat m2 = new Mat ();
            m1.convertTo (m2, CvType.CV_8U);
            Debug.Log (""m2="" + m2.dump());

            // 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
            //

            // 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
size[]=1, 15, 1, 6, 
ch=1
m5=Mat [ 21*24*CV_8UC1, isCont=True, isSubmat=False, nativeObj=0x1029520976, dataAddr=0x245768128 ]
ch=1

Range

Example Code:

            //
            // range example
            //

            // 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]

Shallow Copy And Deep Copy

Example Code:

            //
            // shallow copy and deep copy example
            //

            // 3x3 matrix
            Mat mat1 = new Mat (3, 3, CvType.CV_64FC1);
            mat1.put (0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);

            // shallow copy
            Mat m_shallow = mat1;

            // deep copy (clone, copyTo)
            Mat m_deep1 = mat1.clone();
            Mat m_deep2 = new Mat();
            mat1.copyTo (m_deep2);

            Debug.Log (""mat1="" + mat1.dump());
            Debug.Log (""m_shallow="" + m_shallow.dump());
            Debug.Log (""m_deep1="" + m_deep1.dump());
            Debug.Log (""m_deep2="" + m_deep2.dump());

            // rewrite (0, 0) element of matrix mat1
            mat1.put(0, 0, 100);

            Debug.Log (""mat1="" + mat1.dump());
            Debug.Log (""m_shallow="" + m_shallow.dump());
            Debug.Log (""m_deep1="" + m_deep1.dump());
            Debug.Log (""m_deep2="" + m_deep2.dump());

            Debug.Log (""mat1.Equals(m_shallow)="" + mat1.Equals(m_shallow));
            Debug.Log (""mat1.Equals(m_deep1)="" + mat1.Equals(m_deep1));
            Debug.Log (""mat1.Equals(m_deep2)="" + mat1.Equals(m_deep2));

Execution Result:

mat1=[1, 2, 3;
 4, 5, 6;
 7, 8, 9]
m_shallow=[1, 2, 3;
 4, 5, 6;
 7, 8, 9]
m_deep1=[1, 2, 3;
 4, 5, 6;
 7, 8, 9]
m_deep2=[1, 2, 3;
 4, 5, 6;
 7, 8, 9]
mat1=[100, 2, 3;
 4, 5, 6;
 7, 8, 9]
m_shallow=[100, 2, 3;
 4, 5, 6;
 7, 8, 9]
m_deep1=[1, 2, 3;
 4, 5, 6;
 7, 8, 9]
m_deep2=[1, 2, 3;
 4, 5, 6;
 7, 8, 9]
mat1.Equals(m_shallow)=True
mat1.Equals(m_deep1)=False
mat1.Equals(m_deep2)=False