Problem statement: Assume a high resolution (> 3000 x 3000) image is given as input. The image pixels can be classified into one of the three categories namely text, background and drawing. There is library function which takes a pixel and returns its category. Write a function which takes high resolution image as input and return another image of same resolution where all text pixels are red, background pixels are green and drawing pixels are blue.
Approach: I have currently coded a brute force solution, where I iterate over each pixel in two nested for loops and invoke library method to know its category and accordingly set the colour of the pixel. Functionality wise it runs fine but it is hell slow.
Review ask: How to improve performance? How can I use vectorize this operation? I am currently using opencv but can improve any other library to get performance gain.
def generate_image_label(input_image_path, output_image_path):
try:
print("Processing image " + input_image_path)
image = cv2.imread(input_image_path, cv2.IMREAD_UNCHANGED)
image_width, image_height, image_channels = image.shape
c_b, c_g, c_r, c_a = cv2.split(image)
for i in range(image_width):
for j in range(image_height):
drawing_pixel = is_drawing_pixel(image, j, i) # is_drawing_pixel comes from some other module
text_pixel = is_text_pixel(image, j, i) # is_text_pixel comes from some other module
if c_a[i][j] != 0 and drawing_pixel:
c_b[i][j] = 255
c_g[i][j] = 0
c_r[i][j] = 0
c_a[i][j] = 255
elif c_a[i][j] != 0 and text_pixel:
c_b[i][j] = 0
c_g[i][j] = 0
c_r[i][j] = 255
c_a[i][j] = 255
else:
c_b[i][j] = 0
c_g[i][j] = 255
c_r[i][j] = 0
c_a[i][j] = 255
img_label = cv2.merge((c_b, c_g, c_r, c_a))
cv2.imwrite(os.path.join(output_image_path, os.path.basename(input_image_path)), img_label)
return (True, input_image_path)
except:
return (False, input_image_path)