private bool win = false; // true if the user had win.

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Load the shape and its pieces
        /// </summary>
        /// <param name="lockShapes"></param>
        /// <param name="shape"></param>
        public SecondScatterView(bool lockShapes, TangramShape shape)
        {
            InitializeComponent();
            this.lockShapes = lockShapes;
            this.currentShape = shape;

            //Load the motherpiece for the location
            this.currentShape.getMotherPiece().Center = new Point(512, 384);
            this.currentShape.getMotherPiece().Orientation = 0;
            this.currentShape.getMotherPiece().IsEnabled = false;
            System.Windows.Shapes.Path p = (System.Windows.Shapes.Path)this.currentShape.getMotherPiece().Content;
            p.Fill = new SolidColorBrush(Colors.Black);
            p.Opacity = 0.5;
            this.currentShape.getMotherPiece().CanMove = false;
            this.currentShape.getMotherPiece().CanRotate = false;
            this.currentShape.getMotherPiece().CanScale = false;
            this.scatter2.Items.Add(this.currentShape.getMotherPiece());

            //Load all pieces for the shape
            for (int j = 0; j < this.currentShape.getPieces().Count; j++)
            {
                this.scatter2.Items.Add(this.currentShape.getPieces()[j]);
            }

            //Create the surfaceTextBlock
            this.name = (SurfaceTextBox)Resources["name"];

            //Check the time
            this.t1 = DateTime.Now;
        }
    public static Vector2[] GetShape(this TangramShape shape)
    {
        switch (shape)
        {
        case TangramShape.LargeTriangle:
            return(new Vector2[]
            {
                new Vector2(0.0f, 0.0f),
                new Vector2(0.5f, 0.5f),
                new Vector2(0.0f, 1.0f),
            });

        case TangramShape.MediumTriangle:
            return(new Vector2[]
            {
                new Vector2(0.0f, 0.0f),
                new Vector2(0.5f, 0.0f),
                new Vector2(0.5f, 0.5f),
            });

        case TangramShape.SmallTriangle:
            return(new Vector2[]
            {
                new Vector2(0.0f, 0.0f),
                new Vector2(0.25f, 0.25f),
                new Vector2(0.0f, 0.5f),
            });

        case TangramShape.Square:
            return(new Vector2[]
            {
                new Vector2(0.25f, 0.0f),
                new Vector2(0.5f, 0.25f),
                new Vector2(0.25f, 0.5f),
                new Vector2(0.0f, 0.25f),
            });

        case TangramShape.Parallelogram:
            return(new Vector2[]
            {
                new Vector2(0.75f, 0.0f),
                new Vector2(0.5f, 0.25f),
                new Vector2(0.0f, 0.25f),
                new Vector2(0.25f, 0.0f),
            });

        default:
            return(null);
        }
    }
    public override void OnInspectorGUI()
    {
        TangramGrid tangramGrid = (TangramGrid)target;

        TangramGrid.ConnectionJSON json = JsonConvert.DeserializeObject <TangramGrid.ConnectionJSON>(tangramGrid.AllConnections);
        tangramGrid.Connections         = json.Connections;
        tangramGrid.ExternalConnections = json.ExternalConnections;

        TangramChip oldChip = tangramGrid.Chip;

        tangramGrid.Chip = (TangramChip)EditorGUILayout.ObjectField("Chip Prefab", oldChip, typeof(TangramChip), false);
        if (tangramGrid.Chip != oldChip)
        {
            EditorUtility.SetDirty(target);
        }

        string oldCode = tangramGrid.Code;

        tangramGrid.Code = EditorGUILayout.TextField("Code", oldCode);
        if (tangramGrid.Code != oldCode)
        {
            EditorUtility.SetDirty(target);
        }

        Texture oldTexture = tangramGrid.UnderlayTexture;

        tangramGrid.UnderlayTexture = (Texture)EditorGUILayout.ObjectField("Underlay Texture", oldTexture, typeof(Texture), false);

        EditorGUILayout.LabelField("Cells", EditorStyles.boldLabel);
        ArraySizeField("Cell Count", ref tangramGrid.Cells, target);

        if (tangramGrid.Cells != null)
        {
            EditorGUI.indentLevel++;
            for (int cellIndex = 0; cellIndex < tangramGrid.Cells.Length; ++cellIndex)
            {
                TangramShape oldShape = tangramGrid.Cells[cellIndex];
                tangramGrid.Cells[cellIndex] = (TangramShape)EditorGUILayout.EnumPopup(string.Format("Cell {0}", cellIndex + 1), oldShape);
                if (tangramGrid.Cells[cellIndex] != oldShape)
                {
                    EditorUtility.SetDirty(target);
                }
            }
            EditorGUI.indentLevel--;
        }

        EditorGUILayout.LabelField("Connections", EditorStyles.boldLabel);

        ArraySizeField("Connection Count", ref tangramGrid.Connections, target);
        if (tangramGrid.Connections != null)
        {
            EditorGUI.indentLevel++;

            for (int connectionIndex = 0; connectionIndex < tangramGrid.Connections.Length; ++connectionIndex)
            {
                TangramGridConnection connection = tangramGrid.Connections[connectionIndex];
                if (connection == null)
                {
                    connection = new TangramGridConnection()
                    {
                        PointA = new TangramGridConnectionPoint(), PointB = new TangramGridConnectionPoint()
                    };
                    EditorUtility.SetDirty(target);
                }
                else
                {
                    if (connection.PointA == null)
                    {
                        connection.PointA = new TangramGridConnectionPoint();
                        EditorUtility.SetDirty(target);
                    }

                    if (connection.PointB == null)
                    {
                        connection.PointB = new TangramGridConnectionPoint();
                        EditorUtility.SetDirty(target);
                    }
                }

                EditorGUILayout.BeginHorizontal();

                EditorGUILayout.LabelField(string.Format("Connection {0}", connectionIndex + 1));
                IntField(ref connection.PointA.CellIndex, target);
                IntField(ref connection.PointA.CellPointIndex, target);
                IntField(ref connection.PointB.CellIndex, target);
                IntField(ref connection.PointB.CellPointIndex, target);

                EditorGUILayout.EndHorizontal();
            }
            EditorGUI.indentLevel--;
        }

        EditorGUILayout.LabelField("External Connections", EditorStyles.boldLabel);

        ArraySizeField("Connection Count", ref tangramGrid.ExternalConnections, target);
        if (tangramGrid.ExternalConnections != null)
        {
            EditorGUI.indentLevel++;

            for (int connectionIndex = 0; connectionIndex < tangramGrid.ExternalConnections.Length; ++connectionIndex)
            {
                TangramGridConnectionPoint connectionPoint = tangramGrid.ExternalConnections[connectionIndex];
                if (connectionPoint == null)
                {
                    connectionPoint = new TangramGridConnectionPoint();
                    EditorUtility.SetDirty(target);
                }

                EditorGUILayout.BeginHorizontal();

                EditorGUILayout.LabelField(string.Format("Connection {0}", connectionIndex + 1));
                IntField(ref connectionPoint.CellIndex, target);
                IntField(ref connectionPoint.CellPointIndex, target);

                EditorGUILayout.EndHorizontal();
            }
            EditorGUI.indentLevel--;
        }

        json = new TangramGrid.ConnectionJSON()
        {
            Connections = tangramGrid.Connections, ExternalConnections = tangramGrid.ExternalConnections
        };
        tangramGrid.AllConnections = JsonConvert.SerializeObject(json);
    }
