Exemple #1
0
 // 构造函数
 public FaceTransformation(string source_path, string face_path)
 {
     _source_path        = source_path;
     _source_points_path = source_path.Split('.')[0] + ".txt";
     _source             = new ImageIO(source_path);
     _source.LockBits();
     _source_points    = this.LoadPoints(this.Source_points_path);
     _source_marked    = this.MarkPoints(this.Source, this.Source_points);
     _face_path        = face_path;
     _face_points_path = face_path.Split('.')[0] + ".txt";
     _face             = new ImageIO(face_path);
     _face.LockBits();
     _face_points          = this.LoadPoints(this.Face_points_path);
     _face_marked          = this.MarkPoints(this.Face, this.Face_points);
     _facePointsAffined    = this.AffineTransformation();
     _TPS_transform_matrix = this.TPSTransformMatrix();
     _source.UnlockBits();
     _face.UnlockBits();
 }
Exemple #2
0
        // TPS变换,输入为新图像中的坐标,输出为原图像中的坐标
        public MyMatrix TPSProcessMatrix(double x, double y)
        {
            double[,] processMatrixData = new double[71, 1];
            Parallel.For(0, 71, i =>
            {
                if (i < 68)
                {
                    processMatrixData[i, 0] = RadialBasisFunction(this.FacePointsAffined[2 * i], x, this.FacePointsAffined[2 * i + 1], y);
                }
                else
                {
                    switch (i)
                    {
                    case 68:
                        {
                            processMatrixData[i, 0] = 1;
                            break;
                        }

                    case 69:
                        {
                            processMatrixData[i, 0] = x;
                            break;
                        }

                    case 70:
                        {
                            processMatrixData[i, 0] = y;
                            break;
                        }
                    }
                }
            });
            MyMatrix processMatrix = new MyMatrix(processMatrixData, 71, 1);
            MyMatrix process       = new MyMatrix(processMatrix);

            return(process);
        }
 // 矩阵乘法
 public MyMatrix Multiply(MyMatrix myMatrix)
 {
     if (this.Column == myMatrix.Row)
     {
         double[,] processData = new double[this.Row, myMatrix.Column];
         for (int i = 0; i < this.Row; i++)
         {
             for (int j = 0; j < myMatrix.Column; j++)
             {
                 processData[i, j] = 0;
                 for (int m = 0; m < this.Column; m++)
                 {
                     processData[i, j] += this.GetMatrix_data()[i, m] * myMatrix.GetMatrix_data()[m, j];
                 }
             }
         }
         return(new MyMatrix(processData, this.Row, myMatrix.Column));
     }
     else
     {
         return(null);
     }
 }
Exemple #4
0
        // TPS变换矩阵求解
        private MyMatrix TPSTransformMatrix()
        {
            double[][] LMatrixData = new double[71][];
            double[][] YMatrixData = new double[71][];
            Parallel.For(0, 71, i =>
            {
                LMatrixData[i] = new double[71];
                Parallel.For(0, 71, j =>
                {
                    if ((i < 68) && (j < 68))
                    {
                        if (i == j)
                        {
                            LMatrixData[i][j] = 0;
                        }
                        else
                        {
                            LMatrixData[i][j] = RadialBasisFunction(this.FacePointsAffined[2 * i], this.FacePointsAffined[2 * j], this.FacePointsAffined[2 * i + 1], this.FacePointsAffined[2 * j + 1]);
                        }
                    }
                    else if ((i < 68) && (j >= 68))
                    {
                        switch (j)
                        {
                        case 68: LMatrixData[i][j] = 1; break;

                        case 69: LMatrixData[i][j] = this.FacePointsAffined[2 * i]; break;

                        case 70: LMatrixData[i][j] = this.FacePointsAffined[2 * i + 1]; break;
                        }
                    }
                    else if ((i >= 68) && (j < 68))
                    {
                        switch (i)
                        {
                        case 68: LMatrixData[i][j] = 1; break;

                        case 69: LMatrixData[i][j] = this.FacePointsAffined[2 * j]; break;

                        case 70: LMatrixData[i][j] = this.FacePointsAffined[2 * j + 1]; break;
                        }
                    }
                    else
                    {
                        LMatrixData[i][j] = 0;
                    }
                });
                YMatrixData[i] = new double[2];
                if (i < 68)
                {
                    YMatrixData[i][0] = this.Source_points[2 * i];
                    YMatrixData[i][1] = this.Source_points[2 * i + 1];
                }
                else
                {
                    YMatrixData[i][0] = 0;
                    YMatrixData[i][1] = 0;
                }
            });
            MyMatrix LMatrix         = new MyMatrix(LMatrixData);
            MyMatrix YMatrix         = new MyMatrix(YMatrixData);
            MyMatrix TransformMatrix = new MyMatrix(LMatrix.Inverse().Multiply(YMatrix).Transpose());

            return(TransformMatrix);
        }
