public Image <Bgr, byte> Warp(List <SupLine> list_dest, double a = 1, double b = 2, double p = 0) { Image <Bgr, byte> ans = new Image <Bgr, byte>(origin.Size); for (int i = 0; i < ans.Width; i++) { for (int j = 0; j < ans.Height; j++) { SupPoint dest = new SupPoint(i, j); SupPoint sour = new SupPoint(0, 0); List <double> weight = new List <double>(); double weight_sum = 0; List <SupPoint> loc = new List <SupPoint>(); for (int k = 0; k < list_dest.Count; k++) { double u = list_dest[k].GetProjectionScale(dest); double v = list_dest[k].GetPerpendicularLength(dest); SupPoint temp = LineList[k].Begin + u * LineList[k].Vector + v * new SupPoint(LineList[k].Vector.Y, -LineList[k].Vector.X) / LineList[k].Vector.Length; double dist = Math.Abs(u < 0 ? (temp - LineList[k].Begin).Length : (u > 1 ? (temp - LineList[k].End).Length : LineList[k].GetPerpendicularLength(temp))); double w = Math.Pow(Math.Pow(list_dest[k].Vector.Length, p) / (a + dist), b); weight_sum += w; weight.Add(w); loc.Add(temp); } for (int k = 0; k < weight.Count; k++) { sour += (weight[k] / weight_sum) * loc[k]; } Point SP = new Point((int)Math.Round(sour.X), (int)Math.Round(sour.Y)); if (SP.X < 0) { SP.X = 0; } if (SP.Y < 0) { SP.Y = 0; } if (SP.X >= ans.Width) { SP.X = ans.Width - 1; } if (SP.Y >= ans.Height) { SP.Y = ans.Height - 1; } ans[new Point(i, j)] = Bilinear((SupPoint)SP); } } return(ans); }
private Bgr Bilinear(SupPoint p) { MCvScalar result = new MCvScalar(0, 0, 0); SupPoint basep = new SupPoint(Math.Floor(p.X), Math.Floor(p.Y)); if (basep.X >= origin.Width - 1 || basep.Y >= origin.Height - 1) { return(origin[(int)basep.Y, (int)basep.X]); } double a = p.X - basep.X; double b = p.Y - basep.Y; Bgr lt = origin[(int)basep.Y, (int)basep.X]; Bgr lb = origin[(int)basep.Y + 1, (int)basep.X]; Bgr rt = origin[(int)basep.Y, (int)basep.X + 1]; Bgr rb = origin[(int)basep.Y + 1, (int)basep.X + 1]; double blue = (1 - a) * (1 - b) * lt.Blue + (1 - a) * b * lb.Blue + a * (1 - b) * rt.Blue + a * b * rb.Blue; double green = (1 - a) * (1 - b) * lt.Green + (1 - a) * b * lb.Green + a * (1 - b) * rt.Green + a * b * rb.Green; double red = (1 - a) * (1 - b) * lt.Red + (1 - a) * b * lb.Red + a * (1 - b) * rt.Red + a * b * rb.Red; return(new Bgr(blue, green, red)); }