web-dev-qa-db-ja.com

Python stdlibのみを使用して、jpeg画像がカラースケールかグレースケールかを確認する方法

私はpythonにテストケースを作成して、jpg画像がカラーかグレースケールかどうかを確認する必要があります。 opencv?

23
kadina

@gatの答えを拡張する:

import Image

def is_grey_scale(img_path):
    img = Image.open(img_path).convert('RGB')
    w,h = img.size
    for i in range(w):
        for j in range(h):
            r,g,b = img.getpixel((i,j))
            if r != g != b: return False
    return True

基本的に、すべてのピクセルをチェックして、それがグレースケールであるかどうかを確認します(R == G == B)

12
joaoricardo000

次のように行うことができます:

from scipy.misc import imread, imsave, imresize
image = imread(f_name)
if(len(image.shape)<3):
      print 'gray'
Elif len(image.shape)==3:
      print 'Color(RGB)'
else:
      print 'others'
17
superMind

処理を高速化するには、ImageChopsを使用して、すべてのピクセルでループを回避することをお勧めします(ただし、イメージが本当にグレースケールであることを確認するには、すべてのピクセルの色を比較する必要があり、合計を使用するだけではできません)。

from PIL import Image,ImageChops

def is_greyscale(im):
    """
    Check if image is monochrome (1 channel or 3 identical channels)
    """
    if im.mode not in ("L", "RGB"):
        raise ValueError("Unsuported image mode")

    if im.mode == "RGB":
        rgb = im.split()
        if ImageChops.difference(rgb[0],rgb[1]).getextrema()[1]!=0: 
            return False
        if ImageChops.difference(rgb[0],rgb[2]).getextrema()[1]!=0: 
            return False
    return True
9
Karl K

Numpy機能とopencvを使用するよりPython的な方法があります。

import cv2
def isgray(imgpath):
    img = cv2.imread(imgpath)
    if len(img.shape) < 3: return True
    if img.shape[2]  == 1: return True
    b,g,r = img[:,:,0], img[:,:,1], img[:,:,2]
    if (b==g).all() and (b==r).all(): return True
    return False
5

高速な結果のためのパフォーマンス強化:多くの画像に黒または白の境界線があるため、imからいくつかのランダムなi、jポイントをサンプリングしてテストすることで、より高速な終了を期待しますか?または、モジュロ演算を使用して画像行をトラバースします。最初に、サンプル(-without-replacement)を100個のランダムなi、jポイントと言います。決定的ではない万が一の場合には、それを直線的にスキャンします。

カスタムイテレータiterpixels(im)を使用する。 PILがインストールされていないため、これをテストすることはできません。概要は次のとおりです。

import Image

def isColor(r,g,b): # use Tuple-unpacking to unpack pixel -> r,g,b
    return (r != g != b)

class Image_(Image):
    def __init__(pathname):
        self.im = Image.open(pathname)
        self.w, self.h = self.im.size
    def iterpixels(nrand=100, randseed=None):
        if randseed:
            random.seed(randseed) # For deterministic behavior in test
        # First, generate a few random pixels from entire image
        for randpix in random.choice(im, n_Rand)
            yield randpix
        # Now traverse entire image (yes we will unwantedly revisit the nrand points once)
        #for pixel in im.getpixel(...): # you could traverse rows linearly, or modulo (say) (im.height * 2./3) -1
        #    yield pixel

    def is_grey_scale(img_path="lena.jpg"):
        im = Image_.(img_path)
        return (any(isColor(*pixel)) for pixel in im.iterpixels())

(私の元の発言も同様です。最初に、JPEGヘッダーをチェックし、オフセット6:コンポーネントの数(1 =グレースケール、3 = RGB)です。1=グレースケールの場合、個々のピクセルを検査する必要なく、答えがわかっています。)

4
smci

なぜImageStatモジュールを使用しないのですか?

from PIL import Image, ImageStat

def is_grayscale(path="image.jpg")

    im = Image.open(path).convert("RGB")
    stat = ImageStat.Stat(im)

    if sum(stat.sum)/3 == stat.sum[0]:
        return True
    else:
        return False

stat.sumは、リストビューのすべてのピクセルの合計を示します= [R、G、B](例:[568283302.0、565746890.0、559724236.0])。グレースケール画像の場合、リストのすべての要素は同じです。

1
GriMel