java - para - imagenes prediseñadas power point 2010
¿Cómo detectar si una imagen es una foto, una imagen prediseñada o un dibujo lineal? (4)
¿Cuál es la mejor manera de identificar el tipo de una imagen? rwong''s answer rwong''s a esta pregunta sugiere que Google segmenta las imágenes en los siguientes grupos:
- Foto - tono continuo
- Imágenes prediseñadas - sombreado suave
- Dibujo lineal - bitonal
¿Cuál es la mejor estrategia para clasificar una imagen en uno de esos grupos? Actualmente estoy usando Java pero cualquier enfoque general es bienvenido.
¡Gracias!
Actualizar:
tyjkenn método único de conteo de colores que tyjkenn mencionó en un comentario y parece funcionar en aproximadamente el 90% de los casos que probé. En particular, las fotos en blanco y negro son difíciles de detectar correctamente usando solo un recuento de color único.
Obtener el histograma de la imagen y contar las miradas por sí solo no parece ser una opción viable. Por ejemplo, esta imagen solo tiene dos picos:
Además de los histogramas de color, también tenga en cuenta la información de bordes y la consistencia de los anchos de línea en toda la imagen.
Foto : los bordes naturales tendrán una variedad de puntos fuertes y es menos probable que haya muchos bordes paralelos.
Imágenes prediseñadas : un algoritmo de cuenca podría ayudar a identificar regiones grandes y conectadas de brillo constante. En imágenes prediseñadas y en imágenes sintéticas diseñadas para alta visibilidad, es más probable que existan líneas perfectamente rectas y líneas paralelas. Es probable que un histograma de fuerzas de borde tenga unos picos muy fuertes.
Dibujo lineal : es probable que las líneas sintéticas tengan un ancho muy consistente. La Transformación del ancho de trazo podría ayudarlo a identificar los trazos. (Uno de los principios básicos es encontrar gradientes de borde que "apunten entre sí"). Un histograma de fuerzas de borde puede tener solo un pico fuerte.
Este problema puede resolverse mediante la clasificación de la imagen y esa es probablemente la solución de Google al problema. Básicamente, lo que tienes que hacer es (i) obtener un conjunto de imágenes etiquetadas en 3 categorías: foto, clip art y dibujo de líneas; (ii) extraer características de estas imágenes; (iii) utilice las características y la etiqueta de la imagen para entrenar a un clasificador.
Extracción de características:
En este paso, debe extraer información visual que puede ser útil para que el clasificador discrimine entre las 3 categorías de imágenes:
- Una característica visual muy básica pero útil es el histograma de la imagen y sus variantes. Por ejemplo, el histograma de nivel de gris de una foto es probablemente más suave que el histograma de un clipart, donde tiene regiones que pueden ser todas del mismo valor de color.
- Otra característica que se puede usar es convertir la imagen al dominio de la frecuencia (por ejemplo, utilizando FFT o DCT ) y medir la energía de los componentes de alta frecuencia. Debido a que los dibujos lineales probablemente tendrán transiciones bruscas de colores, sus componentes de alta frecuencia tenderán a acumular más energía.
También hay una serie de otros algoritmos de extracción de características que pueden usarse.
Entrenando a un clasificador:
Después de la fase de extracción de características, tendremos para cada imagen un vector de valores numéricos (llamémoslo el vector de características de la imagen) y su tupla. Esa es una entrada adecuada para un entrenamiento de un clasificador. En cuanto al clasificador, uno puede considerar Redes neuronales , SVM y others .
Clasificación:
Ahora que tenemos un clasificador entrenado, para clasificar una imagen (es decir, detectar una categoría de imagen) simplemente tenemos que extraer sus características e ingresarla en el clasificador y devolverá su categoría predicha
Los histogramas serían una primera forma de hacer esto.
Convierta la imagen en color a escala de grises y calcule el histograma. Un histograma muy bimodal con 2 picos afilados en negro (u oscuro) y blanco (o derecha), probablemente con mucho más blanco, es una buena indicación para dibujar líneas.
Si tiene solo unos pocos picos más, es probable que sea una imagen de tipo clip-art.
De lo contrario es una foto.
Más bien simples, pero enfoques efectivos para diferenciar entre dibujos y fotos. Úsalos en combinación para lograr la mejor precisión:
1) Tipo Mime o extensión de archivo
Los PNG suelen ser imágenes prediseñadas o dibujos, mientras que los JPEG son en su mayoría fotos.
2) transparencia
Si la imagen tiene un canal alfa, es muy probable que sea un dibujo. En caso de que exista un canal alfa, también puede iterar sobre todos los píxeles para verificar si se utiliza la transparencia. Aquí un código de ejemplo de 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) Distribución del color
Las artes de clip a menudo tienen regiones con colores idénticos. Si algunos colores componen una parte significativa de la imagen, es más bien un dibujo que una foto. Este código genera el porcentaje del área de imagen que se crea a partir de los diez colores más utilizados (ejemplo de 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))
Necesitas adaptar y optimizar esos valores. ¿Son diez colores suficientes para sus datos? ¿Qué porcentaje funciona mejor para usted? Descúbrelo probando un número mayor de imágenes de muestra. 30% o más es típicamente una imagen prediseñada. Sin embargo, no para fotos del cielo o similares. Por lo tanto, necesitamos otro método - el siguiente.
4) Detección de bordes afilados a través de FFT
Los bordes afilados dan como resultado altas frecuencias en un espectro de Fourier. Y, por lo general, estas características se encuentran con más frecuencia en los dibujos (otro fragmento de código de 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
Este código le da la cantidad de frecuencias que están por encima de un millón por área. De nuevo: optimice dichos números de acuerdo con sus imágenes de muestra.
Combina y optimiza estos métodos para tu conjunto de imágenes. Déjeme saber si puede mejorar esto, o simplemente edite esta respuesta, por favor. Me gustaría mejorarlo yo mismo :-)