python - 让我们为python的numpy做一个N维像素分箱/分桶的引用实现

标签 python arrays image numpy image-processing

我经常想要pixel bin/pixel bucket一个 numpy 数组,意思是,用单个像素替换 N 连续像素组,该像素是 N 替换像素的总和。例如,从值开始:

x = np.array([1, 3, 7, 3, 2, 9])

如果桶大小为 2,则转换为:

bucket(x, bucket_size=2) 
= [1+3, 7+3, 2+9]
= [4, 10, 11]

据我所知,没有专门执行此操作的 numpy 函数(如果我错了请纠正我!),所以我经常自己动手。对于一维 numpy 数组,这还不错:

import numpy as np

def bucket(x, bucket_size):
    return x.reshape(x.size // bucket_size, bucket_size).sum(axis=1)

bucket_me = np.array([3, 4, 5, 5, 1, 3, 2, 3])
print(bucket(bucket_me, bucket_size=2)) #[ 7 10  4  5]

...但是,我很容易对多维情况感到困惑,最终我一遍又一遍地用自己的错误、半途而废的解决方案来解决这个“简单”的问题。如果我们能建立一个很好的 N 维引用实现,我会很高兴。

  • 函数调用最好允许沿不同轴使用不同的 bin 大小(可能类似于 bucket(x, bucket_size=(2, 2, 3)))

    <
  • 最好的解决方案是相当有效的(reshape 和 sum 在 numpy 中相当快)

  • 当数组不能很好地划分为整数个桶时处理边缘效应的加分项。

  • 允许用户选择初始 bin 边缘偏移量的奖励积分。

根据 Divakar 的建议,这是我在示例二维案例中的期望行为:

x = np.array([[1, 2, 3, 4],
              [2, 3, 7, 9],
              [8, 9, 1, 0],
              [0, 0, 3, 4]])

bucket(x, bucket_size=(2, 2))
= [[1 + 2 + 2 + 3, 3 + 4 + 7 + 9],
   [8 + 9 + 0 + 0, 1 + 0 + 3 + 4]]
= [[8, 23],
   [17, 8]]

...希望我的算术正确;)

最佳答案

我认为您可以使用 skimage 的 view_as_blocks 完成大部分繁琐的工作.这个函数是implemented using as_strided所以它非常有效(它只是改变步幅信息来 reshape 数组)。因为它是用 Python/NumPy 编写的,所以如果您没有安装 skimage,您可以随时复制代码。

应用该函数后,您只需对 reshape 数组的 N 个尾轴求和(其中 N 是 bucket_size 元组的长度)。这是一个新的 bucket() 函数:

from skimage.util import view_as_blocks

def bucket(x, bucket_size):
    blocks = view_as_blocks(x, bucket_size)
    tup = tuple(range(-len(bucket_size), 0))
    return blocks.sum(axis=tup)

然后举例:

>>> x = np.array([1, 3, 7, 3, 2, 9])
>>> bucket(x, bucket_size=(2,))
array([ 4, 10, 11])

>>> x = np.array([[1, 2, 3, 4],
                  [2, 3, 7, 9],
                  [8, 9, 1, 0],
                  [0, 0, 3, 4]])

>>> bucket(x, bucket_size=(2, 2))
array([[ 8, 23],
       [17,  8]])

>>> y = np.arange(6*6*6).reshape(6,6,6)
>>> bucket(y, bucket_size=(2, 2, 3))
array([[[ 264,  300],
        [ 408,  444],
        [ 552,  588]],

       [[1128, 1164],
        [1272, 1308],
        [1416, 1452]],

       [[1992, 2028],
        [2136, 2172],
        [2280, 2316]]])

关于python - 让我们为python的numpy做一个N维像素分箱/分桶的引用实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36269508/

相关文章:

javascript - 将 mongodb 中的图像保存为 blob,React

image - 为什么 magento 中的 wysiwyg 插件让我断开链接?

python - 使类可转换为 ndarray

python - Bamboo 日志输出顺序问题

python - python 需要的 GLIBC_2.15

python - Django - 基于函数的 View 的自定义权限

javascript - Chrome DevTools - 数组长度不一致

html - 图片未出现在现场;可以直接通过url访问

c++ - 如何在 C++ 中按列对多维数组进行排序?

php - 将 .csv 读入 PHP 数组