I'm very new to using OpenCV and wanted to know if there was a way of returning the values for the number of pixels in an image. For example returning the amount of Red, Blue, Green, etc, in a picture and then stating the most common colour (the colour with the highest number of pixels). Like I said I'm very new to using OpenCV and so have no idea on how to start writing it. If this is already possible in the OpenCV library can someone just tell me the function to call upon. Because I am going to use this with a camera to gather the image you can use any image that you want.
1 Answers
I'll try answering your question specifically but it's important to know that OpenCV relies a lot on NumPy arrays architecture. Please ask if something isn't clear in the following code concerning how we can manipulate images and pixel values using NumPy arrays.
So let's say that you read a picture using OpenCV:
import cv2
import numpy as np
# reading the picture in coloured mode
image = cv2.imread("path/to/picture.jpg", cv2.IMREAD_COLOR)
Now, please note that OpenCV uses BGR format and not RGB, which means that each pixel in your image will be represented by a NumPy array with three values, each of which represents the pixel intensity value in blue, green and red order.
So, if you want to know which colour appears the most in that picture in a BGR (red, blue and green) format, you can do:
# first, count all occurrences of unique colours in your picture
unique, counts = np.unique(image.reshape(-1, image.shape[2]), axis=0, return_counts=True)
# then, return the colour that appears the most
print(max(zip(unique, counts), key=lambda x: x[1]))
If what you want to do is knowing whether there is more blue, green or red in your picture (which makes less sense to be honest), what you can do is the following:
# count the raw pixel values for red, blue and green over all pixels in the image
counts = np.sum(image.reshape(-1, image.shape[2]), axis=0)
# remember that OpenCV uses BGR format and not RGB
BGR = ["blue", "green", "red"]
# then, for instance, return the amount of blue, green and red in a percentage format:
for colour, count in zip(BGR, counts):
print(colour+":", "{0:.2%}".format(count/np.sum(counts)))
Again, please ask if anything is unclear!

- 2,018
- 8
- 21
-
What does the program return with the line 'print(max(zip(unique, counts), key=lambda x: x[1]))' – A_Person_ Nov 21 '19 at 09:58
-
So basically ```zip(unique, counts)``` yields a list of sublists containing each unique colour in the picture and the associated frequency of that colour in the picture (something like ```[(colour, count), (colour, count), ..., (colour, count)]```). Then, when you do ```max(zip(unique, counts), key=lambda x: x[1])```, you return the maximum of that list where the maximum is defined by the ```key``` argument as the maximum of the second coordinate of each sublist, that is the frequency of colours in the picture. So, in the end, it yields the one colour with the maximum frequency in the picture. – bglbrt Nov 21 '19 at 10:16
-
With the most common colour now recognised, could I also show only instances of that colour on the image. – A_Person_ Nov 26 '19 at 12:22
-
I'm not sure I understand what it means. Do you mean displaying the image with all pixels that are not this colour blanked out? – bglbrt Nov 26 '19 at 14:15
-