检查图像是否为灰度,无for循环

2024-03-28 14:14:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试将以下代码替换为使用np.any()或允许我删除for循环的代码,这些代码通过分析实际图像内容本身(而不仅仅是通道总数)来检查图像是否为灰度:

from scipy.misc import imread
import numpy as np

def check_grayscale(image):
    image = imread('input.jpg').astype(np.float64)
    w = image.shape[0]
    h = image.shape[1]
    for i in range(w):
        for j in range(h):
            r, g, b = image[i][j]
            if r != g != b:
                return False
    return True

Tags: 代码in图像imageimport内容forreturn
2条回答

这看起来像是在检查图像是否为灰度。灰度图像使得整个图像的所有RGB通道彼此相等。您可以使用第一个频道,并通过广播查看是否有任何像素不等于任何其他频道:

check = ~np.any(np.any(image[...,0][:,:,None] != image, axis=2))

请注意,以上假设为uint8或整数像素。强烈建议您不要与浮点比较进行比较,例如在转换为浮点比较时在代码中所做的比较。要使用上述代码,请删除浮点转换。整数比较更安全。我们将首先检查第一个通道中的任何像素是否不等于图像中所有其他通道的任何像素。完成后,我们再包装另一个np.any调用来描述整个图像。check包含这样一个结果-True即您的图像是灰度的,否则False。请注意最终结果的反转,因为我们显式地检查任何不相等的像素,并且当我们使用np.any将其减少到一个答案时,我们必须反转,因为我们检查的是相反的情况。你知道吗

我会这样做-这不是很难,因为它看起来,有几行设置和一些注释掉调试行来显示我的想法。实际代码是一行代码。你知道吗

它基本上是检查图像的整个红色通道(im[...,0])与整个绿色通道(im[...,1])匹配,同样地,红色与蓝色匹配。你知道吗

#!/usr/bin/env python3

import numpy as np

# Synthesize single channel, grey image of randomness
rangrey = np.random.randint(0,256,(480,640,1), dtype=np.uint8)

# Make RGB equivalent with R=G=B by stacking initial image 3x
ranrgb  = np.dstack((rangrey,rangrey,rangrey))

# DEBUG: Check shape
# print(ranrgb,shape)      # prints (480, 640, 3)

# DEBUG: Check red channel equals green channel throughout image
# DEBUG print(np.equal(ranrgb[...,0],ranrgb[...,1]).all())     # prints True

# DEBUG: Check red channel equals blue channel throughout image
# DEBUG print(np.equal(ranrgb[...,0],ranrgb[...,2]).all())     # prints True

isGrey = np.equal(ranrgb[...,0],ranrgb[...,1]).all() and np.equal(ranrgb[...,1],ranrgb[...,2]).all()
print(isGrey)    # prints True

# Now change one pixel and check
ranrgb[0,0,0] += 1

isGrey = np.equal(ranrgb[...,0],ranrgb[...,1]).all() and np.equal(ranrgb[...,1],ranrgb[...,2]).all()
print(isGrey)    # prints False

如果你的图像是float64由于某种未知的原因,你应该用np.allclose()代替np.equal()。你知道吗

注意,由于andisGrey的测试中间,测试的后半部分可能会短路(省略以节省一半的时间),因为如果已经很清楚红色通道与绿色通道不匹配,就没有必要检查蓝色通道中发生了什么。你知道吗

相关问题 更多 >