【问题标题】:scikit-image pixel by pixel manipulationscikit-image 逐像素操作
【发布时间】:2017-03-31 23:39:28
【问题描述】:

我需要读取一个图像,然后对每个像素执行一个函数,然后将其保存为新图像。我将 scikit-image 用于第一部分和最后一部分(读取和写入),但我无法快速执行第二个操作(实际转换)。

scikit-image 中读取操作的结果是一个形状为 (WIDTH, HEIGHT, N_CHANNELS) 的 numpy 数组,其中 WIDTH 和 HEIGHT 是图像的,N_CHANNELS 是 3 或 4。我需要应用这样的函数将像素从 [R, G, B] 转换为 [R - B, G - B, B - R] 的像素分别转换为每个像素。

我花了几天时间试图让它工作,但到目前为止我唯一可行的解​​决方案是遍历每一行和每一列并执行计算。这需要很长时间才能完成。

我尝试对数组进行矢量化,但结果是一维数组,无法使用它。有没有其他高效的方法来完成这项工作?

def calculate_ndvi(nir, red):
    if red == 0 and nir == 0:
        return 0.5
    else:
        num = int(nir) - int(red)
        den = int(nir) + int(red)
        return num / den


zero_uint = numpy.uint8(0)


def process_color(clr):
    ndvi = calculate_ndvi(clr[2], clr[0])
    return [-ndvi, ndvi, zero_uint]


def save_ndvi_file():
    image = io.imread(input_path)

    rows = image.shape[0]
    cols = image.shape[1]

    out = numpy.empty(shape=(rows, cols, 3))
    for i in range(rows):
        for j in range(cols):
            out[i][j] = process_color(image[i][j])

    io.imsave('output.jpg', out)

【问题讨论】:

  • 没有看到你的代码,我们能做的最好的就是猜测。请准备一个minimal reproducible example。将该函数应用于 25MP 文件应该不会花费很长时间,因此您可能做错了什么。

标签: python numpy scikit-image


【解决方案1】:

您可以通过使用多维广播操作来将其向量化。这是您的函数的一个版本,它以矢量化方式执行所有操作:

def save_ndvi_file():
    image = io.imread(input_path)

    nir = image[:, :, 2]
    red = image[:, :, 0]
    ndvi = (nir - red) / (nir + red)
    ndvi[(nir == 0) & (red == 0)] = 0.5
    out = ndvi[:, :, np.newaxis] * np.array([[[-1, 1, 0]]])

    io.imsave('output.jpg', out)

请注意,您循环的所有事情现在都通过广播的 numpy 操作完成,而不是通过循环外部函数调用。以这种方式编写代码需要对算法的思考方式略有不同,但一旦习惯了它就会非常直观。

【讨论】:

    猜你喜欢
    • 2021-04-12
    • 2015-08-08
    • 2019-12-12
    • 2021-06-06
    • 2011-12-08
    • 2021-02-10
    • 2017-05-25
    • 1970-01-01
    相关资源
    最近更新 更多