Esempio n. 1
0
        private void TPSchangeNegativeMatch(Matrix A)//TPS逆变换变形(配准后)
        {
            Matrix T = new Matrix(1, 71);
            Matrix F = new Matrix(1, 2);
            double distance;

            progressBar1.Maximum = picWidth2;//进度条显示
            progressBar1.Visible = true;


            for (int i = 0; i < picWidth2; i++)
            {
                progressBar1.Value = i;
                progressBar1.PerformStep();
                Application.DoEvents();

                for (int j = 0; j < picHeight2; j++)
                {
                    for (int k = 0; k < 68; k++)//对新图像里的每个点构造矩形求取f(x,y)映射到2图中
                    {
                        distance = Math.Pow(i - Pic1CorNew[k, 0], 2) + Math.Pow(j - Pic1CorNew[k, 1], 2);
                        if (distance == 0)
                        {
                            T[0, k] = 0;
                        }
                        else
                        {
                            T[0, k] = distance * Math.Log(distance);
                        }
                    }
                    T[0, 68] = 1;
                    T[0, 69] = i;
                    T[0, 70] = j;
                    F        = T * A;

                    if (nearest.Checked)
                    {
                        NewPic.SetPixel(i, j, Nearest(F[0, 0], F[0, 1]));
                    }
                    else if (bilinear.Checked)
                    {
                        NewPic.SetPixel(i, j, Bilinear(F[0, 0], F[0, 1]));
                    }
                    else if (bicubic.Checked)
                    {
                        NewPic.SetPixel(i, j, Bicubic(F[0, 0], F[0, 1]));
                    }
                }
            }
        }
Esempio n. 2
0
        private void TPSchangeNegative(Matrix A)//TPS反变换变形
        {
            Matrix T = new Matrix(1, 71);
            Matrix F = new Matrix(1, 2);
            double distance;

            for (int i = 0; i < picWidth2; i++)
            {
                for (int j = 0; j < picHeight2; j++)
                {
                    for (int k = 0; k < 68; k++)//对新图像里的每个点构造矩形求取f(x,y)映射到2图中
                    {
                        distance = Math.Pow(i - Pic1Cor[k, 0], 2) + Math.Pow(j - Pic1Cor[k, 1], 2);
                        if (distance == 0)
                        {
                            T[0, k] = 0;
                        }
                        else
                        {
                            T[0, k] = distance * Math.Log(distance);
                        }
                    }
                    T[0, 68] = 1;
                    T[0, 69] = i;
                    T[0, 70] = j;
                    F        = T * A;
                    if ((int)F[0, 0] < 0 || (int)F[0, 1] < 0 || (int)F[0, 0] >= picWidth2 || (int)F[0, 1] >= picHeight2)
                    {
                        NewPic.SetPixel(i, j, Color.FromArgb(0, 0, 0));
                    }
                    else
                    {
                        NewPic.SetPixel(i, j, OriginalPic2.GetPixel((int)F[0, 0], (int)F[0, 1]));
                    }
                }
            }
        }
