首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >c# -如何按顺时针顺序(tl、tr、br、bl)对包含4个点的列表进行排序,以便在opencv getPerspective中使用?

c# -如何按顺时针顺序(tl、tr、br、bl)对包含4个点的列表进行排序,以便在opencv getPerspective中使用?
EN

Stack Overflow用户
提问于 2019-02-22 04:47:25
回答 2查看 131关注 0票数 0

我正在使用c#中的opencv来检测网络摄像头图像中的轮廓。如果轮廓有4个点,我想使用opencv的getPerspectivewarpPerspective来校正包含在这个轮廓中的像素的透视。函数。

下面是获取这4个点的代码:

代码语言:javascript
复制
    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而使用它),但我假设有一些助手方法可以让我从中吸取教训。

到目前为止,This gist一直是我调整透视图的主要指南,而for_point_warp函数似乎提供了一个不错的指南。我只是不知道c#的等价物。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-02-22 06:16:43

这是我基于this tutorial实现的(尽管我确信我可以做一些更优雅的事情)。

代码语言:javascript
复制
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]);
票数 0
EN

Stack Overflow用户

发布于 2019-02-22 05:08:00

代码语言:javascript
复制
//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 
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54815961

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档