为了账号安全,请及时绑定邮箱和手机立即绑定

c# - 如何按顺时针顺序对 4 个点的列表进行排序?

c# - 如何按顺时针顺序对 4 个点的列表进行排序?

当年话下 2021-11-16 09:37:05
我在 c# 中使用 opencv 来检测网络摄像头图像中的轮廓。如果轮廓有 4 个点,我想用它来使用 opencv 的getPerspective和warpPerspective. 职能。这是获得这4点的代码:    Imgproc.approxPolyDP(perimMat,polyMat,0.005 * perim, true); //get contour of the current detected perimeter as polyMat    List<Point> polyMatList = polyMat.toList(); //convert it to a list of points    if (polyMatList.Count == 4){ //this contour has 4 points, we can use it for getting perspective      Debug.Log("p1x: " + polyMatList[0].x + "p1y: " + polyMatList[0].y); //example log: p1x: 203,p1y: 111    }所以现在我有了这个点列表,我需要确保它是按左上角、右上角、右下角、左下角的顺序排列的,这样我就可以在getPerspective. 我该怎么做呢?我看过其他语言的例子,但他们通常使用 numpy 之类的东西来进行排序。我对 C# 有点陌生(因为 Unity 使用它),但我假设有一些辅助方法我可以以某种方式借鉴。到目前为止,这个要点一直是我调整视角的主要指南,该for_point_warp功能似乎提供了一个不错的指南。我只是不知道 c# 等价物。
查看完整描述

2 回答

?
青春有我

TA贡献1784条经验 获得超8个赞

//Begin by sorting your list by y values using List.sort()


polyMatList.sort( (pnt_a, pnt_b) => pnt_b.y - pnt_a.y ); // points 0 & 1 will by definition be your top points and points 2, 3 will be definition be your bottom points.


// now your top 2 points may be out of order since we only sorted by y in the previous step

Point tempPoint;


if(polyMatList[0].x > polyMatList[1].x)

{

   tempPoint = polyMatList[0];

   polyMatList[0] = polyMatList[1];

   polyMatList[1] = tempPoint ;

}


// same goes for your bottom two points 

if(polyMatList[2].x > polyMatList[3].x)

{

   tempPoint = polyMatList[2];

   polyMatList[2] = polyMatList[3];

   polyMatList[3] = tempPoint ;

}


//now your list will be ordered tl, tr, bl, br 


查看完整回答
反对 回复 2021-11-16
?
函数式编程

TA贡献1807条经验 获得超9个赞

这是我根据本教程实现的(尽管我确信我可以做一些更优雅的事情)。


polyMat.convertTo(orientationMat, CvType.CV_32S); //conver MatOfPoint2f back to MatofPoint so it can be drawn

//sort by y val


polyMatList = polyMatList.OrderBy(p => p.x).ToList();


List<Point> leftmostPts = new List<Point>();

leftmostPts.Add(polyMatList[0]);

leftmostPts.Add(polyMatList[1]);


List<Point> rightmostPts = new List<Point>();

rightmostPts.Add(polyMatList[2]);

rightmostPts.Add(polyMatList[3]);


//we now have a top left point

leftmostPts = leftmostPts.OrderBy(p => p.y).ToList();


//calculate distance from top left to rightmost 2 points:

double dX0 = rightmostPts[0].x - leftmostPts[0].x;

double dY0 = rightmostPts[0].y - leftmostPts[0].y;

double d0 = Math.Sqrt(dX0 * dX0 + dY0 * dY0); 


double dX1 = rightmostPts[1].x - leftmostPts[0].x;

double dY1 = rightmostPts[1].y - leftmostPts[0].y;

double d1 = Math.Sqrt(dX1 * dX1 + dY1 * dY1);


List<Point> orderedPolyMat = new List<Point>();

orderedPolyMat.Add(leftmostPts[0]);

if (d0 > d1){ //greatest distance between right two points will be bottom right

    orderedPolyMat.Add(rightmostPts[1]);

    orderedPolyMat.Add(rightmostPts[0]);

} else {

    orderedPolyMat.Add(rightmostPts[0]);

    orderedPolyMat.Add(rightmostPts[1]);

}

orderedPolyMat.Add(leftmostPts[1]);


查看完整回答
反对 回复 2021-11-16
  • 2 回答
  • 0 关注
  • 509 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信