如何计算满足谓词的像素值?
How to count pixel values satisfying a predicate?
给定一个形状为 (8, 24, 3)
的 NumPy 数组,对应于高度为 8
宽度为 24
的 HSV 图像,我想计算满足定义的某个谓词的像素数通过函数。
通常对于 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
个值的数量?
我可以对需要三个值的谓词做类似的事情吗?
对应于形状数组中的 HSV 值 (8, 24, 3)
?
像这样:
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 执行其过滤魔法。
使用 NumPy 的 boolean array indexing, and the bitwise_and
and bitwise_or
functions (used as &
and |
) to combine these boolean arrays. At last, count True
values in the resulting array using count_nonzero
:
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()
这是我的标准测试图像(虽然不符合):
根据您的要求,这就是“红色面具”:
这就是输出:
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
这是使用 boolean array indexing and 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]])
给定一个形状为 (8, 24, 3)
的 NumPy 数组,对应于高度为 8
宽度为 24
的 HSV 图像,我想计算满足定义的某个谓词的像素数通过函数。
通常对于 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
个值的数量?
我可以对需要三个值的谓词做类似的事情吗?
对应于形状数组中的 HSV 值 (8, 24, 3)
?
像这样:
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 执行其过滤魔法。
使用 NumPy 的 boolean array indexing, and the bitwise_and
and bitwise_or
functions (used as &
and |
) to combine these boolean arrays. At last, count True
values in the resulting array using count_nonzero
:
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()
这是我的标准测试图像(虽然不符合
根据您的要求,这就是“红色面具”:
这就是输出:
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
这是使用 boolean array indexing and 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]])