如何根据角点和单元格数计算交点

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;
}