Why would cv2.COLOR_RGB2GRAY and cv2.COLOR_BGR2GRAY give different results?

  1. RGB->gray conversion actually isn’t an average — different channels are weighed differently. Specifically:
gray_pixel = 0.114 * blue_pixel + 0.299 * red_pixel + 0.587 * green_pixel

This is also mentioned in the documentation. Thus, it’s expected that RGB2GRAY and BGR2GRAY give different results.

  1. Regarding the discrepancy between sum-then-divide and divide-then-sum approaches, i.e. between
img_read_as_color[:,:,0]/3+img_read_as_color[:,:,1]/3+img_read_as_color[:,:,2]/3

and

(img_read_as_color[:,:,0]+img_read_as_color[:,:,1]+img_read_as_color[:,:,2])/3

Recall that cv2.imread returns a uint8 numpy array. Thus, the latter operation (where all channels are combined together prior to division) results in an overflow (in fact, ipython3 gives me a runtime warning in this case). Overflow-like artifacts are also visible in images labeled channel_avg_div_together and channel_sum.

Leave a Comment