给定一个形状为(8, 24, 3)
的NumPy数组,它对应于高度为8
和宽度为24
的HSV图像,我想计算满足由a定义的某些谓词的像素数量功能。
通常使用NumPy数组,我们可以执行以下操作:
def isSmall(x):
return x < 3
a = np.array([1,2,3,4,5])
isSmall(a)
output: array([ True, True, False, False, False])
在什么时候我们可以计算输出中True
值的数量?
我可以对期望三个值的谓词做类似的事情吗?
对应于形状为(8, 24, 3)
的数组中的HSV值?
类似这样的东西:
def isRed(x):
h, s, v = (x[0], x[1], x[2])
return ((170 <= h <= 180 or 0 <= h <= 10) and 100 <= s <= 255)
a = image of shape (8,24,3)
isRed(a)
Desired output: array([[ True, True, ..., False, False],
... , ...
[False, True, ..., False, False]])
但是,这引发了形状错误,因为似乎整个数组都传递给了函数,而不是NumPy进行了过滤。
答案 0 :(得分:1)
使用NumPy的boolean array indexing,bitwise_and
和bitwise_or
函数(分别用作&
和|
)来组合这些布尔数组。最后,使用count_nonzero
在结果数组中计算True
个值:
import cv2
import numpy as np
def is_red(img):
h, s = cv2.split(cv2.cvtColor(img, cv2.COLOR_BGR2HSV))[:2]
idx = (((h >= 170) & (h <= 180)) | ((h >= 0) & (h <= 10))) & ((s >= 100) & (s <= 255))
# Just for visual debugging
cv2.imshow('image', image)
cv2.imshow('red_mask', idx.astype(np.uint8) * 255)
return idx, np.count_nonzero(idx)
image = cv2.imread('images/paddington.png')
mask, n_pixels = is_red(image)
print('Red mask:\n', mask, '\n')
print('Number of red pixels: ', n_pixels)
cv2.waitKey(0)
cv2.destroyAllWindows()
这是我的标准测试图片(尽管不符合Setchell's law):
根据您的要求,这就是“红色面具”:
这就是输出:
Red mask:
[[False False False ... False False False]
[False False False ... False False False]
[False False False ... False False False]
...
[False False False ... False False False]
[False False False ... False False False]
[False False False ... False False False]]
Number of red pixels: 31938
希望有帮助!
----------------------------------------
System information
----------------------------------------
Platform: Windows-10-10.0.16299-SP0
Python: 3.8.1
NumPy: 1.18.1
OpenCV: 4.2.0
答案 1 :(得分:1)
这是使用boolean array indexing和binary bitwise operators的一种方法:
a = np.random.randint(0,255,(8,24,3))
h = a[...,0]
s = a[...,1]
m = (((170 <= h) & (180 >= h)) | ((0 <= h) & (10 >= h))) & ((100 <= s) & (255 >= s))
a[m]
array([[ 0, 154, 31],
[ 1, 101, 63],
[ 7, 118, 112],
[179, 154, 13],
[170, 163, 58],
[176, 105, 143],
[ 2, 237, 161],
[ 1, 107, 33],
[ 3, 152, 235],
[ 8, 233, 231],
[ 4, 128, 47],
[174, 165, 75]])