如何根据角点和单元格数计算交点
How to calculate intersection points based on corners and number of cells
我试图根据我一直拥有的 4 个角点和单元格数量(在我的例子中是 9,所以 9x9 矩阵,数独游戏)找到所有交点(它们的 x 和 y 值)。
我的4个角都标上了绿色叉号,分别标记为P1到P4。
我试着计算了一下,结果只能准确计算出第一行。
double xDis = p2.x - p1.x;
double yDis = p2.y - p1.y;
double xW = xDis / 9;
double yH = yDis / 9;
for (int i = 0; i < 10; i++) {
Point point = new Point(p1.x + (i * xW), p1.y + (i * yH));
}
此代码将完全按照我的预期运行,但仅适用于第一行。
我在这里错过了什么?是否有某种算法已经做到了这一点?欢迎任何提示。
请注意,我将 android 与 OpenCV 库一起使用。
您只计算一次,在第一行。
将您的 for 循环放在另一个 for 循环中,运行 循环 10 次,您应该会很好(添加在 y 中向下遍历时发生的任何 x,y 转换)。
至于是否有自动执行此操作的方法,是的。我可以建议使用 Harris Corner Detection。我怀疑使用正确的阈值只会让你得到更粗的线角。您也可以尝试进行线检测和寻找交叉点。
此外,this 如果您发现自己找不到好的文章 lines/corners,文章可能会对您有所帮助。您可以校正照明的阴影并获得清晰的图像进行分析。
正如上面评论中所写,我最终扭曲了图像然后进行了切割。它看起来像这样
if (points != null) {
Point p1 = points[0];
Point p2 = points[1];
Point p3 = points[2];
Point p4 = points[3];
MatOfPoint2f src = new MatOfPoint2f(
p1,
p2,
p3,
p4);
drawMarker(frame, p1, new Scalar(255,0,0), 0, 20, 1);
drawMarker(frame, p2, new Scalar(255,0,0), 0, 20, 1);
drawMarker(frame, p3, new Scalar(255,0,0), 0, 20, 1);
drawMarker(frame, p4, new Scalar(255,0,0), 0, 20, 1);
double x = p2.x - p1.x;
double y = p3.y - p2.y;
MatOfPoint2f dst = new MatOfPoint2f(
new Point(0, 0),
new Point(x,0),
new Point(0,y),
new Point(x,y)
);
Mat warpMat = Imgproc.getPerspectiveTransform(src, dst);
//This is you new image as Mat
Mat destImage = new Mat();
Imgproc.warpPerspective(bw2, destImage, warpMat, new Size(x, y));
List<Mat> cells = getCells(destImage, destImage.width() / 9, destImage.height / 9);
}
private List<Mat> getCells(Mat m, int width, int height) {
Size cellSize = new Size(width, height);
List<Mat> cells = new ArrayList<>();
for (int row = 0; row < 9; row++) {
for (int col = 0; col < 9; col++) {
Rect rect = new Rect(new Point(col * width, row * height), cellSize);
Mat digit = new Mat(m, rect).clone();
cells.add(digit);
}
}
return cells;
}
我试图根据我一直拥有的 4 个角点和单元格数量(在我的例子中是 9,所以 9x9 矩阵,数独游戏)找到所有交点(它们的 x 和 y 值)。
我的4个角都标上了绿色叉号,分别标记为P1到P4。 我试着计算了一下,结果只能准确计算出第一行。
double xDis = p2.x - p1.x;
double yDis = p2.y - p1.y;
double xW = xDis / 9;
double yH = yDis / 9;
for (int i = 0; i < 10; i++) {
Point point = new Point(p1.x + (i * xW), p1.y + (i * yH));
}
此代码将完全按照我的预期运行,但仅适用于第一行。 我在这里错过了什么?是否有某种算法已经做到了这一点?欢迎任何提示。 请注意,我将 android 与 OpenCV 库一起使用。
您只计算一次,在第一行。
将您的 for 循环放在另一个 for 循环中,运行 循环 10 次,您应该会很好(添加在 y 中向下遍历时发生的任何 x,y 转换)。
至于是否有自动执行此操作的方法,是的。我可以建议使用 Harris Corner Detection。我怀疑使用正确的阈值只会让你得到更粗的线角。您也可以尝试进行线检测和寻找交叉点。
此外,this 如果您发现自己找不到好的文章 lines/corners,文章可能会对您有所帮助。您可以校正照明的阴影并获得清晰的图像进行分析。
正如上面评论中所写,我最终扭曲了图像然后进行了切割。它看起来像这样
if (points != null) {
Point p1 = points[0];
Point p2 = points[1];
Point p3 = points[2];
Point p4 = points[3];
MatOfPoint2f src = new MatOfPoint2f(
p1,
p2,
p3,
p4);
drawMarker(frame, p1, new Scalar(255,0,0), 0, 20, 1);
drawMarker(frame, p2, new Scalar(255,0,0), 0, 20, 1);
drawMarker(frame, p3, new Scalar(255,0,0), 0, 20, 1);
drawMarker(frame, p4, new Scalar(255,0,0), 0, 20, 1);
double x = p2.x - p1.x;
double y = p3.y - p2.y;
MatOfPoint2f dst = new MatOfPoint2f(
new Point(0, 0),
new Point(x,0),
new Point(0,y),
new Point(x,y)
);
Mat warpMat = Imgproc.getPerspectiveTransform(src, dst);
//This is you new image as Mat
Mat destImage = new Mat();
Imgproc.warpPerspective(bw2, destImage, warpMat, new Size(x, y));
List<Mat> cells = getCells(destImage, destImage.width() / 9, destImage.height / 9);
}
private List<Mat> getCells(Mat m, int width, int height) {
Size cellSize = new Size(width, height);
List<Mat> cells = new ArrayList<>();
for (int row = 0; row < 9; row++) {
for (int col = 0; col < 9; col++) {
Rect rect = new Rect(new Point(col * width, row * height), cellSize);
Mat digit = new Mat(m, rect).clone();
cells.add(digit);
}
}
return cells;
}