python - 使用 Python 检测图像是彩色、灰度还是黑白

标签 python opencv image-processing python-imaging-library

我从一个 jpeg 格式的 PDF 文件中提取页面图像,我需要确定每个图像是更灰度、彩色还是黑白(具有容差系数)。

我找到了一些使用 PIL(herehere)进行颜色检测的方法,但我无法弄清楚如何回答这个简单(视觉)问题:它是否更黑白,彩色还是灰度图像?

我更喜欢在这部分使用 Python 和 PIL,但如果有人有线索(或解决方案),我也可以使用 OpenCV。

最佳答案

我尝试了 Gepeto 的解决方案,它有很多误报,因为颜色大方差可能只是偶然相似。正确的做法是计算每个像素的方差。先缩小图像,这样您就不必处理数百万像素。

默认情况下,此函数还使用平均颜色偏差调整,我发现它可以改进预测。这样做的一个副作用是它还会检测单色但非灰度图像(通常是棕褐色调的东西,该模型似乎在检测与灰度的较大偏差时有点崩溃)。您可以通过对色带均值设置阈值将它们与真正的灰度区分开来。

我在包含 13,000 张摄影图像的测试集上运行此程序,得到的分类准确率为 99.1%,召回率为 92.5%。通过使用非线性偏差调整可能会进一步提高准确性(例如,颜色值必须在 0 到 255 之间)。也许查看中位数平方误差而不是 MSE 会更好地允许例如带有小颜色标记的灰度图像。

from PIL import Image, ImageStat
def detect_color_image(file, thumb_size=40, MSE_cutoff=22, adjust_color_bias=True):
    pil_img = Image.open(file)
    bands = pil_img.getbands()
    if bands == ('R','G','B') or bands== ('R','G','B','A'):
        thumb = pil_img.resize((thumb_size,thumb_size))
        SSE, bias = 0, [0,0,0]
        if adjust_color_bias:
            bias = ImageStat.Stat(thumb).mean[:3]
            bias = [b - sum(bias)/3 for b in bias ]
        for pixel in thumb.getdata():
            mu = sum(pixel)/3
            SSE += sum((pixel[i] - mu - bias[i])*(pixel[i] - mu - bias[i]) for i in [0,1,2])
        MSE = float(SSE)/(thumb_size*thumb_size)
        if MSE <= MSE_cutoff:
            print "grayscale\t",
        else:
            print "Color\t\t\t",
        print "( MSE=",MSE,")"
    elif len(bands)==1:
        print "Black and white", bands
    else:
        print "Don't know...", bands

关于python - 使用 Python 检测图像是彩色、灰度还是黑白,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20068945/

相关文章:

python - 如何在Flow仿真中改变车辆的尺寸?

python - PyCharm CE 2017.2.2 : APPCRASH "Python has stopped working" randomly on Windows 7

java - 递归洪水填充溢出堆栈

ubuntu - 如何在窗口 7 的 Octave 中使用 Vlfeat?

opencv - 如何使用openCV识别连接组件的最窄部分?

python - 我的 formencode.variabledecode 返回一个空列表 - Pylons

python - 无法添加或更新子行: a foreign key constraint fails on a Django generated MySQL table

c++ - 如何在 OpenCV 中获取网络摄像头 fps 速率?

c++ - OpenCV:使用高斯模糊裁剪图像

python - 从视频/图像中提取元数据