区分图纸和照片的方法相当简单但有效。结合使用它们以获得最佳精度:
1) Mime 类型或文件扩展名
PNG 通常是剪贴画或图画,而 JPEG 主要是照片。
2) 透明度
如果图像具有 Alpha 通道,则它很可能是一幅图画。如果存在 Alpha 通道,您还可以遍历所有像素以检查是否确实使用了透明度。这里有一个 Python 示例代码:
from PIL import Image
img = Image.open('test.png')
transparency = False
if img.mode in ('RGBA', 'RGBa', 'LA') or (img.mode == 'P' and 'transparency' in img.info):
if img.mode != 'RGBA': img = img.convert('RGBA')
transparency = any(px for px in img.getdata() if px[3] < 220)
print 'Transparency:', transparency
3) 颜色分布
剪贴画通常具有相同颜色的区域。如果几种颜色构成了图像的重要部分,那么它更像是一幅图画而不是一张照片。此代码输出由十种最常用的颜色组成的图像区域的百分比(Python 示例):
from PIL import Image
img = Image.open('test.jpg')
img.thumbnail((200, 200), Image.ANTIALIAS)
w, h = img.size
print sum(x[0] for x in sorted(img.convert('RGB').getcolors(w*h), key=lambda x: x[0], reverse=True)[:10])/float((w*h))
您需要调整和优化这些价值观。十种颜色足够您的数据吗?什么百分比最适合您。通过测试大量样本图像来找出它。 30% 或更多通常是剪贴画。不过,不适用于天空照片或类似的东西。因此,我们需要另一种方法——下一种。
4) 通过 FFT 进行锐边检测
锋利的边缘会导致傅里叶频谱中出现高频。通常这些特征更常见于图纸中(另一个 Python sn-p):
from PIL import Image
import numpy as np
img = Image.open('test.jpg').convert('L')
values = abs(numpy.fft.fft2(numpy.asarray(img.convert('L')))).flatten().tolist()
high_values = [x for x in values if x > 10000]
high_values_ratio = 100*(float(len(high_values))/len(values))
print high_values_ratio
此代码为您提供每个区域超过一百万的频率数量。同样:根据您的示例图像优化这些数字。
针对您的图像集组合和优化这些方法。让我知道你是否可以改进这个 - 或者只是编辑这个答案,拜托。我想自己改进它:-)