Exemple #4
0
    public override void OnInspectorGUI()
    {
        TangramPiece tangramPiece = (TangramPiece)target;

        tangramPiece.Connectivity = JsonConvert.DeserializeObject <TangramPieceConnections[]>(tangramPiece.Connections);

        TangramShape oldShape = tangramPiece.Shape;

        tangramPiece.Shape = (TangramShape)EditorGUILayout.EnumPopup("Shape", tangramPiece.Shape);
        if (oldShape != tangramPiece.Shape)
        {
            EditorUtility.SetDirty(target);
        }

        int oldIndex = tangramPiece.Index;

        tangramPiece.Index = EditorGUILayout.IntField("Index", tangramPiece.Index);
        if (oldIndex != tangramPiece.Index)
        {
            EditorUtility.SetDirty(target);
        }

        int connectionPointCount = tangramPiece.Shape.GetConnectionPoints().Length;

        if (tangramPiece.Connectivity == null || tangramPiece.Connectivity.Length != connectionPointCount)
        {
            tangramPiece.Connectivity = new TangramPieceConnections[connectionPointCount];
            for (int connectionPointIndex = 0; connectionPointIndex < connectionPointCount; ++connectionPointIndex)
            {
                tangramPiece.Connectivity[connectionPointIndex] = new TangramPieceConnections()
                {
                    Connections = new int[0]
                };
            }

            EditorUtility.SetDirty(target);
        }

        for (int connectionPointIndex = 0; connectionPointIndex < connectionPointCount; ++connectionPointIndex)
        {
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField(connectionPointIndex.ToString(), GUILayout.Width(30.0f));
            for (int endConnectionPointIndex = 0; endConnectionPointIndex < connectionPointCount; ++endConnectionPointIndex)
            {
                if (connectionPointIndex == endConnectionPointIndex)
                {
                    GUI.enabled = false;
                    GUILayout.Toggle(false, endConnectionPointIndex.ToString(), GUILayout.Width(30.0f));
                    GUI.enabled = true;
                }
                else
                {
                    bool oldToggled = tangramPiece.Connectivity[connectionPointIndex].Connections.Contains(endConnectionPointIndex);
                    bool toggled    = GUILayout.Toggle(oldToggled, endConnectionPointIndex.ToString(), GUILayout.Width(30.0f));
                    if (toggled != oldToggled)
                    {
                        if (toggled)
                        {
                            ArrayUtility.Add(ref tangramPiece.Connectivity[connectionPointIndex].Connections, endConnectionPointIndex);
                        }
                        else
                        {
                            ArrayUtility.Remove(ref tangramPiece.Connectivity[connectionPointIndex].Connections, endConnectionPointIndex);
                        }

                        EditorUtility.SetDirty(target);
                    }
                }
            }
            EditorGUILayout.EndHorizontal();
        }

        tangramPiece.Connections = JsonConvert.SerializeObject(tangramPiece.Connectivity);
    }
 /// <summary>
 /// Occurs when the user tap on a shape.
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 private void scatter_ContactTapGesture(object sender, ContactEventArgs e)
 {
     for (int i = 0; i < this.scatter.Items.Count; i++)
     {
         ScatterViewItem svi = (ScatterViewItem)this.scatter.Items[i];
         if (svi.IsActive) //if a shape is selected
         {
             this.selectedShape = this.shapes[i];
             // trigger an event with this selected shape in parameter
             ShapeSelectedEventArgs eventShapeSelection = new ShapeSelectedEventArgs(this.selectedShape);
             if (eventShapeSelection != null) this.OnShapeSelected(this, eventShapeSelection);
         }
     }
 }
    string getFeatureTangram(string path)
    {
        Mat rgbMat = Imgcodecs.imread(path);

        var width  = rgbMat.width();
        var height = rgbMat.height();
        var ofsetx = 0;
        var ofsety = 0;

        if (width > 4096)
        {
            ofsetx = (width - 4096) / 2;
        }
        if (height > 4096)
        {
            ofsety = (height - 4096) / 2;
        }

        var rat = (float)rgbMat.width() / (float)rgbMat.height();

        Imgproc.cvtColor(rgbMat, rgbMat, Imgproc.COLOR_RGBA2BGR);
        Mat rgbMat2 = new Mat(rgbMat.size(), rgbMat.type());

        if (debug == true)
        {
            mainDebug.GetComponent <AspectRatioFitter>().aspectRatio = rat;
            debug1.GetComponent <AspectRatioFitter>().aspectRatio    = rat;
            debug2.GetComponent <AspectRatioFitter>().aspectRatio    = rat;
            debug3.GetComponent <AspectRatioFitter>().aspectRatio    = rat;
            debug4.GetComponent <AspectRatioFitter>().aspectRatio    = rat;
            debug5.GetComponent <AspectRatioFitter>().aspectRatio    = rat;
            debug6.GetComponent <AspectRatioFitter>().aspectRatio    = rat;
            debug7.GetComponent <AspectRatioFitter>().aspectRatio    = rat;
            debug8.GetComponent <AspectRatioFitter>().aspectRatio    = rat;
        }
        Mat hsvMat = new Mat();

        Imgproc.cvtColor(rgbMat, hsvMat, Imgproc.COLOR_RGB2HSV);
        Debug.Log(rgbMat.width());

        if (debug == true)
        {
            maxHeight = (int)(maxWidth / rat);

            texture = new Texture2D(maxWidth, maxHeight, TextureFormat.RGBA32, false);
            dbTxt1  = new Texture2D(maxWidth, maxHeight, TextureFormat.RGBA32, false);
            dbTxt2  = new Texture2D(maxWidth, maxHeight, TextureFormat.RGBA32, false);
            dbTxt3  = new Texture2D(maxWidth, maxHeight, TextureFormat.RGBA32, false);
            dbTxt4  = new Texture2D(maxWidth, maxHeight, TextureFormat.RGBA32, false);
            dbTxt5  = new Texture2D(maxWidth, maxHeight, TextureFormat.RGBA32, false);
            dbTxt6  = new Texture2D(maxWidth, maxHeight, TextureFormat.RGBA32, false);
            dbTxt7  = new Texture2D(maxWidth, maxHeight, TextureFormat.RGBA32, false);
            dbTxt8  = new Texture2D(maxWidth, maxHeight, TextureFormat.RGBA32, false);

            mainDebug.texture = texture;
            debug1.texture    = dbTxt1;
            debug2.texture    = dbTxt2;
            debug3.texture    = dbTxt3;
            debug4.texture    = dbTxt4;
            debug5.texture    = dbTxt5;
            debug6.texture    = dbTxt6;
            debug7.texture    = dbTxt7;
            debug8.texture    = dbTxt8;
        }

        if (debug)
        {
            Mat a = new Mat();
            Imgproc.resize(rgbMat, a, new Size(maxWidth, maxHeight));
            Utils.matToTexture2D(a, dbTxt4);
        }


        Mat threshold  = new Mat();
        Mat threshold2 = new Mat();

        List <MatOfPoint> contours = new List <MatOfPoint>();
        Mat          hierarchy     = new Mat();
        MatOfPoint2f mop2f         = new MatOfPoint2f();


        TangramShape   blackShape = new TangramShape();
        List <MyShape> ls_shapes  = new List <MyShape>();

        blackShape.datas = ls_shapes;


        bool[] OK = new bool[7];

        for (var obj_i = 0; obj_i < 7; obj_i++)
        {
            var obj = ls_obj[obj_i];

            Core.inRange(hsvMat, obj.HSVmin, obj.HSVmax, threshold);
            if (obj_i == (int)tgr.RED)
            {
                Core.inRange(hsvMat, obj.lower_HSVMin, obj.lower_HSVMax, threshold2);
                threshold2.copyTo(threshold, threshold2);
            }

            if (obj_i == (int)tgr.YELLOW)
            {
                if (debug)
                {
                    matToTexture(threshold, dbTxt3);
                }
            }

            contours.Clear();

            Imgproc.findContours(threshold, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);

            for (int ct_i = 0; ct_i < contours.Count; ct_i++)
            {
                if (Imgproc.contourArea(contours[ct_i]) < MIN_OBJECT_AREA)
                {
                    contours.RemoveAt(ct_i);
                    ct_i--;
                }
            }


            Scalar c = hsv2rgb(obj.getColor());
            for (int ct_i = 0; ct_i < contours.Count; ct_i++)
            {
                var ct   = contours[ct_i];
                var peri = Imgproc.arcLength(new MatOfPoint2f(ct.toArray()), true);

                Imgproc.approxPolyDP(new MatOfPoint2f(ct.toArray()), mop2f, 0.05 * peri, true);
                {
                    MyShape ms = new MyShape();

                    var points = mop2f.toArray();

                    var index     = -1;
                    var max       = -1d;
                    var numPoints = points.Length;
                    ms._id = obj_i;
                    ms.ps  = new Point[numPoints];

                    if (numPoints == 3)
                    {
                        OK[obj_i] = true;

                        for (var p_i = 0; p_i < numPoints; p_i++)
                        {
                            //Debug.LogFormat("p1 = {0}, p2 = {1}", p_i % numPoints, (p_i + 1) % numPoints);
                            var   p1  = points[p_i % numPoints];
                            var   p2  = points[(p_i + 1) % numPoints];
                            var   vt  = p2 - p1;
                            float len = (float)(vt.x * vt.x + vt.y * vt.y);
                            if (len > max)
                            {
                                index = p_i;
                                max   = len;
                            }
                        }
                        var i_nhon1 = index;
                        var i_nhon2 = (index + 1) % numPoints;
                        var i_vuong = (index + 2) % numPoints;

                        ms.ps[0] = points[i_vuong];
                        ms.ps[1] = points[i_nhon1];
                        ms.ps[2] = points[i_nhon2];

                        Imgproc.putText(rgbMat2, "1", points[i_nhon1], 1, 20, c, 10);
                        Imgproc.putText(rgbMat2, "2", points[i_nhon2], 1, 20, c, 10);
                        Imgproc.putText(rgbMat2, "0", points[i_vuong], 1, 20, c, 10);
                    }
                    else if (numPoints == 4)
                    {
                        if (obj_i == (int)tgr.YELLOW)
                        {
                            OK[obj_i] = true;
                            Debug.Log("Xin chao the mau vang");
                            ms.ps[0] = points[0];
                            ms.ps[1] = points[1];
                            ms.ps[2] = points[2];
                            ms.ps[3] = points[3];
                        }
                        else if (obj_i == (int)tgr.ORANGE)
                        {
                            OK[obj_i] = true;
                            Debug.Log("Xin chao the gioi");

                            var vt_cheo1 = points[0] - points[2];
                            var vt_cheo2 = points[1] - points[3];

                            var len_cheo1 = vt_cheo1.x * vt_cheo1.x + vt_cheo1.y * vt_cheo1.y;
                            var len_cheo2 = vt_cheo2.x * vt_cheo2.x + vt_cheo2.y * vt_cheo2.y;
                            var i_nhon    = 0;
                            if (len_cheo2 > len_cheo1)
                            {
                                i_nhon = 1;
                            }
                            ms.ps[0] = points[i_nhon];
                            ms.ps[1] = points[(i_nhon + 1)];
                            ms.ps[2] = points[(i_nhon + 2)];
                            ms.ps[3] = points[(i_nhon + 3) % numPoints];

                            var i_prvNhon  = (i_nhon + 4 - 1) % numPoints;
                            var i_aftNhon  = i_nhon + 1;
                            var vt_prvNhon = points[i_prvNhon] - points[i_nhon];
                            var vt_aftNhon = points[i_aftNhon] - points[i_nhon];

                            //Imgproc.line(rgbMat2, points[i_prvNhon], points[i_nhon], c, 10);

                            var len_prvNhon = vt_prvNhon.x * vt_prvNhon.x + vt_prvNhon.y * vt_prvNhon.y;
                            var len_aftNhon = vt_aftNhon.x * vt_aftNhon.x + vt_aftNhon.y * vt_aftNhon.y;
                            if (len_prvNhon > len_aftNhon)
                            {
                                ms.isFlip = true;
                                Imgproc.putText(rgbMat2, " IsFLIP", ms.ps[3], 1, 20, c, 10);
                            }
                            else
                            {
                                ms.isFlip = false;
                                Imgproc.putText(rgbMat2, " IsNOTFLIP", ms.ps[3], 1, 20, c, 10);
                            }



                            Debug.Log(ms.ps.Length);
                            Debug.Log((i_nhon + 3) % numPoints);

                            if (debug == true)
                            {
                                Imgproc.putText(rgbMat2, "0", ms.ps[0], 1, 20, c, 10);
                                Imgproc.putText(rgbMat2, "1", ms.ps[1], 1, 20, c, 10);
                                Imgproc.putText(rgbMat2, "2", ms.ps[2], 1, 20, c, 10);
                                Imgproc.putText(rgbMat2, "3", ms.ps[3], 1, 20, c, 10);
                            }
                        }
                    }

                    ls_shapes.Add(ms);
                }
            }
        }

        for (var ok_i = 0; ok_i < 7; ok_i++)
        {
            if (OK[ok_i] == false)
            {
                Debug.LogError("Sai mau: " + ok_i);
            }
        }


        if (debug)
        {
            Imgproc.circle(rgbMat2, new Point(1851, 3172), 20, yellow.getColor(), 10);
            Imgproc.circle(rgbMat2, new Point(1245, 2565), 20, yellow.getColor(), 10);
            Imgproc.circle(rgbMat2, new Point(883, 2925), 20, red.getColor(), 10);
            Imgproc.circle(rgbMat2, new Point(2100, 1709), 20, red.getColor(), 10);

            Mat a = new Mat();
            Imgproc.resize(rgbMat, a, new Size(maxWidth, maxHeight));
            Utils.matToTexture2D(a, texture);
            Imgproc.resize(hsvMat, a, new Size(maxWidth, maxHeight));
            Utils.matToTexture2D(a, dbTxt1);
            Imgproc.resize(rgbMat2, a, new Size(maxWidth, maxHeight));
            Utils.matToTexture2D(a, dbTxt2);
        }

        for (int i = 0; i < blackShape.datas.Count; i++)
        {
            for (int j = 0; j < blackShape.datas[i].ps.Length; j++)
            {
                blackShape.datas[i].ps[j].x -= ofsetx;
                blackShape.datas[i].ps[j].y -= ofsety;
            }
        }

        var json = JsonUtility.ToJson(blackShape);

        return(json);
    }
    //public delegate void Process(int[] tgrdeteced);
    void tagramDetect(Mat t_rgbaMat, Action <TangramResultModel, List <MyShape> > prc)
    {
        List <MyShape> lms = new List <MyShape>();

        System.Diagnostics.Stopwatch watch = null;

        long elapsedMs;
        TangramResultModel trm = null;

        Observable.Start(() =>
        {
            mut.WaitOne();
            Imgproc.resize(t_rgbaMat, rgbaMat, new Size(nW_goc, nH_goc));
            watch = System.Diagnostics.Stopwatch.StartNew();

            if (warp != null)
            {
                warp.Init(rgbaMat);
                Mat wMat = warp.warpPerspective(rgbaMat);
                rgbaMat  = wMat.submat(0, nH, 0, nW);
            }
            else
            {
                rgbaMat = rgbaMat.submat(0, nH, 0, nW);
            }

            all_thresh      = Mat.zeros(nH, nW, CvType.CV_8UC3);
            all_thresh_afct = Mat.zeros(nH, nW, CvType.CV_8UC3);
            dbMat           = Mat.zeros(nH, nW, CvType.CV_8UC3);
            all_thresh_af   = Mat.zeros(nH, nW, CvType.CV_8UC3);

            rgbaMat.copyTo(rgbMat);
            rgbMat.convertTo(rgbMat2, CvType.CV_8UC3, 0.8, 60);
            rgbMat2.copyTo(rgbMat2copy);
            rgbMat.convertTo(rgbMat3, CvType.CV_8UC3, 1, 60);
            rgbMat.convertTo(rgbMat4, CvType.CV_8UC3, 1.25, 35);
            rgbMat.convertTo(rgbMat, CvType.CV_8UC3, 1.25, 35);


            Imgproc.cvtColor(rgbMat, hsvMat, Imgproc.COLOR_RGB2HSV);
            Imgproc.cvtColor(rgbMat2, hsvMat2, Imgproc.COLOR_RGB2HSV);
            Imgproc.cvtColor(rgbMat3, hsvMat3, Imgproc.COLOR_RGB2HSV);
            Imgproc.cvtColor(rgbMat3, hsvMat4, Imgproc.COLOR_RGB2HSV);

            watch.Stop();
            elapsedMs = watch.ElapsedMilliseconds;

            Mat markers = Mat.zeros(rgbaMat.size(), CvType.CV_32SC1);

            watch = System.Diagnostics.Stopwatch.StartNew();

            for (int obj_i = 0; obj_i < ls_obj.Length; obj_i++)
            {
                var obj = ls_obj[obj_i];

                if (obj_i == (int)tgr.ORANGE | obj_i == (int)tgr.YELLOW | obj_i == (int)tgr.GREEN)
                {
                    Core.inRange(hsvMat2, obj.getHSVmin(), obj.getHSVmax(), thresholdMat);
                }
                else if (obj_i == (int)tgr.LIGHTBLUE)
                {
                    Core.inRange(hsvMat, obj.getHSVmin(), obj.getHSVmax(), thresholdMat);
                }
                else
                {
                    Core.inRange(hsvMat, obj.getHSVmin(), obj.getHSVmax(), thresholdMat);
                }


                if (obj_i == (int)tgr.RED)
                {
                    Core.inRange(hsvMat, new Scalar(0, 20, 45), new Scalar(5, 255, 255), thresholdMat2);
                    thresholdMat2.copyTo(thresholdMat, thresholdMat2);
                }


                thresholdMatArr[obj_i] = thresholdMat.clone();
            }

            //thresholdMatArr[(int)tgr.LIGHTBLUE].setTo(new Scalar(0), thresholdMatArr[(int)tgr.BLUE]);
            //thresholdMatArr[(int)tgr.LIGHTBLUE].setTo(new Scalar(0), thresholdMatArr[(int)tgr.GREEN]);


            for (int obj_i = 0; obj_i < ls_obj.Length; obj_i++)
            {
                var obj = ls_obj[obj_i];

                all_cts.Clear();
                thresholdMat = thresholdMatArr[obj_i];
                if (toggle_db[obj_i] == true)
                {
                    all_thresh.setTo(obj.ColorRGB, thresholdMat);
                }

                if (true | obj_i == (int)tgr.PURPLE | obj_i == (int)tgr.YELLOW | obj_i == (int)tgr.RED | obj_i == (int)tgr.GREEN | obj_i == (int)tgr.ORANGE)
                {
                    Imgproc.erode(thresholdMat, thresholdMat2, Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, new Size(5, 5)), new Point(-1, -1), 1);
                }
                if (obj_i == (int)tgr.LIGHTBLUE | obj_i == (int)tgr.PURPLE)
                {
                    Imgproc.erode(thresholdMat, thresholdMat2, Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, new Size(5, 5)), new Point(-1, -1), 1);
                }

                if (toggle_db[obj_i] == true)
                {
                    all_thresh_af.setTo(obj.ColorRGB, thresholdMat2);
                }
                all_thresh_afct.setTo(new Scalar(obj_i + 1), thresholdMat2);

                color_filter.Add(thresholdMat2.clone());

                Imgproc.findContours(thresholdMat2, all_cts, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
                Scalar c = obj.getColor();

                for (int ct_i = 0; ct_i < all_cts.Count; ct_i++)
                {
                    double area = Imgproc.contourArea(all_cts[ct_i]);
                    // if (area < MIN_OBJECT_AREA)
                    if (area < MIN_OBJECT_AREAS[obj_i] * 0.55)
                    {
                        all_cts.RemoveAt(ct_i);
                        ct_i--;
                    }
                    if (area > MAX_OBJECT_AREAS[obj_i] * 1.3)
                    {
                        all_cts.RemoveAt(ct_i);
                        ct_i--;
                    }
                }

                MyShape chon = null;
                MyShape ms   = new MyShape();
                float dt     = 1000000;

                for (int ct_i = 0; ct_i < all_cts.Count; ct_i++)
                {
                    var ct      = all_cts[ct_i];
                    var peri    = Imgproc.arcLength(new MatOfPoint2f(ct.toArray()), true);
                    var epsilon = 0.1 * peri;
                    if (obj_i == (int)tgr.ORANGE || obj_i == (int)tgr.YELLOW)
                    {
                        epsilon = 0.065 * peri;
                    }
                    Imgproc.approxPolyDP(new MatOfPoint2f(ct.toArray()), approx_ct, epsilon, true);

                    MatOfInt pts_cvh = new MatOfInt();
                    Imgproc.convexHull(ct, pts_cvh, true);
                    var cvh_numPts  = pts_cvh.toArray().Length;
                    Point[] cvh_pts = new Point[cvh_numPts];
                    var ct_pts      = ct.toArray();



                    for (int i = 0; i < cvh_numPts; i++)
                    {
                        var i1     = pts_cvh.toArray()[i];
                        var p1     = ct_pts[i1];
                        cvh_pts[i] = p1;

                        try
                        {
                            if (debug == true)
                            {
                                var i2 = pts_cvh.toArray()[(i + 1) % cvh_numPts];
                                var p2 = ct_pts[i2];
                                Imgproc.circle(rgbMat2, p1, 1, c, 2);
                            }
                        }
                        catch (Exception e)
                        {
                            Utilities.LogFormat("Here3:{0},{1},{2}", rgbMat2 == null, p1 == null, c == null);
                            Utilities.Log("Exception is {0}", e.ToString());
                            Utilities.Log("Trace is {0}", e.StackTrace.ToString());
                        }
                    }


                    MatOfPoint2f approx_cvh = new MatOfPoint2f();

                    var epsilon2 = peri * 0.1;
                    if (obj_i == (int)tgr.ORANGE)
                    {
                        epsilon2 = peri * 0.065;
                    }
                    Imgproc.approxPolyDP(new MatOfPoint2f(cvh_pts), approx_cvh, epsilon2, true);

                    var ct_ori            = new MatOfPoint(ct.toArray());
                    MatOfPoint approx_ct2 = new MatOfPoint(approx_ct.toArray());

                    List <MatOfPoint> approx_cvh2 = new List <MatOfPoint>();
                    approx_cvh2.Add(new MatOfPoint(approx_cvh.toArray()));

                    var mu    = Imgproc.moments(approx_cvh2[0], true);
                    cterTgr.x = mu.m10 / mu.m00;
                    cterTgr.y = mu.m01 / mu.m00;

                    if (approx_ct2.size().height == 3 | approx_ct2.size().height == 4)
                    {
                        var points    = approx_cvh2[0].toArray();
                        var numpoints = points.Length;

                        ms._id = obj_i;
                        ms.ps  = new Point[numpoints];


                        double rat = 1.16;
                        if (obj_i == (int)tgr.PURPLE)
                        {
                            rat = 1.20;
                        }
                        else if (obj_i == (int)tgr.LIGHTBLUE)
                        {
                            rat = 1.20;
                        }
                        else if (obj_i == (int)tgr.RED | obj_i == (int)tgr.BLUE)
                        {
                            rat = 1.09;
                        }
                        else if (obj_i == (int)tgr.YELLOW)
                        {
                            rat = 1.10;
                        }
                        else if (obj_i == (int)tgr.ORANGE)
                        {
                            rat = 1.10;
                        }
                        else if (obj_i == (int)tgr.GREEN)
                        {
                            rat = 1.10;
                        }

                        var ind_huyen = 0;
                        var max       = -1d;

                        if (numpoints == 3 || numpoints == 4)
                        {
                            for (int p_i = 0; p_i < numpoints; p_i++)
                            {
                                var p  = points[p_i];
                                var p2 = points[(p_i + 1) % numpoints];

                                var vect = p - cterTgr;

                                vect = vect * rat;

                                var p_new     = cterTgr + vect;
                                points[p_i].x = (int)(p_new.x * 100) / 100f;
                                points[p_i].y = (int)(p_new.y * 100) / 100f;


                                if (numpoints == 4)
                                {
                                    ms.ps[p_i] = p_new;
                                }

                                if (numpoints == 3)
                                {
                                    var vt     = p2 - p;
                                    var length = vt.x * vt.x + vt.y * vt.y;
                                    if (length > max)
                                    {
                                        ind_huyen = p_i;
                                        max       = length;
                                    }
                                }
                            }
                        }

                        if (numpoints == 3)
                        {
                            var i_nhon1 = ind_huyen;
                            var i_nhon2 = (ind_huyen + 1) % numpoints;
                            var i_vuong = (ind_huyen + 2) % numpoints;

                            ms.ps[0] = points[i_vuong];
                            ms.ps[1] = points[i_nhon1];
                            ms.ps[2] = points[i_nhon2];
                        }
                        else if (numpoints == 4)
                        {
                            if (obj_i == (int)tgr.ORANGE)
                            {
                                var vt_cheo1   = ms.ps[0] - ms.ps[2];
                                var vt_cheo2   = ms.ps[1] - ms.ps[3];
                                var leng_cheo1 = vt_cheo1.x * vt_cheo1.x + vt_cheo1.y * vt_cheo1.y;
                                var leng_cheo2 = vt_cheo2.x * vt_cheo2.x + vt_cheo2.y * vt_cheo2.y;
                                var i_nhon     = 0;
                                if (leng_cheo2 > leng_cheo1)
                                {
                                    i_nhon = 1;
                                }

                                ms.ps[0] = points[i_nhon];
                                ms.ps[1] = points[(i_nhon + 1)];
                                ms.ps[2] = points[(i_nhon + 2)];
                                ms.ps[3] = points[(i_nhon + 3) % numpoints];

                                var i_prvNhon   = (i_nhon + 4 - 1) % numpoints;
                                var i_aftNhon   = i_nhon + 1;
                                var vt_prvNhon  = points[i_prvNhon] - points[i_nhon];
                                var vt_aftNhon  = points[i_aftNhon] - points[i_nhon];
                                var len_prvNhon = vt_prvNhon.x * vt_prvNhon.x + vt_prvNhon.y * vt_prvNhon.y;
                                var len_aftNhon = vt_aftNhon.x * vt_aftNhon.x + vt_aftNhon.y * vt_aftNhon.y;

                                Imgproc.line(dbMat, points[i_prvNhon], points[i_nhon], c, 1);

                                if (len_prvNhon > len_aftNhon)
                                {
                                    ms.isFlip = true;
                                    Imgproc.putText(dbMat, " IsFLIP", ms.ps[3], 1, 1, c, 1);
                                }
                                else
                                {
                                    ms.isFlip = false;
                                    Imgproc.putText(dbMat, " IsNOTFLIP", ms.ps[3], 1, 1, c, 1);
                                }
                            }
                        }

                        var centerMat = new Point(rgbMat.width() / 2f, rgbMat.height() / 2f);
                        var vtLech    = centerMat - cterTgr;
                        var dt2       = vtLech.x * vtLech.x + vtLech.y * vtLech.y;
                        if (dt2 < dt)
                        {
                            chon = ms;
                        }
                    }
                    try
                    {
                        Imgproc.circle(rgbMat, cterTgr, 1, c, 1);
                        Imgproc.putText(rgbMat, mu.m00.ToString(), cterTgr, 1, 1, c, 1);
                    }
                    catch (Exception e)
                    {
                        Utilities.LogFormat("Here2:{0},{1},{2}", rgbMat == null, cterTgr == null, c == null);
                        Utilities.Log("Exception is {0}", e.ToString());
                        Utilities.Log("Trace is {0}", e.StackTrace.ToString());
                    }

                    //if (approx_ct2.size().height == 3 | approx_ct2.size().height == 4) break;
                }

                if (chon != null)
                {
                    lms.Add(chon);

                    var ps = chon.ps;
                    for (int i = 0; i < ps.Length; i++)
                    {
                        var p1 = ps[i];
                        var p2 = ps[(i + 1) % ps.Length];

                        try
                        {
                            Imgproc.line(rgbMat2, p1, p2, c, 1);
                            Imgproc.line(all_thresh_afct, p1, p2, new Scalar(255, 255, 255), 1);
                            Imgproc.line(dbMat, p1, p2, c, 1);
                            Imgproc.circle(dbMat, p1, 1, c);
                        }
                        catch (Exception e)
                        {
                            Utilities.LogFormat("Here1:{0},{1},{2}", rgbMat2 == null, p1 == null, p2 == null);
                            Utilities.Log("Exception is {0}", e.ToString());
                            Utilities.Log("Trace is {0}", e.StackTrace.ToString());
                        }
                    }
                }

                watch.Stop();
                elapsedMs = watch.ElapsedMilliseconds;
            }

            TangramShape msl = new TangramShape();
            msl.datas        = lms;
            var json         = JsonUtility.ToJson(msl);

            watch = System.Diagnostics.Stopwatch.StartNew();
            trm   = tangramFeatureModelList.Detect(msl.datas.ToArray());
            watch.Stop();
            elapsedMs = watch.ElapsedMilliseconds;

            mut.ReleaseMutex();
        }).ObserveOnMainThread().Subscribe((rx) =>
        {
            prc(trm, lms);
            if (debug == true)
            {
                mut.WaitOne();

                if (texture != null && debug == true)
                {
                    Utils.matToTexture2D(dbMat, texture);
                }
                if (dbText1 != null && debug == true)
                {
                    Utils.matToTexture2D(rgbMat2copy, dbText1);
                }
                if (dbText2 != null && debug == true)
                {
                    Utils.matToTexture2D(rgbMat3, dbText2);
                }
                if (dbText3 != null && debug == true)
                {
                    Utils.matToTexture2D(rgbMat4, dbText3);
                }
                if (dbText4 != null && debug == true)
                {
                    Utils.matToTexture2D(rgbMat, dbText4);
                }

                all_thresh_afct = all_thresh_afct * 25;
                Imgproc.cvtColor(rgbMat2, rgbMat2, Imgproc.COLOR_RGBA2RGB);
                Imgproc.cvtColor(all_thresh, all_thresh, Imgproc.COLOR_RGBA2RGB);
                Mat a = new Mat(all_thresh.size(), CvType.CV_8UC3);
                Core.addWeighted(all_thresh, 0.2, rgbMat2, 0.8, 0, a);
                if (dbText5 != null && debug == true)
                {
                    Utils.matToTexture2D(a, dbText5);
                }
                if (dbText6 != null && debug == true)
                {
                    Utils.matToTexture2D(all_thresh, dbText6);
                }
                if (dbText7 != null && debug == true)
                {
                    Utils.matToTexture2D(all_thresh_afct, dbText7);
                }
                if (dbText8 != null && debug == true)
                {
                    Utils.matToTexture2D(all_thresh_af, dbText8);
                }
                mut.ReleaseMutex();
            }
        });
    }
    private void Awake()
    {
        Screen.sleepTimeout = SleepTimeout.NeverSleep;
        mut = new Mutex();
        if (debug == true)
        {
            t_tangram = new Toggle[7];
            if (t_red != null && debug)
            {
                t_tangram[(int)tgr.RED] = t_red;
            }
            if (t_orange != null && debug)
            {
                t_tangram[(int)tgr.ORANGE] = t_orange;
            }
            if (t_yellow != null && debug)
            {
                t_tangram[(int)tgr.YELLOW] = t_yellow;
            }
            if (t_green != null && debug)
            {
                t_tangram[(int)tgr.GREEN] = t_green;
            }
            if (t_lightblue != null && debug)
            {
                t_tangram[(int)tgr.LIGHTBLUE] = t_lightblue;
            }
            if (t_blue != null && debug)
            {
                t_tangram[(int)tgr.BLUE] = t_blue;
            }
            if (t_purple != null && debug)
            {
                t_tangram[(int)tgr.PURPLE] = t_purple;
            }

            for (int i = 0; i < 7; i++)
            {
                var toggle = t_tangram[i];
                var index  = i;
                if (toggle != null)
                {
                    toggle.onValueChanged.AddListener((b) =>
                    {
                        toggle_db[index] = b;
                    });
                }
            }
        }


        //if (toggleColor != null && debug == true)
        //{
        //    toggleColor.onValueChanged.AddListener((string s2) =>
        //    {
        //        var text = s2.Trim();
        //        //if (string.IsNullOrEmpty(text)) { text = "1111111"; toggleColor.text = text; }
        //        var leng = text.Length > 7 ? 7 : text.Length;
        //        for (int i = 0; i < leng; i++)
        //        {
        //            var b = int.Parse(text[i].ToString());
        //            if (b == 1) toggle_db[i] = true;
        //            else toggle_db[i] = false;
        //        }
        //        for (int i = leng; i < 7; i++)
        //        {
        //            toggle_db[i] = false;
        //        }
        //    });

        //    if (string.IsNullOrEmpty(toggleColor.text)) { toggleColor.text = "1111111"; }
        //}

        //init Tangram Feature Detect
        TangramShape msl = JsonUtility.FromJson <TangramShape>(TS_DATA);

        tangramFeatureModelList = new TangramFeatureModelList();
        tangramFeatureModelList.ProcessInput(msl.datas.ToArray(), true);


        colorRGB = new Scalar[7];

        ls_obj = new TangramObject[7];
        red.setHSVmin(new Scalar(170, 30, 45));
        red.setHSVmax(new Scalar(180, 255, 255));
        red.setColor(new Scalar(175, 255, 255));
        red.ColorRGB = hsv2rgb(red.getColor());

        //ngoai troi
        orange.setHSVmin(new Scalar(6, 75, 45));
        orange.setHSVmax(new Scalar(18, 255, 255));
        orange.setColor(new Scalar(13, 255, 255));
        orange.ColorRGB = hsv2rgb(orange.getColor());

        //ngoai troi
        yellow.setHSVmin(new Scalar(23, 75, 100));
        yellow.setHSVmax(new Scalar(34, 255, 255));
        yellow.setColor(new Scalar(30, 160, 255));
        yellow.ColorRGB = hsv2rgb(yellow.getColor());
        //ngoai troi
        green.setHSVmin(new Scalar(35, 30, 40));
        green.setHSVmax(new Scalar(72, 255, 255));
        green.setColor(new Scalar(60, 255, 255));
        green.ColorRGB = hsv2rgb(green.getColor());

        //may ios nhỏ, lúc đầu camera chưa sáng trong 30s đầu
        lightBlue.setHSVmin(new Scalar(70, 30, 45));
        lightBlue.setHSVmax(new Scalar(108, 255, 255));
        lightBlue.setColor(new Scalar(90, 255, 255));
        lightBlue.ColorRGB = hsv2rgb(lightBlue.getColor());

        //xem lai can nsua la tru di mau xanh
        blue.setHSVmin(new Scalar(108, 30, 45));
        blue.setHSVmax(new Scalar(135, 255, 255));
        blue.setColor(new Scalar(115, 255, 255));
        blue.ColorRGB = hsv2rgb(blue.getColor());

        purple.setHSVmin(new Scalar(136, 30, 40));
        purple.setHSVmax(new Scalar(172, 255, 255));
        purple.setColor(new Scalar(150, 255, 255));
        purple.ColorRGB = hsv2rgb(purple.getColor());

        ls_obj[(int)tgr.ORANGE]    = orange;
        ls_obj[(int)tgr.RED]       = red;
        ls_obj[(int)tgr.YELLOW]    = yellow;
        ls_obj[(int)tgr.GREEN]     = green;
        ls_obj[(int)tgr.BLUE]      = blue;
        ls_obj[(int)tgr.LIGHTBLUE] = lightBlue;
        ls_obj[(int)tgr.PURPLE]    = purple;

        gray      = new Mat();
        canny     = new Mat();
        rgb       = new Mat();
        all_cts   = new List <MatOfPoint>();
        hierarchy = new Mat();
        approx_ct = new MatOfPoint2f();
        cterTgr   = new Point();


        for (int i = 0; i < ls_obj.Length; i++)
        {
            var obj = ls_obj[i];
            Mat hsv = new Mat(1, 1, CvType.CV_8UC3, obj.getHSVmax());
            Imgproc.cvtColor(hsv, rgb, Imgproc.COLOR_HSV2RGB);
            var    colorRGB = rgb.get(0, 0);
            Scalar c        = new Scalar(colorRGB[0], colorRGB[1], colorRGB[2]);
            obj.setColor(c);
            hsv.Dispose();
        }
        //create structuring element that will be used to "dilate" and "erode" image.
        //the element chosen here is a 3px by 3px rectangle
        erodeElement = Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, new Size(3, 3));
        //dilate with larger element so make sure object is nicely visible
        dilateElement = Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, new Size(3, 3));
        closeElement  = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(8, 8));


        kernel = new Mat(3, 3, CvType.CV_32F);
        kernel.put(0, 0, -1);
        kernel.put(0, 1, -1);
        kernel.put(0, 2, -1);
        kernel.put(1, 0, -1);
        kernel.put(1, 1, 9);
        kernel.put(1, 2, -1);
        kernel.put(2, 0, -1);
        kernel.put(2, 1, -1);
        kernel.put(2, 2, -1);
        channels     = new List <Mat>();
        color_filter = new List <Mat>();
        Utilities.Log("NUMBER of system Threads : " + SystemInfo.processorCount);
    }