java - 排序点[]左右和自上而下
问题描述
我在 Android 中使用 OpenCV 从轮廓应用 4 点变换。我Imgproc.findContours
用来寻找轮廓。我找到轮廓的代码:
public MatOfPoint2f FindPaper(Mat edged) {
List<MatOfPoint> contours = new ArrayList<>();
Mat hierarchy = new Mat();
Imgproc.findContours(edged, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
if (contours.size() > 0) {
Collections.sort(contours, new ContourComparator()); // compare by area
for (MatOfPoint cnt : contours) {
MatOfPoint2f matrix = new MatOfPoint2f();
MatOfPoint2f approxMatrix = new MatOfPoint2f();
cnt.convertTo(matrix, CvType.CV_32FC2);
double peri = Imgproc.arcLength(matrix, true);
Imgproc.approxPolyDP(matrix, approxMatrix, 0.02 * peri, true);
if (approxMatrix.size().height == 4){
return approxMatrix;
}
}
}
return null;
}
下面是我的 4 点变换代码:
public Mat FourPointTransform(Mat input, MatOfPoint2f cutMat){
Point[] canonicalPoints = new Point[4];
canonicalPoints[0] = new Point(input.width(), 0);
canonicalPoints[1] = new Point(0,0);
canonicalPoints[2] = new Point(0, input.height());
canonicalPoints[3] = new Point(input.width(), input.height());
MatOfPoint2f canonicalMarker = new MatOfPoint2f();
canonicalMarker.fromArray(canonicalPoints);
// how to sort these points Left-Right to Top-Down?
//Point[] cutPoints = SortPoint(cutMat.toArray());
MatOfPoint2f marker = new MatOfPoint2f(cutMat.toArray());
Mat transform = Imgproc.getPerspectiveTransform(marker, canonicalMarker);
Mat dest = new Mat(input.rows(), input.cols(), input.type());
Imgproc.warpPerspective(input, dest, transform, dest.size());
return dest;
}
有时结果Mat
是FourPointTansform
翻转或旋转的。如何对左右和自上而下的点进行排序?
解决方案
经过几天的反复试验,这是我的数组的正确排序。
public static IEnumerable<PointF> SortPoints(IEnumerable<PointF> input)
{
var sorted = new PointF[4];
var listedInput = input.ToList();
// top-left --> min(x+y)
sorted[0] = listedInput.GroupBy(x => x.X + x.Y).OrderBy(x => x.Key).First().First();
// bottom-right --> max(x+y)
sorted[2] = listedInput.GroupBy(x => x.X + x.Y).OrderByDescending(x => x.Key).First().First();
// top-right --> min(x-y)
sorted[1] = listedInput.GroupBy(x => x.X - x.Y).OrderBy(x => x.Key).First().First();
// bottom-left --> max(x-y)
sorted[3] = listedInput.GroupBy(x => x.X - x.Y).OrderByDescending(x => x.Key).First().First();
return sorted;
}
上面的代码是 C# 并使用 EmguCV。
推荐阅读
- php - Laravel/Php - 使用 Eloquent ORM 调用嵌套模型
- python - IndexError:列表索引超出范围,但索引存在
- logging - Logback @Sl4j Lombok 在默认类的情况下传递附加程序名称
- python - 使用字典和 numpy 优化将数组映射到值的执行时间
- python - 如何从字符串中删除特定字符
- python - 如何通过引用熊猫类似列中的行来估算列中的值?
- xml - 直接引用 XML 元素(在 kotlin 中)
- php - SQLSRV_QUERY 省略 WHERE 条件
- python - 如何在 Pandas 的另一列中查找重复数字时生成一列序号:Python
- windows - Windows ReadFile/WriteFile 保证命名管道