Beispiel #1
0
        // Draws the Delaunay triangulation into an image using the triangle indexes
        private void DrawDelaunay(ref Mat img, ref VectorOfPointF points, VectorOfVectorOfInt triangleIndexes, MCvScalar delaunayColor)
        {
            Size      size = img.Size;
            Rectangle rect = new Rectangle(0, 0, size.Width, size.Height);

            for (int i = 0; i < triangleIndexes.Size; i++)
            {
                VectorOfPoint tri = new VectorOfPoint();
                PointF        pp0 = points[triangleIndexes[i][0]];
                PointF        pp1 = points[triangleIndexes[i][1]];
                PointF        pp2 = points[triangleIndexes[i][2]];
                Point[]       p0  = { new Point((int)pp0.X, (int)pp0.Y) };
                Point[]       p1  = { new Point((int)pp1.X, (int)pp1.Y) };
                Point[]       p2  = { new Point((int)pp2.X, (int)pp2.Y) };
                tri.Push(p0);
                tri.Push(p1);
                tri.Push(p2);

                if (rect.Contains(tri[0]) && rect.Contains(tri[1]) && rect.Contains(tri[2]))
                {
                    CvInvoke.Line(img, tri[0], tri[1], delaunayColor, 2, Emgu.CV.CvEnum.LineType.AntiAlias, 0);
                    CvInvoke.Line(img, tri[1], tri[2], delaunayColor, 2, Emgu.CV.CvEnum.LineType.AntiAlias, 0);
                    CvInvoke.Line(img, tri[2], tri[0], delaunayColor, 2, Emgu.CV.CvEnum.LineType.AntiAlias, 0);
                }
            }
        }
Beispiel #2
0
        //public MorphImage(Mat img1, Mat img2, VectorOfPointF points1, VectorOfPointF points2, float alpha)
        public MorphImage(ImageDetails imgdet1, ImageDetails imgdet2, VectorOfPointF points1, VectorOfPointF points2, float alpha)
        {
            this.img1  = imgdet1.ResizedImage.Mat;
            this.img2  = imgdet2.ResizedImage.Mat;
            this.alpha = alpha;

            img1.ConvertTo(img1, Emgu.CV.CvEnum.DepthType.Cv32F);
            img2.ConvertTo(img2, Emgu.CV.CvEnum.DepthType.Cv32F);

            this.points1 = points1;
            this.points2 = points2;

            if (points1.Size == 68)
            {
                AddCornerPoints(points1, img1);
            }

            if (points2.Size == 68)
            {
                AddCornerPoints(points2, img2);
            }

            // Add Points for whole image
            //points1 = AddCornerPoints(points1, img1); // todo: corner points get added twice
            //points2 = AddCornerPoints(points2, img2);

            // Create an instance of Subdiv2D
            Rectangle rect   = new Rectangle(0, 0, img1.Size.Width, img1.Size.Height);
            Subdiv2D  subdiv = new Subdiv2D(rect);

            // Create and Draw the Delaunay triangulation
            triangleIndexes = new VectorOfVectorOfInt();
            CreateDelaunay(ref img1, ref subdiv, ref points1, false, ref triangleIndexes);

            //// Draw the Delaunay triangulation of face 1
            //Mat img1D = img1.Clone();
            //DrawDelaunay(ref img1D, ref subdiv, new MCvScalar(255, 255, 255));


            //// Draw the Delaunay triangulation of face 2
            //Mat img2D = img2.Clone();
            //DrawDelaunay(ref img2D, ref points2, triangleIndexes, new MCvScalar(255, 255, 255));
            //img2D.ConvertTo(img2D, Emgu.CV.CvEnum.DepthType.Cv8U);

            //compute weighted average point coordinates
            pointsM = new VectorOfPointF();
            for (int i = 0; i < points1.Size; i++)
            {
                float    x  = (1 - alpha) * points1[i].X + alpha * points2[i].X;
                float    y  = (1 - alpha) * points1[i].Y + alpha * points2[i].Y;
                PointF[] pf = { new PointF(x, y) };
                pointsM.Push(pf);
            }

            //empty image for morphed face
            int rowsM, colsM;

            if (img1.Cols >= img2.Cols)
            {
                colsM = img1.Cols;
            }
            else
            {
                colsM = img2.Cols;
            }
            if (img1.Rows >= img2.Rows)
            {
                rowsM = img1.Rows;
            }
            else
            {
                rowsM = img2.Rows;
            }


            imgM = Mat.Zeros(rowsM, colsM, Emgu.CV.CvEnum.DepthType.Cv32F, 3);

            for (int i = 0; i < triangleIndexes.Size; i++)
            {
                VectorOfPointF t1 = new VectorOfPointF();
                VectorOfPointF t2 = new VectorOfPointF();
                VectorOfPointF tM = new VectorOfPointF();

                PointF ppft10 = points1[triangleIndexes[i][0]];
                PointF ppft11 = points1[triangleIndexes[i][1]];
                PointF ppft12 = points1[triangleIndexes[i][2]];
                PointF ppft20 = points2[triangleIndexes[i][0]];
                PointF ppft21 = points2[triangleIndexes[i][1]];
                PointF ppft22 = points2[triangleIndexes[i][2]];
                PointF ppftM0 = pointsM[triangleIndexes[i][0]];
                PointF ppftM1 = pointsM[triangleIndexes[i][1]];
                PointF ppftM2 = pointsM[triangleIndexes[i][2]];

                PointF[] pft10 = { new PointF(ppft10.X, ppft10.Y) };
                PointF[] pft11 = { new PointF(ppft11.X, ppft11.Y) };
                PointF[] pft12 = { new PointF(ppft12.X, ppft12.Y) };
                PointF[] pft20 = { new PointF(ppft20.X, ppft20.Y) };
                PointF[] pft21 = { new PointF(ppft21.X, ppft21.Y) };
                PointF[] pft22 = { new PointF(ppft22.X, ppft22.Y) };
                PointF[] pftM0 = { new PointF(ppftM0.X, ppftM0.Y) };
                PointF[] pftM1 = { new PointF(ppftM1.X, ppftM1.Y) };
                PointF[] pftM2 = { new PointF(ppftM2.X, ppftM2.Y) };

                t1.Push(pft10);
                t1.Push(pft11);
                t1.Push(pft12);
                t2.Push(pft20);
                t2.Push(pft21);
                t2.Push(pft22);
                tM.Push(pftM0);
                tM.Push(pftM1);
                tM.Push(pftM2);

                MorphTriangle(ref img1, ref img2, ref imgM, ref t1, ref t2, ref tM, alpha);
            }
            imgM.ConvertTo(imgM, Emgu.CV.CvEnum.DepthType.Cv8U);
            //CvInvoke.Imshow("Morphed Face", imgM);
        }
