Reputation: 73
I want to calculate the green colour percentage in an image
I have calculated by iterating through each pixel in an image and check the color of each pixel. Finally, I keep the count of the number of green pixels and find the total percentage in whole image.
def green_color_optimized(screenpath):
start_time = time.time()
img = image.load_img(screenpath,target_size=(300,300,3))
x = image.img_to_array(img)
print("Image size: ", x.shape)
count_green = 0
for i in range(0,x.shape[0]):
for j in range(0,x.shape[1]):
pixel = list(map(int, x[i,j].tolist()))
if sum(pixel) != 0:
green_pixel = 100*(pixel[1]/sum(pixel))
blue_pixel = 100*(pixel[2]/sum(pixel))
red_pixel = 100*(pixel[0]/sum(pixel))
if green_pixel > red_pixel and green_pixel > blue_pixel:
if green_pixel > 35:
count_green += 1
green_percent = round(100*(count_green/(x.shape[0]*x.shape[1])),2)
With this code, each image takes around 200ms to process; and I want to process 1 million images. How can I optimise the code?
Upvotes: 1
Views: 694
Reputation: 141
Presuming that x is a numpy array, you should always vectorize your matrix operations. The following runs ~200 times faster:
# Your original function, with the file i/o removed for timing comparison
def green_original(x):
count_green = 0
for i in range(0,x.shape[0]):
for j in range(0,x.shape[1]):
pixel = list(map(int, x[i,j].tolist()))
if sum(pixel) != 0:
green_pixel = 100*(pixel[1]/sum(pixel))
blue_pixel = 100*(pixel[2]/sum(pixel))
red_pixel = 100*(pixel[0]/sum(pixel))
if green_pixel > red_pixel and green_pixel > blue_pixel:
if green_pixel > 35:
count_green += 1
green_percent = round(100*(count_green/(x.shape[0]*x.shape[1])),2)
return green_percent
def green_vectorized(x):
mask = (img[:,:,1] > img[:,:,0]) & (img[:,:,1] > img[:,:,2]) & ((img[:,:,1]/np.sum(img, axis=2)) > .35)
round(100 * np.sum(mask)/(x.shape[0]*x.shape[1]), 2)
img = np.ones(shape=(300,300,3))
img[0:150,0:150, 1] = 134
%timeit green_original(img)
%timeit green_vectorized(img)
81.7 ms ± 6.24 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
461 µs ± 78.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Upvotes: 2