/// <summary> /// Резиновая трансформация изображений /// </summary> /// <param name="boxFrom"></param> /// <param name="boxTo"></param> private void RubberWarping(EntityBox boxFrom, EntityBox boxTo) { Delaunay delaunay = new Delaunay(); // // Получить ключевые точки // List <Point2D> pointsLeft = GetKeypoints(boxFrom); List <Point2D> pointsRight = GetKeypoints(boxTo); // // Добавить точки по краям изображения // float gapFromWidth = 25; float gapFromHeight = 25; float scale = new Vec(pointsLeft[0], pointsLeft[1]).Length() / new Vec(pointsRight[0], pointsRight[1]).Length(); float gapToWidth = gapFromWidth * scale; float gapToHeight = gapFromHeight * scale; AddCornerKeypoints(ref pointsLeft, gapFromWidth, gapFromHeight); AddCornerKeypoints(ref pointsRight, gapToWidth, gapToHeight); // // Триангулируем // List <Triangle> mesh = delaunay.GenMesh(pointsLeft); // // Сформировать изображение справа // Point2D bottomDownTo = BottomDownPoint(pointsRight); Bitmap bitmap = new Bitmap((int)bottomDownTo.X + 1, (int)bottomDownTo.Y + 1); Graphics gr = Graphics.FromImage(bitmap); gr.Clear(Color.Gray); boxTo.Image0 = bitmap; // // Трилатеральный перенос треугольников левого изображения в правое // foreach (Triangle sourceTri in mesh) { Triangle destTri = new Triangle(); destTri.a = MapPoint(sourceTri.a, pointsRight); destTri.b = MapPoint(sourceTri.b, pointsRight); destTri.c = MapPoint(sourceTri.c, pointsRight); NonAffineTransform.WarpTriangle(boxFrom.Image0, boxTo.Image0, sourceTri, destTri); } }
private void trilateralTestToolStripMenuItem_Click(object sender, EventArgs e) { Triangle sourceTri = new Triangle(); sourceTri.a = new Point2D(466, 191); sourceTri.b = new Point2D(285, 419); sourceTri.c = new Point2D(636, 462); Triangle destTri = new Triangle(); destTri.a = new Point2D(316, 243); destTri.b = new Point2D(194, 350); destTri.c = new Point2D(383, 372); Point2D n = new Point2D(268, 285); Point2D n2 = NonAffineTransform.TrilateralXform(sourceTri, destTri, n); Console.WriteLine("X: " + n2.X.ToString() + ", Y: " + n2.Y.ToString()); }
/// <summary> /// Из левой части с изображением и тремя точками нарисовать треугольник в правой части /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void drawTexturedTriangleFromLeftImageToolStripMenuItem_Click(object sender, EventArgs e) { List <Entity> _selectedLeft = entityBox1.GetSelected(); List <Entity> _selectedRight = entityBox2.GetSelected(); // // Проверить что изображение в левой части загружено // if (entityBox1.Image0 == null) { MessageBox.Show("Load image on Left", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } // // Проверить что ключевые точки слева выделены правильно // if (_selectedLeft.Count != 3) { MessageBox.Show("Select exactly 3 keypoints to form triangle", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } foreach (Entity entity in _selectedLeft) { if (!entity.IsVias()) { MessageBox.Show("Select keypoints only", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } } // // Проверить что ключевые точки справа выделены правильно // if (_selectedRight.Count != 3) { MessageBox.Show("Select exactly 3 keypoints to form triangle", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } foreach (Entity entity in _selectedRight) { if (!entity.IsVias()) { MessageBox.Show("Select keypoints only", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } } // // Сформировать изображение справа // Bitmap bitmap = new Bitmap(entityBox1.Image0.Width * 3, entityBox1.Image0.Height * 3); Graphics gr = Graphics.FromImage(bitmap); gr.Clear(Color.White); entityBox2.Image0 = bitmap; // // Сформировать параметры // Triangle sourceTri = new Triangle(); Point a0 = entityBox1.LambdaToImage(_selectedLeft[0].LambdaX, _selectedLeft[0].LambdaY); Point a1 = entityBox1.LambdaToImage(_selectedLeft[1].LambdaX, _selectedLeft[1].LambdaY); Point a2 = entityBox1.LambdaToImage(_selectedLeft[2].LambdaX, _selectedLeft[2].LambdaY); sourceTri.a = new Point2D(a0.X, a0.Y); sourceTri.b = new Point2D(a1.X, a1.Y); sourceTri.c = new Point2D(a2.X, a2.Y); Triangle destTri = new Triangle(); Point b0 = entityBox2.LambdaToImage(_selectedRight[0].LambdaX, _selectedRight[0].LambdaY); Point b1 = entityBox2.LambdaToImage(_selectedRight[1].LambdaX, _selectedRight[1].LambdaY); Point b2 = entityBox2.LambdaToImage(_selectedRight[2].LambdaX, _selectedRight[2].LambdaY); destTri.a = new Point2D(b0.X, b0.Y); destTri.b = new Point2D(b1.X, b1.Y); destTri.c = new Point2D(b2.X, b2.Y); NonAffineTransform.WarpTriangle(entityBox1.Image0, entityBox2.Image0, sourceTri, destTri); }