使用Python/NumPy矢量化图像阈值

Joe*_*e G 2 python arrays numpy image-processing vectorization

我一直在努力寻找一种更有效的方法来迭代图像并在阈值上拆分它们的属性.在网上搜索并与一些编程朋友讨论时,他们向我介绍了向量化(特别是使用numpy)函数的概念.经过大量的搜索和反复试验,我似乎无法掌握它.有人可以给我一个链接,或建议如何使以下代码更有效?

Im = plt.imread(img)
Imarray = np.array(Im)
for line in Imarray:
    for pixel in line:
        if pixel <= 20000:
            dim_sum += pixel
            dim_counter += 1
        if pixel > 20000:
            bright_sum += pixel
            bright_counter += 1
bright_mean = bright_sum/bright_counter
dim_mean = dim_sum/dim_counter
Run Code Online (Sandbox Code Playgroud)

基本上,每个像素保持0到30000之间的亮度,我试图分别平均低于20000和高于20000的所有像素.我知道如何做到这一点的最好方法是使用for循环(在python中很慢)并使用if语句搜索每个像素.

Div*_*kar 6

NumPy支持并鼓励通过它arrays和它进行矢量化ufuncs.在您的情况下,您将NumPy数组作为输入图像.因此,这些比较可以一次性/矢量化方式完成,以便为我们提供与输入数组相同形状的布尔数组.那些用于索引输入数组的布尔数组将从中选择有效元素.这被称为boolean-indexing并且在这种矢量化选择中形成关键特征.

最后,我们使用NumPy ufunc ndarray.mean再次以矢量化方式操作,以给出所选元素的平均值.

因此,要将所有这些放入代码中,我们将 -

bright_mean, dim_mean = Im[Im > 20000].mean(), Im[Im <= 20000].mean()
Run Code Online (Sandbox Code Playgroud)

对于这个特定问题,从代码效率的角度来看,执行一次比较会更有意义.比较会给我们一个布尔数组,可以在以后使用两次,一次使用,第二次反转.因此,或者我们会 -

mask = Im > 20000
bright_mean, dim_mean = Im[mask].mean(), Im[~mask].mean()
Run Code Online (Sandbox Code Playgroud)