Luk*_*ane 21 java image-processing computer-vision
识别图像类型的最佳方法是什么?rwong 对这个问题的回答表明Google将图像分为以下几组:
将图像分类为其中一组的最佳策略是什么?我目前正在使用Java,但欢迎任何一般方法.
谢谢!
我尝试了tyjkenn在评论中提到的独特颜色计数方法,它似乎适用于我尝试过的大约90%的案例.特别是使用独特的颜色计数难以正确地检测黑白照片.
相当简单但有效的方法来区分图纸和照片。结合使用它们以达到最佳精度:
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
Run Code Online (Sandbox Code Playgroud)
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))
Run Code Online (Sandbox Code Playgroud)
您需要调整和优化这些值。十种颜色足以容纳您的数据吗?什么百分比最适合您。通过测试大量样本图像来找出它。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
Run Code Online (Sandbox Code Playgroud)
此代码为您提供每个区域超过一百万的频率数。再次:根据您的示例图像优化这些数字。
为您的图像集组合和优化这些方法。如果您可以改进这一点,请告诉我 - 或者只是编辑此答案。我想自己改进它:-)
这个问题可以通过图像分类来解决,这可能是谷歌解决这个问题的方法。基本上,您需要做的是(i)获取一组标记为 3 类的图像:照片、剪贴画和线条画;(ii) 从这些图像中提取特征;(iii) 使用图像的特征和标签来训练分类器。
在此步骤中,您必须提取可能对分类器区分 3 类图像有用的视觉信息:
还可以使用许多其他特征提取算法。
在特征提取阶段之后,我们将为每个图像提供一个数值向量(我们称之为图像特征向量)及其元组。这是训练分类器的合适输入。至于分类器,可以考虑神经网络、SVM等。
现在我们有了一个经过训练的分类器,要对图像进行分类(即检测图像类别),我们只需提取其特征并将其输入到分类器,它将返回其预测类别