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