简体   繁体   中英

Count the pixels of specific color intensity in an image

I want to count the pixels of color intensity of [150,150,150] in an image and I have determined the shape of the image and made a loop to scan the image pixel by pixel but I have faced this error and I don't know why it appeared.

But I got the following error:

File "D:/My work/MASTERS WORK/FUNCTIONS.py", line 78, in <module>
    if img[x,y] == [150,150,150]:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

Code:

img = cv2.imread('imj.jpg')
h ,w =img.shape[:2]
m= 0
for y in range(h):
    for x in range(w):
        if img[x,y] == [150,150,150]:
            m+=1
print('No. of points = ' , m)

Instead of using a for loop, you should vectorize the processing using Numpy. To count the number of pixels of color intensity [150,150,150] , you can use np.count_nonzero()

count = np.count_nonzero((image == [150, 150, 150]).all(axis = 2)) 

Here's an example. We create a black image of size [400,400] and color the bottom left corner to [150,150,150]

import numpy as np

# Create black image
image = np.zeros((400,400,3), dtype=np.uint8)
image[300:400,300:400] = (150,150,150)

We then count the number of pixels at this intensity

# Count number of pixels of specific color intensity
count = np.count_nonzero((image == [150, 150, 150]).all(axis = 2))
print(count)

10000

Finally we if wanted to change the pixels of that intensity, we can find all desired pixels and use a mask. In this case, we turn the pixels to green

# Find pixels of desired color intensity and draw onto mask
mask = (image == [150.,150.,150.]).all(axis=2)

# Apply the mask to change the pixels
image[mask] = [36,255,12]

Full code

import numpy as np

# Create black image
image = np.zeros((400,400,3), dtype=np.uint8)
image[300:400,300:400] = (150,150,150)

# Count number of pixels of specific color intensity
count = np.count_nonzero((image == [150, 150, 150]).all(axis = 2))
print(count)

# Find pixels of desired color intensity and draw onto mask
mask = (image == [150.,150.,150.]).all(axis=2)

# Apply the mask to change the pixels
image[mask] = [36,255,12]

It's not a recommended way to count the pixels having a given value, but still you can use below code for above case(same value of r , g and b ):

for x in range(h):
    for y in range(w):
        if np.all(img[x, y]==150, axis=-1): # (img[x, y]==150).all(axis=-1)
            m+=1

If you want to count pixels with different values of r , g and b , then use np.all(img[x, y]==[b_value, g_value, r_value], axis=-1) , since OpenCV follows bgr order.

Alternatively, you can use np.count_nonzero(np.all(img==[b_value, g_value, r_value],axis=-1)) or simply np.count_nonzero(np.all(img==150, axis=-1)) in above case.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM