【问题标题】:Python script to count pixel values fails on a less-than/greater-than comparison用于计算像素值的 Python 脚本在小于/大于比较时失败
【发布时间】:2016-10-19 04:08:02
【问题描述】:

我写了一个简短的脚本来计算图像中的像素值:

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 库。为什么会出现在这里?我是否限制了大于/小于符号的错误?我试图修复它

numA = (00.99 &lt; y).sum() and (y &lt; 85.00).sum()

但这只是给了我随机的超高值。

更新 - Oct20

所以,我改变了它:

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}

为什么要这样做?

【问题讨论】:

    标签: python arrays numpy operators truthiness


    【解决方案1】:

    您的方法存在一些问题。

    当你这样做时

    (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
    

    另一个问题来自对范围使用紧凑表示法,使用&amp;np.logical_and() 将其分成两部分很容易解决

    In [12]: x[np.where((2 < x) & (x < 6))].sum()
    Out[12]: 12
    

    【讨论】:

    • 好的,知道了。谢谢。
    • 嘿,我还有一个问题:像素数一直在剧烈波动。
    • 等等,也许我真的不明白你想做什么。您想计算符合您条件的数组元素的数量,还是想对它们的内容求和?如果您想要第一个,则整个 np.where 内容不适用。你应该得到正确的结果只是做((00.99 &lt; x) &amp; (x &lt; 85.00)).sum()
    • 我更新了我的帖子,但基本是这样的:如果我有数组:([1, 1], [2, 2], [200, 200]) 我想获得我设置的三个边距之间的图像。
    • 对不起,那是我的错,我看错了你的问题,你应该能够像我在之前的评论中所说的那样解决它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多