【问题标题】:Better image normalization with numpy使用 numpy 进行更好的图像归一化
【发布时间】:2015-06-18 03:49:15
【问题描述】:

我已经实现了标题中描述的目标,但我想知道是否有更有效(或通常更好)的方法来做到这一点。首先让我介绍一下问题。

我有一组不同尺寸的图像,但 宽/高比小于(或等于)2(可以是任何东西,但现在假设为 2),我想对每个图像进行标准化一,意思是我希望它们都具有相同的大小。具体来说,我将这样做:

  • 提取所有图片上方的最大高度
  • 缩放图像,使每张图像都达到最大高度并保持其比例
  • 在右侧添加一个仅使用白色像素的填充,直到图像的宽/高比为 2

请记住,图像表示为灰度值 [0,255] 的 numpy 矩阵。

这就是我现在在 Python 中的做法:

max_height = numpy.max([len(obs) for obs in data if len(obs[0])/len(obs) <= 2])

for obs in data:
    if len(obs[0])/len(obs) <= 2:
        new_img = ndimage.zoom(obs, round(max_height/len(obs), 2), order=3)
        missing_cols = max_height * 2 - len(new_img[0])
        norm_img = []
        for row in new_img:
            norm_img.append(np.pad(row, (0, missing_cols), mode='constant', constant_values=255))
        norm_img = np.resize(norm_img, (max_height, max_height*2))            

关于这段代码有一个注释:

  • 我正在四舍五入缩放比例,因为它使最终高度等于 max_height,我确信这不是最好的方法,但它正在工作(任何建议都在这里表示赞赏)。我想做的是扩大图像,保持比例,直到它达到等于 max_height 的高度。这是迄今为止我找到的唯一解决方案,它立即生效,插值效果非常好。

所以我最后的问题是:

有没有更好的方法来实现上面解释的(图像标准化)?你认为我可以用不同的方式做这件事吗?有没有我没有遵循的常见良好做法?

提前感谢您的宝贵时间。

【问题讨论】:

  • 对于CodeReview来说可能是一个更好的问题?
  • 是的,也许你是对的,我以前从未使用过 CodeReview,我会稍等一下,然后可能会将问题移到那里。
  • 我认为您必须指定您的应用程序才能使您的问题更清楚。例如,如果您将图像用于某些机器学习应用程序,那么您可能希望避免插值(缩放)。你希望你的代码在做什么而不是现在?

标签: python image numpy


【解决方案1】:
  • 你可以使用 ndimage.zoom 而不是 scipy.misc.imresize。这个 函数允许您将目标大小指定为元组,而不是通过缩放 因素。因此,您不必稍后再调用np.resize 来获得与 想要的。

    注意scipy.misc.imresize 调用 PIL.Image.resize 在引擎盖下,所以 PIL(或 Pillow)是一个依赖项。

  • 您可以先为所需的数组norm_arr分配空间,而不是在for-loop中使用np.pad

    norm_arr = np.full((max_height, max_width), fill_value=255)
    

    然后将调整大小的图像,new_arr 复制到norm_arr

    nh, nw = new_arr.shape
    norm_arr[:nh, :nw] = new_arr
    

例如,

from __future__ import division
import numpy as np
from scipy import misc

data = [np.linspace(255, 0, i*10).reshape(i,10)
        for i in range(5, 100, 11)]

max_height = np.max([len(obs) for obs in data if len(obs[0])/len(obs) <= 2])
max_width = 2*max_height
result = []
for obs in data:
    norm_arr = obs
    h, w = obs.shape
    if float(w)/h <= 2:
        scale_factor = max_height/float(h)
        target_size = (max_height, int(round(w*scale_factor)))
        new_arr = misc.imresize(obs, target_size, interp='bicubic')
        norm_arr = np.full((max_height, max_width), fill_value=255)
        # check the shapes
        # print(obs.shape, new_arr.shape, norm_arr.shape)
        nh, nw = new_arr.shape
        norm_arr[:nh, :nw] = new_arr
    result.append(norm_arr)
    # visually check the result
    # misc.toimage(norm_arr).show()

【讨论】:

  • 非常感谢,这很有启发性。我会尽快尝试的。
猜你喜欢
  • 2019-11-24
  • 1970-01-01
  • 1970-01-01
  • 2019-06-28
  • 1970-01-01
  • 2017-09-11
  • 1970-01-01
  • 1970-01-01
  • 2017-07-04
相关资源
最近更新 更多