Mat Basic Processing2

Merge

Example Code:

            //
            // simple composition: Merge example
            //

            // 2x2 matrix
            Mat m1 = new Mat (2, 2, CvType.CV_64FC1);
            m1.put (0, 0, 1.0, 2.0, 3.0, 4.0);
            Mat m2 = new Mat (2, 2, CvType.CV_64FC1);
            m2.put (0, 0, 1.1, 2.1, 3.1, 4.1);
            Mat m3 = new Mat (2, 2, CvType.CV_64FC1);
            m3.put (0, 0, 1.2, 2.2, 3.2, 4.2);

            List<Mat> mv = new List<Mat>();
            mv.Add (m1);
            mv.Add (m2);
            mv.Add (m3);

            // merge
            Mat m_merged = new Mat();
            Core.merge (mv, m_merged);

            // dump
            Debug.Log (""m_merged="" + m_merged.dump());

Execution Result:

m_merged=[1, 1.1, 1.2, 2, 2.1, 2.2;
 3, 3.1, 3.2, 4, 4.1, 4.2]

MixChannels

Example Code:

            //
            // complex composition: mixChannels example
            //

            // 2x2 matrix
            Mat m1 = new Mat (2, 2, CvType.CV_64FC1);
            m1.put (0, 0, 1.0, 2.0, 3.0, 4.0);
            Mat m2 = new Mat (2, 2, CvType.CV_64FC1);
            m2.put (0, 0, 1.1, 2.1, 3.1, 4.1);
            Mat m3 = new Mat (2, 2, CvType.CV_64FC1);
            m3.put (0, 0, 1.2, 2.2, 3.2, 4.2);

            List<Mat> mv = new List<Mat>();
            mv.Add (m1);
            mv.Add (m2);
            mv.Add (m3);

            // mat for output must be allocated.
            Mat m_mixed1 = new Mat(2, 2, CvType.CV_64FC2);
            Mat m_mixed2 = new Mat(2, 2, CvType.CV_64FC2);
            MatOfInt fromTo = new MatOfInt (0,0, 1,1, 1,3, 2,2);

            List<Mat> mixv = new List<Mat> ();
            mixv.Add (m_mixed1);
            mixv.Add (m_mixed2);

            // mix
            Core.mixChannels (mv, mixv, fromTo);

            // dump
            Debug.Log (""m_mixed1="" + m_mixed1.dump());
            Debug.Log (""m_mixed2="" + m_mixed2.dump());

Execution Result:

m_mixed1=[1, 1.1, 2, 2.1;
 3, 3.1, 4, 4.1]
m_mixed2=[1.2, 1.1, 2.2, 2.1;
 3.2, 3.1, 4.2, 4.1]

Split

Example Code:

            //
            // split example
            //

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

            List<Mat> planes = new List<Mat>();

            // split
            Core.split (m1, planes);

            // dump
            foreach (Mat item in planes) {
                Debug.Log (item.dump());
            }

Execution Result:

[1, 4, 7;
 10, 13, 16]
[2, 5, 8;
 11, 14, 17]
[3, 6, 9;
 12, 15, 18]

Reduce

Example Code:

            //
            // reduce example
            //

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

            Mat v1 = new Mat ();
            Mat v2 = new Mat ();
            Mat v3 = new Mat ();
            Mat v4 = new Mat ();

            // reduce 3 x 3 matrix to one row
            Core.reduce (m1, v1, 0, Core.REDUCE_SUM); // total value of each column
            Core.reduce (m1, v2, 0, Core.REDUCE_AVG); // total average value of each column
            Core.reduce (m1, v3, 0, Core.REDUCE_MIN); // minimum value of each column
            Core.reduce (m1, v4, 0, Core.REDUCE_MAX); // maximum value of each column

            // dump
            Debug.Log (""m1="" + m1.dump());
            Debug.Log (""v1(sum)="" + v1.dump());
            Debug.Log (""v2(avg)="" + v2.dump());
            Debug.Log (""v3(min)="" + v3.dump());
            Debug.Log (""v4(max)="" + v4.dump());

            // reduce 3 x 3 matrix to one col
            Core.reduce (m1, v1, 1, Core.REDUCE_SUM); // total value of each row
            Core.reduce (m1, v2, 1, Core.REDUCE_AVG); // total average value of row
            Core.reduce (m1, v3, 1, Core.REDUCE_MIN); // minimum value of each row
            Core.reduce (m1, v4, 1, Core.REDUCE_MAX); // maximum value of each row

            // dump
            Debug.Log (""m1="" + m1.dump());
            Debug.Log (""v1(sum)="" + v1.dump());
            Debug.Log (""v2(avg)="" + v2.dump());
            Debug.Log (""v3(min)="" + v3.dump());
            Debug.Log (""v4(max)="" + v4.dump());

