I’m trying to implement some image processing (finding regions of similar colour) in Python with PIL and Numpy. Can’t figure out how to speed up this code. Could you help?
def findRegions(self, data):
#data is numpy.array
ret = [[False for _ in range(self.width)] for _ in range(self.heigth)]
for i in range(self.heigth):
for j in range(self.width):
k = 0
acc = 0
for x,y in [(-1,0),(0,-1),(0,1),(1,0)]:
if (self.heigth>i+x>=0 and self.width>j+y>=0):
k = k+1
acc += math.sqrt(sum((data[i][j][c]-data[i+x][j+y][c])**2 for c in range(3)))
if (acc/k<self.threshold):
ret[i][j]= True
return ret
PIL and other image libraries have got many filtering and processing functions which are really quick. But what is the best way to implement own image processing functions?
Rather than looping over each row and column you can shift the array left, right, up, and down for the appropriate number of elements. On each shift you accumulate your values in a base array. After the shifting and accumulating you compute your average and apply your threshold to return a mask. See this post which has a general discussion on the topic. The idea is take advantage of numpy’s broadcasting, which will apply a function or operator to all elements of an array in C rather than Python.
I’ve adapted the code from the linked post to fit what I believe you are trying to accomplish. In any case the general pattern should speed things up. You have to work out what to do with the edges in the return mask. Here I’ve simply set the return mask to False, but you could also eliminate the edges by expanding the input data by one pixel in each direction and filling with the nearest pixel, zeros, gray, etc.