如何检测图像是照片,剪贴画还是线条图?
computer-vision
image-processing
java
4
0

识别图像类型的最佳方法是什么? rwong这个问题 回答表明,Google将图片分为以下几类:

  • 照片-连续色调
  • 剪贴画-平滑阴影
  • 线描-双色调

将图像分类到这些组之一的最佳策略是什么?我目前正在使用Java,但是欢迎使用任何常规方法。

谢谢!


更新:

我尝试了tyjkenn在评论中提到的独特的颜色计数方法,该方法似乎可以在我尝试过的案例中使用大约90%。特别是,黑白照片很难单独使用独特的色彩计数来正确检测。

仅获取图像直方图并计算偷看次数似乎不是一个可行的选择。例如,此图像只有两个峰值:

这是我已签出的另外两张图片:

参考资料:
Stack Overflow
收藏
评论
共 3 个回答
高赞 时间 活跃

这个问题可以通过图像分类来解决,这很可能是Google的解决方案。基本上,您要做的是(i)获得一组标记为3类的图像:照片,剪贴画和线条画; (ii)从这些图像中提取特征; (iii)使用图像的特征和标签来训练分类器。

特征提取:

在此步骤中,您必须提取视觉信息,这可能有助于分类器区分图像的3类:

  • 图像直方图及其变体是一个非常基本但有用的视觉功能。例如,照片的灰度直方图可能比剪贴画的直方图更平滑,在剪贴画中,您的区域可能全都具有相同的颜色值。
  • 可以使用的另一功能是将图像转换到频域(例如,使用FFTDCT )并测量高频分量的能量。由于线条图可能会具有鲜明的颜色过渡,因此其高频分量将倾向于积累更多的能量。

还可以使用许多其他特征提取算法

训练分类器:

在特征提取阶段之后,我们将为每个图像提供一个数值向量(我们将其称为图像特征向量)及其元组。这是训练分类器的合适输入。至于分类器,可以考虑神经网络SVM

分类:

现在我们有了训练有素的分类器,要对图像进行分类(即检测图像类别),我们只需提取其特征并将其输入到分类器中,它将返回其预测的类别

收藏
评论

相当简单但有效的方法来区分图纸和照片。结合使用它们可获得最佳精度:

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

此代码为您提供每个区域超过一百万个的频率数。再次:根据您的样本图像优化此类数字。

为您的图像集组合并优化这些方法。让我知道您是否可以改善-或只是编辑此答案。我想自己改善它:-)

收藏
评论

直方图将是这样做的第一种方法。
将彩色图像转换为灰度并计算直方图。一个非常双峰的直方图,在黑色(或深色)和白色(或右侧)中有两个尖锐的峰值,可能还有更多的白色,这是画线的好兆头。
如果您只有几个峰,则可能是剪贴画类型的图像。
否则,是照片。

收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号