Execution Result:

m1=[1, 5, 3;
 4, 2, 6;
 7, 8, 9]
v1(sum)=[12, 15, 18]
v2(avg)=[4, 5, 6]
v3(min)=[1, 2, 3]
v4(max)=[7, 8, 9]
m1=[1, 5, 3;
 4, 2, 6;
 7, 8, 9]
v1(sum)=[9;
 12;
 24]
v2(avg)=[3;
 4;
 8]
v3(min)=[1;
 2;
 7]
v4(max)=[5;
 6;
 9]

Submatrix

Example Code:

            //
            // submatrix (ROI) example
            //

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

RandShuffle

Example Code:

            //
            // randShuffle example
            //

            // 4x5 matrix
            Mat m1 = new Mat (4, 5, CvType.CV_64FC1);
            m1.put (0, 0, 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20);
            Debug.Log (""m1(original)="" + m1.dump ());

            // shuffle
            Core.randShuffle (m1, UnityEngine.Random.value);
            Debug.Log (""m1(shuffle)="" + m1.dump ());

            // submatrix
            Mat m2 = new Mat (m1, new OpenCVForUnity.Rect(1,1,3,2));
            Debug.Log (""m2(sub-matrix)="" + m2.dump());

            Core.randShuffle (m2, UnityEngine.Random.value);
            Debug.Log (""m2(sub-matrix)="" + m2.dump());
            Debug.Log (""m1="" + m1.dump ());

Execution Result:

m1(original)=[1, 2, 3, 4, 5;
 6, 7, 8, 9, 10;
 11, 12, 13, 14, 15;
 16, 17, 18, 19, 20]
m1(shuffle)=[7, 5, 20, 3, 2;
 11, 1, 13, 17, 4;
 12, 19, 14, 6, 16;
 10, 8, 9, 18, 15]
m2(sub-matrix)=[1, 13, 17;
 19, 14, 6]
m2(shuffle sub-matrix)=[1, 6, 19;
 14, 13, 17]
m1=[7, 5, 20, 3, 2;
 11, 1, 6, 19, 4;
 12, 14, 13, 17, 16;
 10, 8, 9, 18, 15]

Sort

Example Code:

            //
            // sort example
            //

            // 5x5 matrix
            Mat m1 = new Mat (5, 5, CvType.CV_8UC1);
            Core.randu (m1, 0, 25);
            Debug.Log (""m1="" + m1.dump ());

            executionResultText.text = ""m1="" + m1.dump() + ""\n"";

            Mat dst_mat = new Mat ();

            // sort ascending
            Core.sort (m1, dst_mat, Core.SORT_EVERY_ROW|Core.SORT_ASCENDING);
            Debug.Log (""ROW|ASCENDING:"" + dst_mat.dump ());

            // sort descending
            Core.sort (m1, dst_mat, Core.SORT_EVERY_ROW|Core.SORT_DESCENDING);
            Debug.Log (""ROW|DESCENDING:"" + dst_mat.dump ());

            // sort ascending
            Core.sort (m1, dst_mat, Core.SORT_EVERY_COLUMN|Core.SORT_ASCENDING);
            Debug.Log (""COLUMN|ASCENDING:"" + dst_mat.dump ());

            // sort descending
            Core.sort (m1, dst_mat, Core.SORT_EVERY_COLUMN|Core.SORT_DESCENDING);
            Debug.Log (""COLUMN|DESCENDING:"" + dst_mat.dump ());

