相当简单但有效的方法来区分图纸和照片。结合使用它们可获得最佳精度:
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代码段):
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
此代码为您提供每个区域超过一百万个的频率数。再次:根据您的样本图像优化此类数字。
为您的图像集组合并优化这些方法。让我知道您是否可以改善-或只是编辑此答案。我想自己改善它:-)
0
识别图像类型的最佳方法是什么? rwong对这个问题 的 回答表明,Google将图片分为以下几类:
将图像分类到这些组之一的最佳策略是什么?我目前正在使用Java,但是欢迎使用任何常规方法。
谢谢!
更新:
我尝试了tyjkenn在评论中提到的独特的颜色计数方法,该方法似乎可以在我尝试过的案例中使用大约90%。特别是,黑白照片很难单独使用独特的色彩计数来正确检测。
仅获取图像直方图并计算偷看次数似乎不是一个可行的选择。例如,此图像只有两个峰值:
这是我已签出的另外两张图片: