【问题标题】:Finding the number of possible squares in this picture [closed]在这张图片中找到可能的正方形的数量[关闭]
【发布时间】:2012-07-25 00:53:36
【问题描述】:

以下是我今天遇到的一个视觉问题。这里的问题只是图片中有多少个正方形。

您将如何通过代码解决此类问题?另外,如果不处理实际的图片,你会怎么建模呢?

P.S:我感觉实际的分辨率需要一个规则来定义什么可以被视为正方形。类似于说边的长度相等并且可以由任意数量的线段组成,只要它们适合封闭的正方形。不过,我不确定您如何代表一个职位。

【问题讨论】:

  • 我看到了很多很多的正方形,但我怀疑它们中的许多只是使用有损 JPEG 压缩而不是更合适的 PNG 格式的产物。
  • 我知道这并不能完全回答你的问题,但我认为这个关于 SO 的答案可能会引导你朝着你正在寻找的正确方向前进:stackoverflow.com/a/11628969/337315 我相信寻找这条线从起点(比如一个角)开始分段,然后沿着正方形,您可以根据您的发现在代码中创建一个矩阵。然后您可以从该矩阵中得出正方形的数量。
  • 我在黑线的每个交叉点看到一些非常难以捉摸的白色小方块:当我试图专注于它们时,它们消失了。
  • @MarkByers 是的,对质量感到抱歉。它脱离了 JPEG 通常是常态的社交网络。为了这个问题,只应考虑实心黑线。
  • 仅从外观来看,我认为这是一个棘手的问题。当您知道四叉树、kd-tree 或空间填充曲线是什么时,这个符号就没有任何意义,而只是证明您有时可以混合计数和数字。

标签: algorithm language-agnostic rules


【解决方案1】:

如果您可以将其建模为矩阵,那么您需要的唯一信息就是顶点的位置。然后为每个顶点检查同一行中的所有顶点,并为每个找到的顶点检查它们的列。然后删除处理过的顶点。逐列执行相同的操作。最坏情况的复杂度是 n! (?)

我添加了代码以进行澄清。

public class SqFinder {
        int calculateSquares(int[][] vertices, int n) {
            int count = 0;
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    if (vertices[i][j] == 1) {
                        for (int k = 1; k < n-j; k++) {
                            if (i + k < n && vertices[i][j+k] == 1 && vertices[i + k][j] == 1 && vertices[i + k][j + k] == 1)
                                count++;
                        }
                    }
                    vertices[i][j] =0;
                }
            }
            return count;
        }

        public static void main(String[] args) {
            SqFinder a = new SqFinder();
    //      int [][] test = {{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}};
            int [][] test = {{1,1,1},{1,1,1},{1,1,1}};
            System.out.println(a.calculateSquares(test, 3));
        }
    }

【讨论】:

  • 要么你的解释对我来说太微妙了,要么就是难以理解。我很确定是后者,因为您甚至没有描述如何识别或计算任何正方形。
  • @Marcin :识别一个正方形:假设我们在第 x 行。在 y 列和 y+j 列的同一行中有两个顶点。那么 (x+j,y) 和 (x+j,y+j) 中应该有另外两个顶点。在这种情况下,您将有一个正方形。在计算所有包含点 (x,j) 的正方形后,将其删除以避免冗余。
  • 您确实意识到发布此评论只是在证明您的答案不完整?
  • @Marcin :我添加了代码。希望对您有所帮助。
【解决方案2】:

最简单的方法是遍历每个顶点,并检查它是否可以是宽度为 1、宽度为 2、宽度为 3 等正方形的左上顶点。

【讨论】:

    【解决方案3】:

    编码:你所拥有的是一个网络。将其编码为连接位于离散二维空间中的节点的网络。

    问题其实是要你数一下满足以下属性的路径的数量:

    1. 有3圈
    2. 每个这样的转弯之间的长度是相等的
    3. 路径的起点和终点相同。

    在这种情况下,转弯是指 (a) 如果前一次移动导致 y 坐标发生变化,则该移动会导致 x 坐标发生变化;或者 (b) 如果之前的移动导致 x 坐标发生变化,则这次移动会导致 y 坐标发生变化。

    关于跟踪过程:我在此页面上看到的最佳建议是简单地遍历每个节点,并为每个这样的节点检查所有可能的正方形大小。这应该避免进一步跟踪的需要。

    如果您有更聪明的方法,只要您的路径始终是左手或右手,每个正方形都由起始顶点和边长唯一标识。

    【讨论】:

    • 这是一个网络,我理解这种方法。你有什么建议可以跟踪已经计算过的方格吗?
    • @JamesPoulson 我在这个页面上看到的最好的建议是简单地遍历每个节点,并为每个这样的节点检查所有可能的正方形大小。这应该避免进一步跟踪的需要。如果你有更聪明的方法,只要你的路径总是左手或右手,每个正方形都由起始顶点和边长唯一标识。
    • @JamesPoulson 另外,如果您最终编写了此代码,我鼓励您将其发布为答案。
    • 是的,不能在接下来的几周内做出任何承诺,但如果我通过此处发布的答案找到解决方案,我会发布答案。
    【解决方案4】:

    应该这样做:

    int line_width = 1; //the width of the square line
    int squares = 0;
    for (int x = 0; x < width; ++x)
    {
        for (int y = 0; y < height; ++y)
        {
            for (int size = line_width; x + size < width && y + size < height; ++x)
            {
                if (valid_square_at(x, y, x + size, y + size, line_width))
                {
                    ++squares;
                }
            }
        }
    }
    return squares;
    
    bool valid_square_at(x_0, y_0, x_1, y_1, width) 
    {
        return valid_line(x_0, y_0, x_0_ x_1, width)
            && valid_line(x_0, y_0, x_1_ x_0, width)
            && valid_line(x_0, y_1, x_1_ x_1, width)
            && valid_line(x_1, y_0, x_1_ x_1, width);
    }
    
    bool valid_line(x_0, y_0, x_1, y_1, width) 
    {
        //check that all pixel in that line are black...
    }
    

    基本上,对于图片中的每个点,您都会检查每个可能大小的正方形,如果该大小的正方形从该像素开始。这很容易,因为您的正方形都与边框“对齐”......问题是如果它们不是......

    【讨论】:

    • 您选择不使用图形表示有什么原因吗?一旦你有了一个代表,就可以做一些暴力之外的事情。
    • 图的表示是什么意思?无论如何,它是 O(n^4)... 没那么糟糕...
    • 我的意思是图形的表示,它以位图以外的任何方式对信息进行编码。
    • 如果你使用一个表示,你必须检查你的不同图形是如何“合并”的(你可能有 2 个三角形拦截蚂蚁他们创建一个正方形)。因此,您需要将所有内容解码为“线”或“点”(如果您允许曲线,则需要使用“点”)......并且您需要实现很多案例,或​​将其渲染为一个位图,看看所有的数字是如何合并在一起的......所以回到第一方:)
    • 可以在图形中找到循环,而无需渲染到位图或使用三角形之类的东西。
    猜你喜欢
    • 2014-08-11
    • 2013-03-19
    • 1970-01-01
    • 2015-12-05
    • 2019-09-29
    • 1970-01-01
    • 2021-10-14
    • 2012-08-23
    • 1970-01-01
    相关资源
    最近更新 更多