Execution Result:

m1=[ 21,   6,  12,  22,   1;
  21,  10,  22,  23,  15;
   0,  16,   3,   3,  17;
  15,   0,   5,  18,  20;
   7,  17,  16,  17,  14]
ROW|ASCENDING:[  1,   6,  12,  21,  22;
  10,  15,  21,  22,  23;
   0,   3,   3,  16,  17;
   0,   5,  15,  18,  20;
   7,  14,  16,  17,  17]
ROW|DESCENDING:[ 22,  21,  12,   6,   1;
  23,  22,  21,  15,  10;
  17,  16,   3,   3,   0;
  20,  18,  15,   5,   0;
  17,  17,  16,  14,   7]
COLUMN|ASCENDING:[  0,   0,   3,   3,   1;
   7,   6,   5,  17,  14;
  15,  10,  12,  18,  15;
  21,  16,  16,  22,  17;
  21,  17,  22,  23,  20]
COLUMN|DESCENDING:[ 21,  17,  22,  23,  20;
  21,  16,  16,  22,  17;
  15,  10,  12,  18,  15;
   7,   6,   5,  17,  14;
   0,   0,   3,   3,   1]

Comparison

Example Code:

            //
            // comparison example
            //

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

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

            Mat dst_mat = new Mat ();

            // GT (M1 > M2)
            Core.compare (m1, m2, dst_mat, Core.CMP_GT);
            Debug.Log (""GT (M1 > M2)="" + dst_mat.dump ());

            // GE (M1 >= M2)
            Core.compare (m1, m2, dst_mat, Core.CMP_GE);
            Debug.Log (""GE (M1 >= M2)="" + dst_mat.dump ());

            // EQ (M1 == M2)
            Core.compare (m1, m2, dst_mat, Core.CMP_EQ);
            Debug.Log (""EQ (M1 == M2)="" + dst_mat.dump ());

            // NE (M1 != M2)
            Core.compare (m1, m2, dst_mat, Core.CMP_NE);
            Debug.Log (""NE (M1 != M2)="" + dst_mat.dump ());

            // LE (M1 <= M2)
            Core.compare (m1, m2, dst_mat, Core.CMP_LE);
            Debug.Log (""LE (M1 <= M2)="" + dst_mat.dump ());

            // LT (M1 < M2)
            Core.compare (m1, m2, dst_mat, Core.CMP_LT);
            Debug.Log (""LT (M1 < M2)="" + dst_mat.dump ());

Execution Result:

m1=[1, 2, 3;
 4, 5, 6;
 7, 8, 9]
m2=[9, 8, 7;
 6, 5, 4;
 3, 2, 1]
GT (M1 > M2)=[  0,   0,   0;
   0,   0, 255;
 255, 255, 255]
GE (M1 >= M2)=[  0,   0,   0;
   0, 255, 255;
 255, 255, 255]
EQ (M1 == M2)=[  0,   0,   0;
   0, 255,   0;
   0,   0,   0]
NE (M1 != M2)=[255, 255, 255;
 255,   0, 255;
 255, 255, 255]
LE (M1 <= M2)=[255, 255, 255;
 255, 255,   0;
   0,   0,   0]
LT (M1 < M2)=[255, 255, 255;
 255,   0,   0;
   0,   0,   0]

Operators

Example Code:

            //
            // operators example
            //

            // 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 s = new Scalar (5);
            double alpha = 3;

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

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

            // (M1 – M2 = Core.subtract (M1, M2, M_dst))
            Debug.Log (""m1-m2="" + (m1 - m2).dump());
            // (M1 – s = Core.subtract (M1, s, M_dst))
            Debug.Log (""m1-s="" + (m1 - s).dump());

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


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


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

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

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


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


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

            // (M1 | M2 = Core.bitwise_or (M1, M2, M_dst))
            Debug.Log (""m1|m2="" + (m1 | m2).dump());

            // (M1 ^ M2 = Core.bitwise_xor (M1, M2, M_dst))
            Debug.Log (""m1^m2="" + (m1 ^ m2).dump());

            // (~M1 = Core.bitwise_not (M1, M_dst))
            Debug.Log (""~m1="" + (~m1).dump());
			
            // Note.
            // The assignment operator behavior is different from OpenCV (c ++). 
            // For example, C = A + B will not be expanded to cv::add(A, B, C).
            // Also cannot assign a scalar to Mat like C = s.

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=[0.3, 0.2727272727272727, 0.25;
 0.2307692307692308, 0.2142857142857143, 0.2;
 0.1875, 0.1764705882352941, 0.1666666666666667]
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]	
	
