【问题标题】:About the numpy.where statement关于 numpy.where 语句
【发布时间】:2021-11-20 12:28:37
【问题描述】:

我想使用 numpy.where 来检查前一行的值,但不知道如何编码

对于范围内的 n1(len(image1)):

print('input image ',input_folder+'\\' + image1[n1])
print('\n')
print('image1[n1] ',image1[n1])
print('\n')

im = Image.open(input_folder+'\\'+image1[n1])

a = np.array(im, dtype='uint8')

width, height = im.size

print('width ',width)
print('height ',height)


a = np.where(a==[0,0,0],[255,255,255],a)

!-- 将循环语句改为 np.where --!

  for h in range(height):
    for w in range(width):
      
      if h <= (height - 2) and w <= (width - 2):
           
         if a[h,w,0] != 255 and a[h,w,1] != 255 and a[h,w,2] != 255:
             if (a[h-1,w,0] == 255 and a[h-1,w,1] == 255 and a[h-1,w,2] == 255 and a[h+1,w,0] == 255 and a[h+1,w,1] == 255 and a[h+1,w,2] == 255) or (a[h,w-1,0] == 255 and a[h,w-1,1] == 255 and a[h,w-1,2] == 255 and a[h,w+1,0] == 255 and a[h,w+1,1] == 255 and a[h,w+1,2] == 255):***

             Change the above looping statement to np.where(a[-??] = [255,255,255] or a[+??] = [255,255,255]) so it can run more faster than the for loop statement.  -->


                a[h,w,0] = 255
                a[h,w,1] = 255
                a[h,w,2] = 255

【问题讨论】:

    标签: numpy where-clause


    【解决方案1】:

    恐怕你不能在这里使用np.where

    原因是:

    • 传递给 np.where 的条件应指示 源数组,
    • 而您代码中的标准实际上只与前 2 个相关 源数组的维度。

    所以我想出了另一个非常优雅简洁的解决方案。

    第 1 部分:如何获取元素的前两个索引,其中所有元素 在第三个维度是 != 255:

    对于它,在整个数组上,你可以运行:

    np.not_equal(a, 255).all(axis=2)
    

    第 2 部分:如何将“操作范围”限制为具有两者的元素 上一行和下一行和下一列。

    您可以将原始数组的“子范围”传递给上述代码:

    np.not_equal(a[1:-1, 1:-1], 255).all(axis=2))
    

    您应该删除 both 第一和最后一列和行(在 您的代码未能消除第一行/第一列)。

    但请注意,这次生成的索引比以前少了一个, 所以在后面的步骤中,您必须将 1 添加到它们。

    第 3 部分:检查所有元素是否沿第三维的函数 == 255,对于某些行 (r) 和列 (c):

    def all_eq(arr, r, c):
        return np.equal(arr[r, c], 255).all()
    

    (即将使用)。

    第 4 部分:如何获得结果:

    res = a.copy()
    for r, c in zip(*np.where(np.not_equal(a[1:-1, 1:-1], 255).all(axis=2))):
        h = r + 1
        w = c + 1
        if all_eq(a, h-1, w) and all_eq(a, h+1, w) or\
                all_eq(a, h, w-1) and all_eq(a, h, w+1):
            res[h, w] = 255
    

    请注意,此代码从制作原始数组的副本开始 (它将保存结果)。

    然后,for r, c in zip(…) 遍历找到的索引。

    循环中的前 2 行将 1 添加到 子范围 中找到的索引中 的原始数组,所以现在 hw 表示 whole 中的行/列 原始数组。

    然后if检查各个相邻像素是否在所有元素中都有255

    如果有,则将 255 放入“当前”像素的所有元素中,在结果中。

    您不能对原始数组进行操作,因为某些像素的值发生了变化 会“伪造”对后续像素条件的评估。

    编辑

    经过一番研究我发现,可以使用np.where, 虽然解决方案有点复杂并且涉及相当大的 Numpy 方法的数量:

    # Mask 1: Pixels with all elements != 255
    m1 = np.zeros((height, width), dtype='int8')
    idx = np.where(np.not_equal(a, 255).all(axis=2))
    m1[idx] = 1
    # Pixels with all elements == 255
    m2 = np.apply_along_axis(lambda px: np.equal(px, 255).all(), 2, a).astype('int8')
    # Both adjacent pixels (left / right) == 255
    m2a = np.logical_and(np.insert(m2, 0, 0, axis=1)[:,:-1], np.insert(m2,
        width, 0, axis=1)[:,1:])
    # Both adjacent pixels (up / down) == 255
    m2b = np.logical_and(np.insert(m2, 0, 0, axis=0)[:-1,:], np.insert(m2,
        height, 0, axis=0)[1:,:])
    # Mask 2: Both adjacent pixels (either vertically or horizontally) == 255
    m2 = np.logical_or(m2a, m2b)
    # The "final" mask
    msk = np.logical_and(m1, m2)
    # Generate the result
    result = np.where(np.expand_dims(msk, 2), 255, a)
    

    这个解决方案应该比我的第一个概念快得多。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-15
      • 2015-06-02
      • 1970-01-01
      • 2010-12-09
      相关资源
      最近更新 更多