私はpythonにテストケースを作成して、jpg画像がカラーかグレースケールかどうかを確認する必要があります。 opencv?
@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)
次のように行うことができます:
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'
処理を高速化するには、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
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
高速な結果のためのパフォーマンス強化:多くの画像に黒または白の境界線があるため、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=グレースケールの場合、個々のピクセルを検査する必要なく、答えがわかっています。)
なぜ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])。グレースケール画像の場合、リストのすべての要素は同じです。