Проверьте, не является ли изображение в градациях серого без цикла for - PullRequest
0 голосов
/ 01 ноября 2019

Я пытаюсь заменить следующий код, который проверяет, является ли изображение в градациях серого, анализируя сам фактический контент изображения (а не только общее количество каналов), на код, который использует np.any() или что-то, что позволяет мне удалить для-loops:

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

Ответы [ 2 ]

1 голос
/ 01 ноября 2019

Похоже, вы проверяете, отображается ли изображение в градациях серого. Изображения в градациях серого таковы, что все каналы RGB равны друг другу для всего изображения. Что вы можете сделать, это использовать первый канал и проверить, не совпадают ли пиксели с другими каналами, передавая в эфир:

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

Обратите внимание, что в приведенном выше предположении принимается uint8 или целочисленные пиксели. ,Настоятельно рекомендуется не сравнивать со сравнением с плавающей запятой, например с тем, как вы сделали в своем коде при преобразовании в него. Чтобы использовать код выше, пожалуйста, удалите преобразование с плавающей точкой. Целочисленное сравнение безопаснее. Сначала мы проверим, не совпадают ли пиксели в первом канале с пикселями всех остальных каналов в вашем изображении. Как только это будет сделано, мы завернем еще один np.any вызов, чтобы охарактеризовать все изображение. check содержит этот результат - True означает, что ваше изображение в градациях серого, а False в противном случае. Обратите внимание на инверсию конечного результата, так как мы явно проверяем любые пиксели, которые не равны, и когда мы используем np.any, чтобы свести все к одному ответу, но нам придется инвертировать, потому что мы проверяли дляпротивоположная ситуация.

0 голосов
/ 02 ноября 2019

Я хотел бы пойти с чем-то вроде этого - это не так сложно, как кажется, есть несколько строк настройки и несколько закомментированных строк DEBUG, чтобы показать мое мышление. Фактический код является однострочным.

Это в основном проверка того, что весь красный канал изображения (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().

Обратите внимание, что из-за and в серединетеста для isGrey, вторая половина теста может быть закорочена (опущено, чтобы сэкономить половину времени), поскольку, если уже ясно, что красный канал не соответствует зеленому каналу, нет смысла проверять, чтопроисходит в синем канале.

...