Esempio n. 3
0
        private void SPlinechange2()//将小孩的脸与特朗普对齐后进行的B样条反变换(最终采用)
        {
            int Nx = 45, Ny = 45;
            int max = 0;

            for (int I = 0; I < 68; I++)
            {
                int AbsX = (int)Math.Abs(Pic1CorNewInt[I, 0] - Pic2Cor[I, 0]);
                int AbsY = (int)Math.Abs(Pic1CorNewInt[I, 1] - Pic2Cor[I, 1]);
                if (AbsX > max)
                {
                    max = AbsX;
                }
                if (AbsY > max)
                {
                    max = AbsY;
                }
                //Console.WriteLine("AbsX:{0} AbsY:{1}", AbsX, AbsY);
            }
            Console.WriteLine("max:{0}", max);
            if (max <= 45)
            {
                Nx = max;
                Ny = max;
            }
            progressBar1.Maximum = 67;
            progressBar1.Visible = true;

            for (int I = 0; I < 68; I++)
            {
                progressBar1.Value = I;
                progressBar1.PerformStep();
                Application.DoEvents();

                int IndexX = (int)(Pic1CorNewInt[I, 0] / Nx);//确定按控制点分片后新特征点所处的Tiles坐标[IndexX,IndexY]
                int IndexY = (int)(Pic1CorNewInt[I, 1] / Ny);

                double dx = Pic1CorNewInt[I, 0] - Pic2Cor[I, 0];//目标控制点-初始控制点即为位移
                double dy = Pic1CorNewInt[I, 1] - Pic2Cor[I, 1];

                double Tx = 0, Ty = 0;                               //此后循环时的目标点
                int    dx0 = (int)Pic1CorNewInt[I, 0] - IndexX * Nx; //定义两个校正量,把位移到达的点当做控制点
                int    dy0 = (int)Pic1CorNewInt[I, 1] - IndexY * Ny; //注意,此时由于引入配准实际会引入误差,因为要求整数点

                for (int x1 = -2 * Nx; x1 < 2 * Nx; x1++)
                {
                    for (int y1 = -2 * Ny; y1 < 2 * Ny; y1++)//开始遍历4*Nx,4*Ny之间的所有受该控制点平移影响的点(x,y)
                    {
                        int x = (int)Pic1CorNewInt[I, 0] + x1;
                        int y = (int)Pic1CorNewInt[I, 1] + y1;

                        int i = (int)((x - dx0) / Nx) - 1;                         //将默认从(0,0)开始的控制点方格平移为从(2,3)开始
                        int j = (int)((y - dy0) / Ny) - 1;                         //计算该受影响的点落在了被控制点分割出的哪个tile内

                        double u = (double)(x - dx0) / Nx - (int)((x - dx0) / Nx); //计算该受影响的点在所处tile内的offset
                        double v = (double)(y - dy0) / Ny - (int)((y - dy0) / Ny);

                        for (int l = 0; l <= 3; l++)
                        {
                            for (int m = 0; m <= 3; m++)
                            {
                                if ((l + i) == IndexX && (j + m) == IndexY) //对所有遍历的点而言,只有一个控制点的位移不为0,需要计算
                                {
                                    double weight = G(l, u) * G(m, v);      //想要优化可以存一张表
                                    Tx = x - weight * dx;
                                    Ty = y - weight * dy;
                                }
                            }
                        }

                        if (x < 0 || y < 0 || x >= picWidth2 - 1 || y >= picHeight2 - 1)//目标点超出范围了继续下一次循环
                        {
                            continue;
                        }

                        else if (Tx < 0 || Ty < 0 || Tx >= picWidth2 - 1 || Ty >= picHeight2 - 1)
                        {
                            NewPic.SetPixel(x, y, Color.FromArgb(0, 0, 0));//越界返回黑色
                        }
                        else
                        {
                            if (nearest.Checked)
                            {
                                NewPic.SetPixel(x, y, Nearest(Tx, Ty));
                            }
                            else if (bilinear.Checked)
                            {
                                NewPic.SetPixel(x, y, Bilinear(Tx, Ty));
                            }
                            else if (bicubic.Checked)
                            {
                                NewPic.SetPixel(x, y, Bicubic(Tx, Ty));
                            }
                        }
                    }
                }
            }
        }
