Python 计算像素值的脚本在 less-than/greater-than 比较中失败
Python script to count pixel values fails on a less-than/greater-than comparison
我写了一个简短的脚本来计算图像中的像素值:
import os
import sys
import cv2
import numpy as np
imn = (sys.argv[1])
a = cv2.imread(imn, 0)
b = cv2.imread(imn, 1)
c = cv2.GaussianBlur(cv2.imread(imn, 0), (7,7), 2)
def NC(img):
y = img.reshape(1, -1)
numA = (y < 127.5).sum()
numB = (y > 127.5).sum()
return ({'less': numA, 'greater': numB})
aa = NC(a)
bb = NC(b)
cc = NC(c)
print "File: {}".format(imn.split('/')[-1])
print "Image: {} - Set: {}".format('A', aa)
print "Image: {} - Set: {}".format('B', bb)
print "Image: {} - Set: {}".format('C', cc)
而且效果很好:
File: ObamaBidenSituationRoom.jpg
Image: A - Set: {'greater': 480558, 'less': 611282}
Image: B - Set: {'greater': 1441948, 'less': 1833572}
Image: C - Set: {'greater': 471559, 'less': 620281}
但是当我试图展开它时:
def NC(img):
y = img.reshape(1, -1)
numA = (00.99 < y < 85.00).sum()
numB = (85.00 < y < 170.0).sum()
numC = (170.0 < y < 256.0).sum()
return ({'low': numA, 'middle': numB, 'high': numC})
它给了我一个错误:
Traceback (most recent call last):
File "Bins--02.py", line 25, in <module>
aa = NC(a)
File "Bins--02.py", line 17, in NC
numA = (00.99 < y < 85.00).sum()
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
我不久前得到了这张图片,但那是我最终没有使用的 matplotlib 库。为什么会出现在这里?我是否认为 greater-than/less-than 标志错误?我试着修复它
numA = (00.99 < y).sum() and (y < 85.00).sum()
但这给了我 运行dom 超高的价值。
更新 - 10 月 20 日
所以,我改变了它:
def NC(img):
x = img.reshape(1, -1)
numA = x[np.where((00.99 < x) & (x < 85.00))].sum()
numB = x[np.where((85.00 < x) & (x < 170.0))].sum()
numC = x[np.where((170.0 < x) & (x < 256.0))].sum()
numD = x.shape
return ({'total': numD, 'low': numA, 'middle': numB, 'high': numC})
现在可以使用了,但是有一个问题:像素数不匹配。
Image: lenna.png
Image: A Set:{'high': 8367459, 'middle': 20278460, 'total': (1, 262144), 'low': 3455619}
Image: B Set:{'high': 45250935, 'middle': 43098232, 'total': (1, 786432), 'low': 11609051}
Image: C Set:{'high': 8216989, 'middle': 20633144, 'total': (1, 262144), 'low': 3531090}
尺寸以像素为单位,不能超过总数。我哪来的200万?
例如,我 运行 它在一个 100x100 的蓝色圆圈图像上:
Image: lightblue.png
Image: A Set:{'high': 0, 'middle': 1035999, 'total': (1, 10000), 'low': 0}
Image: B Set:{'high': 1758789, 'middle': 1212681, 'total': (1, 30000), 'low': 417612}
Image: C Set:{'high': 0, 'middle': 1014135, 'total': (1, 10000), 'low': 31801}
这是完全错误的。
编辑二
我只是 运行 它在测试阵列上:
i = np.array([[1, 1, 1, 1, 1, 1, 1, 1], [3, 3, 3, 3, 3, 3, 3, 3], [200, 200, 200, 200, 200, 200, 200, 200]])
def NC(img):
x = img.reshape(1, -1)
numA = x[np.where((00.99 < x) & (x < 85.00))].sum()
numB = x[np.where((85.00 < x) & (x < 170.0))].sum()
numC = x[np.where((170.0 < x) & (x < 256.0))].sum()
numD = (img.shape[0] * img.shape[1])
return ({'total': numD, 'low': numA, 'middle': numB, 'high': numC})
aa = NC(i)
bb = NC(i)
cc = NC(i)
print "Image: {} Set:{}".format('A', aa)
print "Image: {} Set:{}".format('B', bb)
print "Image: {} Set:{}".format('C', cc)
它完全坏了:
Image: A Set:{'high': 1600, 'middle': 0, 'total': 24, 'low': 32}
Image: B Set:{'high': 1600, 'middle': 0, 'total': 24, 'low': 32}
Image: C Set:{'high': 1600, 'middle': 0, 'total': 24, 'low': 32}
为什么要这样做?
你的方法有几个问题。
当你这样做时
(y < 85.00).sum()
你实际上是在对真值条件求和。因此,您最终会计算条件计算结果为 True
的位置。你可以通过一个简单的例子很容易地看到它:
In [6]: x = np.arange(10)
In [7]: x
Out[7]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [8]: x < 4
Out[8]: array([ True, True, True, True, False, False, False, False, False, False], dtype=bool)
In [9]: (x < 4).sum()
Out[9]: 4
现在如果要获取满足条件的索引,可以使用np.where
In [10]: np.where(x < 4)
Out[10]: (array([0, 1, 2, 3]),)
并将它们用于您的总和
In [11]: x[np.where(x < 4)].sum()
Out[11]: 6
另一个问题来自对范围使用紧凑的表示法,使用 &
或 np.logical_and()
将其分成两部分很容易解决
In [12]: x[np.where((2 < x) & (x < 6))].sum()
Out[12]: 12
我写了一个简短的脚本来计算图像中的像素值:
import os
import sys
import cv2
import numpy as np
imn = (sys.argv[1])
a = cv2.imread(imn, 0)
b = cv2.imread(imn, 1)
c = cv2.GaussianBlur(cv2.imread(imn, 0), (7,7), 2)
def NC(img):
y = img.reshape(1, -1)
numA = (y < 127.5).sum()
numB = (y > 127.5).sum()
return ({'less': numA, 'greater': numB})
aa = NC(a)
bb = NC(b)
cc = NC(c)
print "File: {}".format(imn.split('/')[-1])
print "Image: {} - Set: {}".format('A', aa)
print "Image: {} - Set: {}".format('B', bb)
print "Image: {} - Set: {}".format('C', cc)
而且效果很好:
File: ObamaBidenSituationRoom.jpg
Image: A - Set: {'greater': 480558, 'less': 611282}
Image: B - Set: {'greater': 1441948, 'less': 1833572}
Image: C - Set: {'greater': 471559, 'less': 620281}
但是当我试图展开它时:
def NC(img):
y = img.reshape(1, -1)
numA = (00.99 < y < 85.00).sum()
numB = (85.00 < y < 170.0).sum()
numC = (170.0 < y < 256.0).sum()
return ({'low': numA, 'middle': numB, 'high': numC})
它给了我一个错误:
Traceback (most recent call last):
File "Bins--02.py", line 25, in <module>
aa = NC(a)
File "Bins--02.py", line 17, in NC
numA = (00.99 < y < 85.00).sum()
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
我不久前得到了这张图片,但那是我最终没有使用的 matplotlib 库。为什么会出现在这里?我是否认为 greater-than/less-than 标志错误?我试着修复它
numA = (00.99 < y).sum() and (y < 85.00).sum()
但这给了我 运行dom 超高的价值。
更新 - 10 月 20 日
所以,我改变了它:
def NC(img):
x = img.reshape(1, -1)
numA = x[np.where((00.99 < x) & (x < 85.00))].sum()
numB = x[np.where((85.00 < x) & (x < 170.0))].sum()
numC = x[np.where((170.0 < x) & (x < 256.0))].sum()
numD = x.shape
return ({'total': numD, 'low': numA, 'middle': numB, 'high': numC})
现在可以使用了,但是有一个问题:像素数不匹配。
Image: lenna.png
Image: A Set:{'high': 8367459, 'middle': 20278460, 'total': (1, 262144), 'low': 3455619}
Image: B Set:{'high': 45250935, 'middle': 43098232, 'total': (1, 786432), 'low': 11609051}
Image: C Set:{'high': 8216989, 'middle': 20633144, 'total': (1, 262144), 'low': 3531090}
尺寸以像素为单位,不能超过总数。我哪来的200万?
例如,我 运行 它在一个 100x100 的蓝色圆圈图像上:
Image: lightblue.png
Image: A Set:{'high': 0, 'middle': 1035999, 'total': (1, 10000), 'low': 0}
Image: B Set:{'high': 1758789, 'middle': 1212681, 'total': (1, 30000), 'low': 417612}
Image: C Set:{'high': 0, 'middle': 1014135, 'total': (1, 10000), 'low': 31801}
这是完全错误的。
编辑二
我只是 运行 它在测试阵列上:
i = np.array([[1, 1, 1, 1, 1, 1, 1, 1], [3, 3, 3, 3, 3, 3, 3, 3], [200, 200, 200, 200, 200, 200, 200, 200]])
def NC(img):
x = img.reshape(1, -1)
numA = x[np.where((00.99 < x) & (x < 85.00))].sum()
numB = x[np.where((85.00 < x) & (x < 170.0))].sum()
numC = x[np.where((170.0 < x) & (x < 256.0))].sum()
numD = (img.shape[0] * img.shape[1])
return ({'total': numD, 'low': numA, 'middle': numB, 'high': numC})
aa = NC(i)
bb = NC(i)
cc = NC(i)
print "Image: {} Set:{}".format('A', aa)
print "Image: {} Set:{}".format('B', bb)
print "Image: {} Set:{}".format('C', cc)
它完全坏了:
Image: A Set:{'high': 1600, 'middle': 0, 'total': 24, 'low': 32}
Image: B Set:{'high': 1600, 'middle': 0, 'total': 24, 'low': 32}
Image: C Set:{'high': 1600, 'middle': 0, 'total': 24, 'low': 32}
为什么要这样做?
你的方法有几个问题。
当你这样做时
(y < 85.00).sum()
你实际上是在对真值条件求和。因此,您最终会计算条件计算结果为 True
的位置。你可以通过一个简单的例子很容易地看到它:
In [6]: x = np.arange(10)
In [7]: x
Out[7]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [8]: x < 4
Out[8]: array([ True, True, True, True, False, False, False, False, False, False], dtype=bool)
In [9]: (x < 4).sum()
Out[9]: 4
现在如果要获取满足条件的索引,可以使用np.where
In [10]: np.where(x < 4)
Out[10]: (array([0, 1, 2, 3]),)
并将它们用于您的总和
In [11]: x[np.where(x < 4)].sum()
Out[11]: 6
另一个问题来自对范围使用紧凑的表示法,使用 &
或 np.logical_and()
In [12]: x[np.where((2 < x) & (x < 6))].sum()
Out[12]: 12