I am trying to determine if certain parts of an RGB image are colored or grayscale, using python, opencv and numpy libraries. To be more spesific, in an RGB image I determine face locations using neural networks and when that image contains printed photos I would like to find out if the face location in that image is grayscale or colored.
What I tried so far:
red_average = np.average(rgb_image_crop[:,:,0])
green_average = np.average(rgb_image_crop[:,:,1])
blue_average = np.average(rgb_image_crop[:,:,2])
highest_distance = max(abs(red_average-green_average), abs(red_average-blue_average), abs(green_average-blue_average))
if highest_distance> 15:
print("this crop is colored")
else:
print("this crop is grayscale")
After finding the location of faces, faces are cropped and named "rgb_image_crop". I basically split the R, G, B channels using numpy and took their averages separately. My logic was that grayscale images would have R, G, B pixel values close to each other compared to colored images and this method worked with average performance.
But I was wondering is there a more sophisticated approach than this with higher success hopefully? I looked through other questions, but everyone was just asking to determine if an image file is B/W or RGB.
Edit after concluding the results: I have tried various methods in computer vision and then tried training CNN classifier using a dataset I created. Apparently CNN networks cannot learn colors much but mostly they learn textures and results were really disappointing. I trained a Darknet YOLOV4 based classifier and tests with real life examples failed to give satisfactory outcomes. Mark's suggestion has been the most stable one and after that the one I mentioned in my question. I will try to implement Mark's solution using hardware acceleration and make it use less CPU resources.