Esempio n. 4
0
        private void SPlinechange1()//将小孩的脸与特朗普对齐后进行的B样条反变换(对控制点采用最近邻思想,认为某一点发生的位移是离它最近的控制点的位移)
        {
            int Nx = 45, Ny = 45;
            int max = 0;

            for (int I = 0; I < 68; I++)
            {
                int AbsX = (int)Math.Abs(Pic1CorNewInt[I, 0] - Pic2Cor[I, 0]);
                int AbsY = (int)Math.Abs(Pic1CorNewInt[I, 1] - Pic2Cor[I, 1]);
                if (AbsX > max)
                {
                    max = AbsX;
                }
                if (AbsY > max)
                {
                    max = AbsY;
                }
                //Console.WriteLine("AbsX:{0} AbsY:{1}", AbsX, AbsY);
            }
            Console.WriteLine("max:{0}", max);//取平移的最大值作为控制点间距
            if (max <= 45)
            {
                Nx = max;
                Ny = max;
            }
            progressBar1.Maximum = 67;
            progressBar1.Visible = true;

            for (int I = 0; I < 68; I++)
            {
                progressBar1.Value = I;
                progressBar1.PerformStep();
                Application.DoEvents();

                int IndexX = (int)(Pic1CorNewInt[I, 0] / Nx);//确定按控制点分片后新特征点所处的Tiles坐标[IndexX,IndexY]
                int IndexY = (int)(Pic1CorNewInt[I, 1] / Ny);

                double dx = Pic1CorNewInt[I, 0] - Pic2Cor[I, 0];//目标控制点-初始控制点即为位移
                double dy = Pic1CorNewInt[I, 1] - Pic2Cor[I, 1];

                if (Pic1CorNewInt[I, 0] - IndexX * Nx > 0.5 * Nx)//对控制点形成的大格点采用最近邻思想,认为某一点发生的位移是离它最近的控制点的位移
                {
                    Pic1CorNewInt[I, 0] = (IndexX + 1) * Nx;
                    IndexX = IndexX + 1;
                }
                else
                {
                    Pic1CorNewInt[I, 0] = IndexX * Nx;
                }
                if (Pic1CorNewInt[I, 1] - IndexY * Ny > 0.5 * Ny)
                {
                    Pic1CorNewInt[I, 1] = (IndexY + 1) * Ny;
                    IndexY = IndexY + 1;
                }
                else
                {
                    Pic1CorNewInt[I, 1] = IndexY * Ny;
                }

                double Tx = 0, Ty = 0;//此后循环时的目标点

                for (int x1 = -2 * Nx; x1 < 2 * Nx; x1++)
                {
                    for (int y1 = -2 * Ny; y1 < 2 * Ny; y1++)//开始遍历4*Nx,4*Ny之间的所有受该控制点平移影响的点(x,y)
                    {
                        int x = (int)Pic1CorNewInt[I, 0] + x1;
                        int y = (int)Pic1CorNewInt[I, 1] + y1;

                        int i = (int)(x / Nx) - 1;
                        int j = (int)(y / Ny) - 1;                   //计算该受影响的点落在了被控制点分割出的哪个tile内

                        double u = (double)(x / Nx) - (int)(x / Nx); //计算该受影响的点在所处tile内的offset
                        double v = (double)(y / Ny) - (int)(y / Ny);

                        for (int l = 0; l <= 3; l++)
                        {
                            for (int m = 0; m <= 3; m++)
                            {
                                if ((l + i) == IndexX && (j + m) == IndexY) //对所有遍历的点而言,只有一个控制点的位移不为0需要计算
                                {
                                    double weight = G(l, u) * G(m, v);      //想要优化可以存一张表
                                    Tx = x - weight * dx;
                                    Ty = y - weight * dy;
                                }
                            }
                        }

                        if (x < 0 || y < 0 || x >= picWidth2 - 1 || y >= picHeight2 - 1)//目标点超出范围了继续下一次循环
                        {
                            continue;
                        }

                        else if (Tx < 0 || Ty < 0 || Tx >= picWidth2 - 1 || Ty >= picHeight2 - 1)
                        {
                            NewPic.SetPixel(x, y, Color.FromArgb(0, 0, 0));//越界返回黑色
                        }
                        else
                        {
                            if (nearest.Checked)
                            {
                                NewPic.SetPixel(x, y, Nearest(Tx, Ty));
                            }
                            else if (bilinear.Checked)
                            {
                                NewPic.SetPixel(x, y, Bilinear(Tx, Ty));
                            }
                            else if (bicubic.Checked)
                            {
                                NewPic.SetPixel(x, y, Bicubic(Tx, Ty));
                            }
                        }
                    }
                }
            }
        }
