【发布时间】:2021-12-20 17:09:36
【问题描述】:
问题
我在 Windows 窗体对象的面板上绘制了 C# 中的点列表。列表变量是两个listA 和listB。 listB 中的点就是listA 中的点,只是它们经过了一些变换,将其变形为类似于listA 中的点形成的形状,然后添加了一些异常值,使它们看起来不同。如果您可以在您的视觉工作室上尝试这些,那么这就是代码...
class Form1 : Form
{
//declare the list to hold points for
//shapes
List<Point> listA = new List<Point>();
List<Point> listB = new List<Point>();
//this methods transforms,applies outliers and draws the shapes on panel1
private void button1_click(EventArgs e, object sender)
{
//clear the lists for initializing
listA.Clear();
listB.Clear();
Point p1a = new Point(20, 30);
Point p2a = new Point(120, 50);
Point p3a = new Point(160, 80);
Point p4a = new Point(180, 300);
Point p5a = new Point(100, 220);
Point p6a = new Point(50, 280);
Point p7a = new Point(20, 140);
//Hold the Points in an array
Point[] mypoints = new Point[] { p1a, p2a, p3a, p4a, p5a, p6a, p7a };
//add the points to the List with one call
listA.AddRange(mypoints);
//define a new Transformation
//that will translate shapeA to have a slightly different imageB
Transformation t2 = new Transformation();
t2.A = 1.05; t2.B = 0.05; t2.T1 = 15; t2.T2 = 22;
//assign the new translated points to listB
listB = applytransformation(t2, listA);
//Add outliers to listb by manipulating the values in the list
Shape2[2] = new Point(Shape2[2].X + 10, Shape2[2].Y + 3);
//create a new instance of pen
//for drawing imageA in blue
Pen penner = new Pen(Brushes.Blue, 3);
//Create a new instance of pen for
//drawing imageB in red
Pen mypen = new Pen(Brushes.Red, 3);
//get the graphic context
Graphics g = panel1.CreateGraphics();
//draw both shapes
DisplayShape(listA, penner, g);
DisplayShape(listB, mypen, g);
}
//the method below does the transformation of imagea into imageb by manipulating the points and the transformation
List<Point> applytransformation(Transformation x, List<Point> shape)
{
List<Point> Tlist = new List<Point>();
foreach (Point c in shape) {
double xprime = x.A * c.X + x.B * c.Y + x.T1;
double yprime = x.B * c.X * -1 + x.A * c.Y + x.T2;
Point ptrans = new Point((int)xprime, (int)yprime);
Tlist.Add(ptrans);
}
//it returns the points that will be used to draw imageB
return Tlist;
}
//this method draws the points on the panel
void DisplayShape(List<Point> Shp, Pen pen, Graphics G)
{
Point? prevPoint = null;//nullable
foreach (Point pt in Shp) {
G.DrawEllipse(pen, new Rectangle(pt.X - 2, pt.Y - 2, 4, 4));
if (prevPoint != null) {
G.DrawLine(pen, (Point)prevPoint, pt);
}
prevPoint = pt;
}
G.DrawLine(pen, Shp[0], Shp[Shp.Count - 1]);
}
}
public class Transformation
{
public double A { get; set; }
public double B { get; set; }
public double T1 { get; set; }
public double T2 { get; set; }
}
目标
我想删除 imageB 中的所有异常值,以便它类似于 imageA,即使它不是完美的。欢迎所有方法或算法,即RANSAC,minimum cost function。我试图在网上找到一个权威的资源,可以指导或帮助我在 C# 中实现这一目标,但成功率为零。我提供的代码是可以在任何 Visual Studio IDE 上复制的最小可复制示例。请帮助,感谢您的时间和贡献。
预期输出
我添加了一张图片以明确我想要的结果
【问题讨论】:
-
为什么右上角的两个点被替换成了一个?异常值似乎是指向右下角的尖峰。为什么在应用转换之前已经有两条线了?
-
是的,右下角的尖峰是异常值,我在 ransac 中有一个代码来检查错误点并删除它们