Beispiel #3
0
        private void CreateDelaunay(ref Mat img, ref Subdiv2D subdiv, ref VectorOfPointF points,
                                    bool drawAnimated, ref VectorOfVectorOfInt triangleIndexes)
        {
            PointF[] pointsArr = points.ToArray();
            foreach (PointF p in pointsArr)
            {
                subdiv.Insert(p);
                if (drawAnimated)
                {
                    Mat imgCopy = img.Clone();
                    DrawDelaunay(ref imgCopy, ref subdiv, new MCvScalar(255, 255, 255));
                    CvInvoke.Imshow("Delaunay Triangulation", imgCopy);
                }
            }

            // Unfortunately we don't get the triangles by there original point indexes.
            // We only get them with their vertex coordinates.
            // So we have to map them again to get the triangles with their point indexes.

            Size      size = img.Size;
            Rectangle rect = new Rectangle(0, 0, size.Width, size.Height);

            VectorOfInt ind = new VectorOfInt();

            int[]         indArr       = new int[3];
            Triangle2DF[] triangleList = subdiv.GetDelaunayTriangles();
            for (int i = 0; i < triangleList.Length; i++)
            {
                Triangle2DF t = triangleList[i];

                PointF ptzero = new PointF {
                    X = t.V0.X, Y = t.V0.Y
                };
                PointF[] PZero = new PointF[] { ptzero };

                PointF ptone = new PointF {
                    X = t.V1.X, Y = t.V1.Y
                };
                PointF[] POne = new PointF[] { ptone };

                PointF pttwo = new PointF {
                    X = t.V2.X, Y = t.V2.Y
                };
                PointF[] PTwo = new PointF[] { pttwo };

                VectorOfPointF pt = new VectorOfPointF();

                pt.Push(PZero);

                pt.Push(POne);
                pt.Push(PTwo);

                if (rect.Contains(new Point((int)pt[0].X, (int)pt[0].Y)) &&
                    rect.Contains(new Point((int)pt[1].X, (int)pt[1].Y)) &&
                    rect.Contains(new Point((int)pt[2].X, (int)pt[2].Y)))
                {
                    for (int j = 0; j < 3; j++)
                    {
                        for (int k = 0; k < points.Size; k++)
                        {
                            if (Math.Abs(pt[j].X - points[k].X) < 1.0 &&
                                Math.Abs(pt[j].Y - points[k].Y) < 1)
                            {
                                indArr[j] = k;
                            }
                        }
                    }
                }
                ind = new VectorOfInt(indArr);
                triangleIndexes.Push(ind);
            }
        }
Beispiel #4
0
      public void TestVectorOfVector()
      {
         int[][] v0 = new int[][]
         {
            new int[] {1, 2, 3},
            new int[] {4, 5}, 
            new int[] {6}
         };

         using (VectorOfVectorOfInt v = new VectorOfVectorOfInt(v0))
         {
            int[][] v1 = v.ToArrayOfArray();

            for (int i = 0; i < v0.Length; i++)
            {
               int[] a = v0[i];
               int[] b = v1[i];
               for (int j = 0; j < a.Length; j++)
               {
                  EmguAssert.IsTrue(a[j] == b[j]);
               }
            }
         }

      }