Esempio n. 5
0
        private void SPlinechange()//将特朗普的脸与小孩对齐后进行的B样条变换
        {
            int max = 0;

            for (int I = 0; I < 68; I++)
            {
                int AbsX = (int)Math.Abs(Pic1Cor[I, 0] - Pic2CorNew[I, 0]);
                int AbsY = (int)Math.Abs(Pic1Cor[I, 1] - Pic2CorNew[I, 1]);
                if (AbsX > max)
                {
                    max = AbsX;
                }
                if (AbsY > max)
                {
                    max = AbsY;
                }
                Console.WriteLine("AbsX:{0} AbsY:{1}", AbsX, AbsY);
            }
            Console.WriteLine("max:{0}", max);
            int Nx = max, Ny = max;

            for (int I = 0; I < 68; I++)
            {
                int IndexX = (int)(Pic1Cor[I, 0] / Nx);//确定按控制点分片后新点所处的Tiles坐标[IndexX,IndexY]
                int IndexY = (int)(Pic1Cor[I, 1] / Ny);

                double dx = Pic1Cor[I, 0] - Pic2CorNew[I, 0];//目标点-初始点即为位移
                double dy = Pic1Cor[I, 1] - Pic2CorNew[I, 1];
                //Console.WriteLine("X方向位移dx:{0} Y方向位移dy:{1}", dx, dy);

                if (dx > 3 * Nx)
                {
                    dx = 3 * Nx;
                }
                if (dy > 3 * Ny)
                {
                    dy = 3 * Ny;
                }

                double Tx = 0, Ty = 0;                         //目标点
                int    dx0 = (int)Pic1Cor[I, 0] - IndexX * Nx; //定义两个校正量,把位移到达的点当做控制点
                int    dy0 = (int)Pic1Cor[I, 1] - IndexY * Ny; //注意,由于引入配准的话实际会引入误差,因为要求坐标为整数点
                //Console.WriteLine("dx0:{0} dy0:{1}", dx0, dy0);

                double[] Param = MatchNegative();

                for (int x1 = -2 * Nx; x1 < 2 * Nx; x1++)
                {
                    for (int y1 = -2 * Ny; y1 < 2 * Ny; y1++)//开始遍历4*Nx,4*Ny之间的所有受该控制点平移影响的点(x,y)
                    {
                        int x = (int)Pic1Cor[I, 0] + x1;
                        int y = (int)Pic1Cor[I, 1] + y1;
                        //Console.WriteLine("此时将平移到的点的坐标 X:{0} Y:{1}", x, y);


                        int i = (int)((x - dx0) / Nx) - 1; //将默认从(0,0)开始的控制点方格平移为从(2,3)开始
                        int j = (int)((y - dy0) / Ny) - 1; //计算该受影响的点落在了被控制点分割出的哪个tile内
                        //Console.WriteLine("目标点所属tiles下标[{0},{1}]", i, j);

                        double u = (double)(x - dx0) / Nx - (int)((x - dx0) / Nx);//计算该受影响的点在所处tile内的offset
                        double v = (double)(y - dy0) / Ny - (int)((y - dy0) / Ny);
                        //Console.WriteLine("所属tiles下标[{0},{1}]", i, j);

                        for (int l = 0; l <= 3; l++)
                        {
                            for (int m = 0; m <= 3; m++)
                            {
                                if ((l + i) == IndexX && (j + m) == IndexY) //对所有遍历的点而言,只有一个控制点的位移不为0需要计算
                                {
                                    double weight = G(l, u) * G(m, v);      //想要优化可以存一张表
                                    Tx = x - weight * dx;
                                    Ty = y - weight * dy;
                                }
                            }
                        }
                        double[] OriginalCor = MatchNegativeInv(Tx, Ty, Param);

                        if (x < 0 || y < 0 || x >= picWidth2 - 1 || y >= picHeight2 - 1)
                        {
                            continue;
                        }

                        else if (OriginalCor[0] < 0 || OriginalCor[1] < 0 || OriginalCor[0] >= picWidth2 - 1 || OriginalCor[1] >= picHeight2 - 1)
                        {
                            NewPic.SetPixel(x, y, Color.FromArgb(0, 0, 0));//越界返回黑色
                        }
                        else
                        {
                            NewPic.SetPixel(x, y, Nearest(OriginalCor[0], OriginalCor[1]));
                        }
                    }
                }
            }
        }