【问题标题】:runtime of an algorithm slows down heavily as it processes the data算法的运行时间在处理数据时会大大减慢
【发布时间】:2019-09-29 16:32:30
【问题描述】:

这个算法是我正在进行的一个更大项目的一部分,这个算法的作用是查找给定颜色的像素,然后返回它们的坐标。

def find_pixels(img):
    labels = np.zeros((len(img), len(img[0])))
    c = 0
    x0 = 0
    while True:
        print(c)
        pixel = find_pixel_v2(img, labels, x0)
        if pixel[0] == False:
            break
        else:
            i, j, labels, x0 = pixel[0][0], pixel[0][1], pixel[1], pixel[2]
        c += 1
        print((i,j)) 


def find_pixel_v2(img, labels, x0):
    for i in range(x0, len(img)):
        for j in range(0, len(img[0])):
            if labels[i][j] == 1:
                continue
            else:
                if img[i][j][0] != 0:
                    labels[i][j] = 1
                    return (i, j), labels, x0
                else:
                    labels[i][j] = 1
    return False, labels


输入 img 是一个形状 (x,y,3) 的数组。 标签是一个形状为 (x, y) 的零数组,以确保我不会遍历已经检查过的坐标。

问题是算法的运行时间随着时间的推移而严重减慢,我不知道为什么。

【问题讨论】:

  • 您在哪里指定要查找的颜色?
  • img[ i ][ j ][0] != 0,其中 img[ i ][ j ] 是像素的 RGB 代码。
  • 为什么在find_pixel_v2 中有时使用labels_ 有时使用labels?这是故意的吗?
  • 取决于labels 的大小,它可能会因为labels[i][j] = 1 而变慢。我最近在 DataFrames 上遇到了类似的问题。与其调整标签并一次又一次地保存它们,不如尝试使用append 将值保存在不断增长的列表中,然后将它们插入labels。例如pixels.append([i,j])
  • 为什么需要多次调用find_pixel_v2?难道你不能一次通过图像并收集一组左右的坐标吗?

标签: python arrays python-3.x numpy time-complexity


【解决方案1】:

很高兴看到您发现了自己的错误(诚然,这就是您的问题所在)。
但是 - 我并没有真正得到你算法的全部努力,如果我误解了任何东西,请纠正我。

但 IIUC IMO 的全部内容是获取图像的所有索引,其中像素的红色分量不为零,对吧?

所以我的方法是为搜索的像素制作一个 True 的掩码,为所有其他像素制作一个 False,然后向 np.argwhere 询问它们的索引:

mask = img[:, :, 0] != 0
indices = np.argwhere(mask)

也许你可以测试一下;希望这会有所帮助。

【讨论】:

  • 这个算法的重点是测试for循环的运行时间。原始算法应该得到一个不同于黑色的颜色的像素,然后捕捉它附近的所有像素,这是一种检测特定颜色簇的算法。在这篇文章之前我对面具一无所知,我是一个初学者,所以它肯定会有所帮助,感谢您指出!
  • 不客气。也许您考虑阅读 numpy 文档中关于 indexing 的一些段落。这是一个关于一些强大功能的有趣话题。由于图像是我知道的那些包中的 numpy 数组,它可能是你的基本工具集。
  • 我一定会这样做,因为正如您提到的那样,它确实是我的基本工具集,谢谢!
【解决方案2】:

我发现问题出在哪里:

运行时变慢的原因是因为每次调用 find_pixel_v2() 时,for 循环都会从一开始就迭代整个数组,直到它到达具有所需颜色的像素,随着时间的推移,这个过程将花费越来越长。

我想我可以使用一个变量 x0 来防止 for 循环在每次调用时重复一遍。

但是,我在这里犯了一个错误:return (i, j), labels, x0 我返回相同的 x0 值,每次都为零。

将此行更改为return (i, j), labels, i 即可解决,即下次调用find_pixel_v2() 时,for 循环将从上次调用结束处开始。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-29
    • 2015-03-13
    • 2017-07-23
    • 1970-01-01
    • 2015-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多