Exemple #5
0
        // 转换函数,输入为新图像位置,输出为原图像对应的位置
        private Poseition TransformFunction(double x, double y)
        {
            switch (this.ProcessOption.Transform)
            {
            // 旋转扭曲,使用题目给出的函数计算
            case Transform.Distortion:
            {
                if (this.DistortionParameter == null)
                {
                    return(null);
                }
                else
                {
                    double new_x    = x;
                    double new_y    = y;
                    double distance = Math.Sqrt(Math.Pow(Convert.ToDouble(x - this.DistortionParameter.DistortionCenter_x) / this.DistortionParameter.Factor_x, 2) + Math.Pow(Convert.ToDouble(y - this.DistortionParameter.DistortionCenter_y) / this.DistortionParameter.Factor_y, 2));
                    if (distance < this.DistortionParameter.DistortionRadius)
                    {
                        double distortionDegree = -this.DistortionParameter.MaxDistortionDegree * ((this.DistortionParameter.DistortionRadius - distance) / this.DistortionParameter.DistortionRadius);
                        new_x = ((x - this.DistortionParameter.DistortionCenter_x) * Math.Cos(distortionDegree) - (y - this.DistortionParameter.DistortionCenter_y) * Math.Sin(distortionDegree)) + this.DistortionParameter.DistortionCenter_x;
                        new_y = ((x - this.DistortionParameter.DistortionCenter_x) * Math.Sin(distortionDegree) + (y - this.DistortionParameter.DistortionCenter_y) * Math.Cos(distortionDegree)) + this.DistortionParameter.DistortionCenter_y;
                    }
                    return(new Poseition(new_x, new_y));
                }
            }

            // * 畸变矫正,题目给出的函数实现效果不佳,查询网络相关实现方法后,学习、改进并实现了自己的转换方法
            case Transform.Warp:
            {
                if (this.WarpParameter == null)
                {
                    return(null);
                }
                else
                {
                    double new_x    = x;
                    double new_y    = y;
                    double distance = Math.Sqrt(Math.Pow(Convert.ToDouble(x - this.WarpParameter.WarpCenter_x) / this.WarpParameter.Factor_x, 2) + Math.Pow(Convert.ToDouble(y - this.WarpParameter.WarpCenter_y) / this.WarpParameter.Factor_y, 2));
                    if (distance != 0)
                    {
                        double k = this.WarpParameter.WarpFactor * (Math.Pow(distance, 2) / this.WarpParameter.WarpScale);
                        new_x = (1 + k) * (x - this.WarpParameter.WarpCenter_x) + this.WarpParameter.WarpCenter_x;
                        new_y = (1 + k) * (y - this.WarpParameter.WarpCenter_y) + this.WarpParameter.WarpCenter_y;
                    }
                    return(new Poseition(new_x, new_y));
                }
            }

            // TPS变换,使用题目给的变换方法并做了相关改进,详见 FaceTransformation.cs
            case Transform.TPS:
            {
                MyMatrix newPosition = new MyMatrix(this.FaceTransformation.TPS_transform_matrix.Multiply(this.FaceTransformation.TPSProcessMatrix(x, y)));
                return(new Poseition(newPosition.GetMatrix_data()[0, 0], newPosition.GetMatrix_data()[1, 0]));
            }

            // 无变换,直接插值
            case Transform.None:
            {
                return(new Poseition(x, y));
            }

            default: return(null);
            }
        }