How to understand the max() function in OpenCV-Python
Question:
Today I learned a new API but ran into trouble. What’s the return value of .max()
?
I hadn’t seen this function until today. Can anyone tell me something?
import cv2
img = cv2.imread('../src/lena.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
print(img.max())
print(gray.max())
The outputs are 255 and 245.
Why the value changes to 245 when it turn into a gray photo?
img and gray:
Answers:
Here’s an example with code. Suppose we use this very basic image. It is a 3 x 3
BGR
matrix. The first element (pixel), from top left to bottom right, is pure green, so its value in BGR
format is: [0, 255, 0]
. The fifth element is a kind of dark red, but not pure. Its BGR
value is [0, 0, 200]
. The last element is a very dark blue, with value [150, 0, 0]
. So we have nice colors in the diagonal while all remaining pixels are black, with a value of [0, 0, 0]
. You can see it in this (enlarged for displaying purposes) image:
Let’s read it and print its maximum value:
# imports:
import numpy as np
import cv2
# image path
path = "D://opencvImages//"
fileName = "testMat2.png"
# Reading an image in default mode:
inputImage = cv2.imread(path + fileName)
# Get max value and print it:
maxValue = inputImage.max()
print("Max BGR value is: "+str(maxValue))
# Display the image:
cv2.imshow("inputImage [BGR]", inputImage)
cv.waitKey(0)
This prints the following value:
Max BGR value is: 255
As you see, we have only one maximum value: 255
, which is the value of the pure green pixel. The value is actually the largest in the entire matrix – all dimensions included: width, height and channels.
Let’s convert the image to grayscale
. As I mentioned on my comment, the grayscale
version of a BGR
image is obtained by applying a weighted average of the three channels. The weights can very depending on which version of grayscale
transformation you are applying (there’s more than one). In the case of OpenCV this is the formula used. From here it is clear that every pixel value will change, let’s print the changes:
# Convert BGR to grayscale:
grayImg = cv2.cvtColor(inputImage, cv2.COLOR_BGR2GRAY)
# Get max value and print it:
maxValue = grayImg.max()
print("Max Gray value is: "+str(maxValue))
# Display the image:
cv2.imshow("inputImage [grayImg]", grayImg)
cv.waitKey(0)
This snippet prints the following:
Max Gray value is: 150
If you display the grayscale image, you would see something like this:
The 150
pixel also corresponds to the pure green pixel. Its value has been modified by the conversion formula but, as was the case in the original image, it is still the largest pixel on the image. Additionally, the dark red has now a value of 60
and the very dark blue a value of 17
. As a nice bit of info: In the weighted average formula, the weights of the colors are not the same. Green has the largest weight because the human eye perceives it easily than the rest of the RGB
additive primary colors.
Today I learned a new API but ran into trouble. What’s the return value of .max()
?
I hadn’t seen this function until today. Can anyone tell me something?
import cv2
img = cv2.imread('../src/lena.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
print(img.max())
print(gray.max())
The outputs are 255 and 245.
Why the value changes to 245 when it turn into a gray photo?
img and gray:
Here’s an example with code. Suppose we use this very basic image. It is a 3 x 3
BGR
matrix. The first element (pixel), from top left to bottom right, is pure green, so its value in BGR
format is: [0, 255, 0]
. The fifth element is a kind of dark red, but not pure. Its BGR
value is [0, 0, 200]
. The last element is a very dark blue, with value [150, 0, 0]
. So we have nice colors in the diagonal while all remaining pixels are black, with a value of [0, 0, 0]
. You can see it in this (enlarged for displaying purposes) image:
Let’s read it and print its maximum value:
# imports:
import numpy as np
import cv2
# image path
path = "D://opencvImages//"
fileName = "testMat2.png"
# Reading an image in default mode:
inputImage = cv2.imread(path + fileName)
# Get max value and print it:
maxValue = inputImage.max()
print("Max BGR value is: "+str(maxValue))
# Display the image:
cv2.imshow("inputImage [BGR]", inputImage)
cv.waitKey(0)
This prints the following value:
Max BGR value is: 255
As you see, we have only one maximum value: 255
, which is the value of the pure green pixel. The value is actually the largest in the entire matrix – all dimensions included: width, height and channels.
Let’s convert the image to grayscale
. As I mentioned on my comment, the grayscale
version of a BGR
image is obtained by applying a weighted average of the three channels. The weights can very depending on which version of grayscale
transformation you are applying (there’s more than one). In the case of OpenCV this is the formula used. From here it is clear that every pixel value will change, let’s print the changes:
# Convert BGR to grayscale:
grayImg = cv2.cvtColor(inputImage, cv2.COLOR_BGR2GRAY)
# Get max value and print it:
maxValue = grayImg.max()
print("Max Gray value is: "+str(maxValue))
# Display the image:
cv2.imshow("inputImage [grayImg]", grayImg)
cv.waitKey(0)
This snippet prints the following:
Max Gray value is: 150
If you display the grayscale image, you would see something like this:
The 150
pixel also corresponds to the pure green pixel. Its value has been modified by the conversion formula but, as was the case in the original image, it is still the largest pixel on the image. Additionally, the dark red has now a value of 60
and the very dark blue a value of 17
. As a nice bit of info: In the weighted average formula, the weights of the colors are not the same. Green has the largest weight because the human eye perceives it easily than the rest of the RGB
additive primary colors.