// Note.
// The assignment operator behavior is different from OpenCV (c ++). 
// For example, C = A + B will not be expanded to cv::add(A, B, C).
// Also cannot assign a scalar to Mat like C = s.

Get And Put

Example Code:

            //
            // get and put example
            //

            // channels=4 3x3 matrix
            Mat m1 = new Mat (3, 3, CvType.CV_8UC4 , new Scalar(1,2,3,4));
            Debug.Log (""m1="" + m1.dump ());


            // get an element value.
            double[] m1_1_1 = m1.get(1,1);
            Debug.Log (""m1[1,1]="" + m1_1_1[0] + "", "" + m1_1_1[1] + "", "" + m1_1_1[2] + "", "" + m1_1_1[3]);

            // get an array of all element values.
            byte[] m1_array = new byte[m1.total () * m1.channels()];
            m1.get (0, 0, m1_array);

            string dump_str = """";
            foreach (var i in m1_array){
                dump_str += i + "", "";
            }
            Debug.Log (""m1_array="" + dump_str);
			
            // another faster way. (use Utils.copyFromMat())
            Utils.copyFromMat (m1, m1_array);

            dump_str = "";
            foreach (var i in m1_array) {
                dump_str += i + ", ";
            }
            Debug.Log ("m1_array (use Utils.copyFromMat())=" + dump_str);


            // put an element value in a matrix.
            Mat m2 = m1.clone ();
            m2.put (1, 1, 5,6,7,8);
            Debug.Log (""m2="" + m2.dump ());

            // put an array of element values in a matrix.
            byte[] m2_arr = new byte[]{5,6,7,8,5,6,7,8,5,6,7,8,5,6,7,8,5,6,7,8,5,6,7,8,5,6,7,8,5,6,7,8,5,6,7,8};
            m2.put (0, 0, m2_arr);
            Debug.Log (""m2="" + m2.dump ());
			
            // another faster way. (use Utils.copyToMat())
            Utils.copyToMat (m2_arr, m2);
            Debug.Log ("m2 (use Utils.copyToMat())=" + m2.dump ());
			

            // fill element values (setTo method)
            m2.setTo(new Scalar(100,100,100,100));
            Debug.Log (""m2="" + m2.dump ());

Execution Result:

m1=[  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]
m1[1,1]=1, 2, 3, 4
m1_array=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, 
m1_array (use Utils.copyFromMat())=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, 
m2=[  1,   2,   3,   4,   1,   2,   3,   4,   1,   2,   3,   4;
   1,   2,   3,   4,   5,   6,   7,   8,   1,   2,   3,   4;
   1,   2,   3,   4,   1,   2,   3,   4,   1,   2,   3,   4]
m2=[  5,   6,   7,   8,   5,   6,   7,   8,   5,   6,   7,   8;
   5,   6,   7,   8,   5,   6,   7,   8,   5,   6,   7,   8;
   5,   6,   7,   8,   5,   6,   7,   8,   5,   6,   7,   8]
m2 (use Utils.copyToMat())=[  5,   6,   7,   8,   5,   6,   7,   8,   5,   6,   7,   8;
   5,   6,   7,   8,   5,   6,   7,   8,   5,   6,   7,   8;
   5,   6,   7,   8,   5,   6,   7,   8,   5,   6,   7,   8]
m2=[100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100;
 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100;
 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100]

Accessing Pixel Values

Example Code:

            //
            // accessing pixel values example
            //

            // How access pixel values in an OpenCV Mat.

            // channels=4 10x10 matrix (RGBA color image)
            Mat src_img = new Mat (10, 10, CvType.CV_8UC4, new Scalar (0, 0, 0, 255));
            Mat dst_img = new Mat (10, 10, CvType.CV_8UC4);

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

            // Copies an OpenCV Mat data to a pixel data Array.
            byte[] img_array = new byte[src_img.total () * src_img.channels()];
            Utils.copyFromMat (src_img, img_array);

            int pixel_i = 0;
            int channels = src_img.channels();
            int total = (int)src_img.total();
            for (int i = 0; i < total; i++) {

                img_array [pixel_i] = (byte)i;
                img_array [pixel_i + 1] = (byte)i;
                img_array [pixel_i + 2] = (byte)i;

                // Advance to next pixel
                pixel_i += channels;
            }

            // Copies a pixel data Array to an OpenCV Mat data.
            Utils.copyToMat (img_array, dst_img);

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

Execution Result:

src_img=[  0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255;
   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255;
   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255;
   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255;
   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255;
   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255;
   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255;
   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255;
   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255;
   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255,   0,   0,   0, 255]
   dst_img=[  0,   0,   0, 255,   1,   1,   1, 255,   2,   2,   2, 255,   3,   3,   3, 255,   4,   4,   4, 255,   5,   5,   5, 255,   6,   6,   6, 255,   7,   7,   7, 255,   8,   8,   8, 255,   9,   9,   9, 255;
  10,  10,  10, 255,  11,  11,  11, 255,  12,  12,  12, 255,  13,  13,  13, 255,  14,  14,  14, 255,  15,  15,  15, 255,  16,  16,  16, 255,  17,  17,  17, 255,  18,  18,  18, 255,  19,  19,  19, 255;
  20,  20,  20, 255,  21,  21,  21, 255,  22,  22,  22, 255,  23,  23,  23, 255,  24,  24,  24, 255,  25,  25,  25, 255,  26,  26,  26, 255,  27,  27,  27, 255,  28,  28,  28, 255,  29,  29,  29, 255;
  30,  30,  30, 255,  31,  31,  31, 255,  32,  32,  32, 255,  33,  33,  33, 255,  34,  34,  34, 255,  35,  35,  35, 255,  36,  36,  36, 255,  37,  37,  37, 255,  38,  38,  38, 255,  39,  39,  39, 255;
  40,  40,  40, 255,  41,  41,  41, 255,  42,  42,  42, 255,  43,  43,  43, 255,  44,  44,  44, 255,  45,  45,  45, 255,  46,  46,  46, 255,  47,  47,  47, 255,  48,  48,  48, 255,  49,  49,  49, 255;
  50,  50,  50, 255,  51,  51,  51, 255,  52,  52,  52, 255,  53,  53,  53, 255,  54,  54,  54, 255,  55,  55,  55, 255,  56,  56,  56, 255,  57,  57,  57, 255,  58,  58,  58, 255,  59,  59,  59, 255;
  60,  60,  60, 255,  61,  61,  61, 255,  62,  62,  62, 255,  63,  63,  63, 255,  64,  64,  64, 255,  65,  65,  65, 255,  66,  66,  66, 255,  67,  67,  67, 255,  68,  68,  68, 255,  69,  69,  69, 255;
  70,  70,  70, 255,  71,  71,  71, 255,  72,  72,  72, 255,  73,  73,  73, 255,  74,  74,  74, 255,  75,  75,  75, 255,  76,  76,  76, 255,  77,  77,  77, 255,  78,  78,  78, 255,  79,  79,  79, 255;
  80,  80,  80, 255,  81,  81,  81, 255,  82,  82,  82, 255,  83,  83,  83, 255,  84,  84,  84, 255,  85,  85,  85, 255,  86,  86,  86, 255,  87,  87,  87, 255,  88,  88,  88, 255,  89,  89,  89, 255;
  90,  90,  90, 255,  91,  91,  91, 255,  92,  92,  92, 255,  93,  93,  93, 255,  94,  94,  94, 255,  95,  95,  95, 255,  96,  96,  96, 255,  97,  97,  97, 255,  98,  98,  98, 255,  99,  99,  99, 255]