如何仅用Python标准库检查JPEG图像是彩色还是灰度
我需要用Python写一个测试案例,来检查一个jpg图片是彩色的还是黑白的。有没有人能告诉我有没有办法在不安装额外库(比如OpenCV)的情况下做到这一点?
12 个回答
6
在处理灰度图像时,某个像素的所有通道值都是相同的(如果只有一个通道,那就没问题了)。
所以,基本上你可以列出所有像素的三个通道值,来检查每个像素的三个通道是否都相等。
Image.getcolors()
这个函数会返回一个无序的 (数量, 像素) 值的列表。
im = Image.open('path_to_image.whatever')
color_count = im.getcolors()
如果 len(color_count)
超过 256(默认的最大值),那么这个函数会返回 None,这意味着你的像素列表中有超过 256 种颜色选项,因此这是一张彩色图像(灰度图像最多只能有 256 种颜色,从 (0,0,0)
到 (255,255,255)
)。
所以之后你只需要:
if color_count:
# your image is grayscale
else:
# your images is colored
请注意,这个方法只在使用 getcolors()
的默认参数值时有效。
文档链接: https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.getcolors
19
为了提高处理速度,最好避免对每个像素进行循环操作。可以使用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
22
这里有一种更符合Python风格的方法,使用了numpy的功能和opencv库:
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
31
可以这样做:
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'
26
你可以检查每一个像素,看看它是否是灰度的(也就是红色、绿色和蓝色的值相等)。
from PIL 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