2017-03-31 50 views
0

我需要读取图像,然后对每个像素执行一项功能,然后将其另存为新图像。我使用scikit-image作为第一部分和最后一部分(阅读和写作),但在快速执行第二个操作(实际转换)时遇到问题。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) 
+0

没有看到你的代码,我们能做的最好的就是猜测。请准备[mcve]。在25MP文件上应用该功能不应该花很长时间,所以你可能做错了什么。 –

回答

2

您可以通过使用多维操作广播来对此进行矢量化。这里是你的函数的一个版本,做一个量化的方式一切:

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的操作现在完成了,而不是通过遍历外部函数调用。以这种方式编写代码需要对算法进行稍微不同的思考方式,但一旦习惯了它,它就非常直观。