【问题标题】:Slicing ndarray using floats in Python在 Python 中使用浮点数对 ndarray 进行切片
【发布时间】:2017-03-28 12:21:14
【问题描述】:

我想在 Python 中构造一个算法,将图像切成 n×n 相等的块。我知道现有的 Python 包可以做到这一点,但我有兴趣使用生成的块的维度执行数学计算,这些维度不必是整数值。

我已使用numpycv2 成功地将我的图像输入转换为ndarray。我很好奇我是否可以以某种方式对ndarray 对象进行切片,这样当我拆分一个“像素”时,我只需将该“像素”对它们各自块的贡献取加权平均值。

例如,如果图像输入的尺寸为 100px x 100px,并且我想将此图像拆分为 7x7 块,因为 100/7 = ~14.2857,每个块的尺寸将为 14.2857 x 14.2857。但是只有一小部分像素是没有意义的。相反,我希望对此进行解释,以便第一个块包含来自像素 (1,1),(1,2),...,(1,14),(2,1),... 的所有信息,(3,1),...,(14,1),... ,(14,14), 满足 (15,k) 和 (k,15) 的所有像素中的 0.2857,像素为 0.2857*0.2857 (15,15)。我希望对所有 49 个区块都这样做。

任何见解将不胜感激!谢谢。

【问题讨论】:

    标签: python algorithm numpy image-processing slice


    【解决方案1】:

    正如您正确观察到的,图像中不能有 14.29 像素。但是,您可以执行 下采样 到 14(或更少)像素或 上采样 到 15(或更多)像素。我认为前者是你想要的,但后者也是一个可行的选择。

    一种简单的方法是将图像调整为可以轻松拆分为 7x7 的新尺寸。如果您使用正确的函数来执行此操作(例如scipy.ndimage.interpolation.zoom),它将自动插入像素值。

    为简单起见,假设您要将 5x5 图像拆分为 2x2 块:

    from scipy.ndimage.interpolation import zoom
    import numpy as np
    
    blocks = (2, 2)
    
    image = np.arange(25).reshape(5, 5) * 10
    print(image)
    # [[  0  10  20  30  40]
    #  [ 50  60  70  80  90]
    #  [100 110 120 130 140]
    #  [150 160 170 180 190]
    #  [200 210 220 230 240]]
    
    # use np.ceil instead of np.floor to do upsampling
    zoom_factor = [np.floor(s / b) * b / s for s, b in zip(image.shape, blocks)]
    
    zoomed = zoom(image, zoom_factor)
    print(zoomed)
    # [[  0  14  26  40]
    #  [ 69  83  95 109]
    #  [131 145 157 171]
    #  [200 214 226 240]]
    
    for b1 in range(0, zoomed.shape[0], blocks[0]):
        for b2 in range(0, zoomed.shape[1], blocks[1]):
            print('block:')
            print(zoomed[b1:b1+blocks[0], :][:, b2:b2+blocks[1]])
    # block:
    # [[ 0 14]
    #  [69 83]]
    # block:
    # [[ 26  40]
    #  [ 95 109]]
    # block:
    # [[131 145]
    #  [200 214]]
    # block:
    # [[157 171]
    #  [226 240]]
    

    请注意,在缩放后的图像中,第一行中的第二个像素的值为 14,其中包含来自邻居 10 和 20 的贡献。(它可能也包含来自其他像素的贡献,因为缩放默认使用 3 阶样条曲线用于插值)。图像中间的其他像素包含来自整个周围邻域的贡献。

    【讨论】:

    • 感谢您的意见。我喜欢这个建议。我将使用这种方法遇到的唯一问题是比较两个不同尺寸的图像,这是我项目的总体目标。如果我有两张不同尺寸的图像并想比较两者怎么办?我应该缩小较大的图像以匹配较小图像的尺寸,然后实施这种方法吗?感谢您的帮助!
    • @wilson 一般来说,是的,这就是我会做的。如果我使用许多不同尺寸的图像,我通常会选择一个“工作尺寸”并将所有图像调整为这个尺寸。对较小的图像进行上采样,对较大的图像进行下采样。是放大较小的图片还是缩小较大的图片取决于您的应用和偏好。
    • 非常感谢您的回复。幸运的是,我正在处理非常大的图像,因此缩小这些图像以补偿各种分区大小并保持图像质量不会丢失太多像素信息。还有一个问题:如何在重新调整尺寸的同时保留图像的纵横比?
    • @wilson 保持纵横比对每个维度使用相同的缩放系数。
    猜你喜欢
    • 2015-01-17
    • 2010-09-20
    • 2020-06-15
    • 1970-01-01
    • 2017-05-31
    • 2016-07-29
    • 1970-01-01
    • 2013-09-13
    • 2020-08-27
    相关资源
    最近更新 更多