// * 仿射变换,目的对齐人脸,使得生成的图像较为自然,避免无用拉伸 private double[] AffineTransformation() { double[][] sourcePointsMatrixData = new double[68][]; double[][] facePointsMatrixData = new double[68][]; double[] facePointsTransformed = new double[this.Face_points.Length]; Parallel.For(0, 68, i => { facePointsMatrixData[i] = new double[3]; facePointsMatrixData[i][0] = this.Face_points[i * 2]; facePointsMatrixData[i][1] = this.Face_points[i * 2 + 1]; facePointsMatrixData[i][2] = 1; sourcePointsMatrixData[i] = new double[2]; sourcePointsMatrixData[i][0] = this.Source_points[i * 2]; sourcePointsMatrixData[i][1] = this.Source_points[i * 2 + 1]; }); MyMatrix sourcePointsMatrix = new MyMatrix(sourcePointsMatrixData); MyMatrix facePointsMatrix = new MyMatrix(facePointsMatrixData); MyMatrix affineTransformationMatrix = new MyMatrix(facePointsMatrix.Transpose().Multiply(facePointsMatrix).Inverse().Multiply(facePointsMatrix.Transpose().Multiply(sourcePointsMatrix))); // 并行计算 Parallel.For(0, 68, i => { facePointsTransformed[i * 2] = affineTransformationMatrix.GetMatrix_data()[0, 0] * this.Face_points[i * 2] + affineTransformationMatrix.GetMatrix_data()[1, 0] * this.Face_points[i * 2 + 1] + affineTransformationMatrix.GetMatrix_data()[2, 0]; facePointsTransformed[i * 2 + 1] = affineTransformationMatrix.GetMatrix_data()[0, 1] * this.Face_points[i * 2] + affineTransformationMatrix.GetMatrix_data()[1, 1] * this.Face_points[i * 2 + 1] + affineTransformationMatrix.GetMatrix_data()[2, 1]; }); return(facePointsTransformed); }
public MyMatrix(MyMatrix sourceMatrix) { _matrix_data = sourceMatrix.GetMatrix_data(); _row = sourceMatrix.Row; _column = sourceMatrix.Column; _square = (this.Row == this.Column) && (this.GetMatrix_data() != null); }
// 矩阵乘法 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); } }
// 转换函数,输入为新图像位置,输出为原图像对应的位置 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); } }