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)