segmentacion reconocimiento por objetos inteligencia imagenes geometricas figuras detectar deteccion como colores color artificial image algorithm colors

image - reconocimiento - segmentacion por color matlab



DesafĂ­o de algoritmo: generar esquema de color a partir de una imagen (11)

Fondo

Por lo tanto, estoy trabajando en una nueva iteración de una aplicación web. Y descubrimos que nuestros usuarios están obsesionados con ser flojos. Realmente flojo. De hecho, cuanto más trabajo hacemos por ellos, más aman el servicio. Una parte de la aplicación existente requiere que el usuario seleccione un esquema de color para usar. Sin embargo, tenemos una imagen (una captura de pantalla del sitio web del usuario), entonces ¿por qué no podemos simplemente saciar su pereza y hacerlo por ellos? Respuesta: ¡Podemos, y será un ejercicio de programación divertido! :)

El reto

Dada una imagen, ¿cómo se crea un esquema de color correspondiente? En otras palabras, ¿cómo se seleccionan los colores primarios de X en una imagen (donde X está definida por la aplicación web)? La imagen utilizada en nuestra situación particular es una captura de pantalla del sitio web del usuario, tomada a resolución completa (por ejemplo, 1280x1024). ( Nota: simplemente describa su algoritmo, no es necesario publicar el seudocódigo real).

Puntos de bonificación (puntos de crédito callejero, puntos SO no reales) para:

  • Describiendo un algoritmo que es simple pero efectivo. El código es cómo creamos, mantenlo simple y hermoso.
  • Permitir al usuario ajustar el esquema de color de acuerdo con varios "estados de ánimo" como "Colorido", "Brillante", "Silencio", "Profundo", etc. (a la Kuler )
  • Describiendo un método para determinar de manera confiable el color de texto principal utilizado en la captura de pantalla del sitio web (probablemente requerirá su propio, separado, algo).

Inspiración

Hay varios sitios existentes que realizan una función similar. Siéntase libre de revisarlos y pregúntese: "¿Cómo puedo duplicar esto? ¿Cómo podría mejorarlo?"


  1. Divida la imagen de la pantalla en una cuadrícula de r-muchos rectángulos, en una "cuadrícula" de n por m, cada uno con ancho (ancho total / n) y altura (altura total / m).

    1a. Asigne un peso a las áreas de alto perfil de la pantalla, como el área del centro izquierdo al descentrado.

    1b. Para cada rectángulo, asigne los píxeles a un espacio de ( color , frecuencia )

  2. Para cada rectángulo R, distribución de frecuencia f_R y peso W_R:

    2a. Determine el color del esquema i -ésimo (por ejemplo, i = 1 <-> color de fondo) escaneando la "frecuencia superior", "segunda frecuencia" ( es decir, f_R [ i ,:]) para cada bloque.

    2b. Para cada i , póngalo en una tabla de puntaje, ( color_i , puntaje ) donde puntaje = f_R [ i , "frecuencia"] * W_R

    2c. El máximo anotador para cada uno de ellos será el i -ésimo color del esquema.

Teóricamente, si tiene una gran cantidad de "azul sobre blanco" o "rojo sobre negro", debe obtener blanco primario, azul secundario o negro primario, rojo secundario, por ejemplo.

Para el color del texto, base esto directamente en un cálculo sin color de fondo, o elige color secundario, y si la diferencia V de HSV es demasiado baja, basa el color fuera del color del esquema calculado, pero aumenta el valor V.

PseudoCódigo:

float[][] weights = { { 1.0, 3.0, 5.0, 5.0, 3.0, 1.0, 1.0, 1.0, 1.0 }, { 2.0, 6.0, 7.0, 7.0, 6.0, 2.0, 3.0, 3.0, 2.0 }, { 2.0, 8.0, 9.0, 9.0, 7.0, 3.0, 6.0, 6.0, 3.0 }, { 2.0, 8.0, 9.0, 9.0, 7.0, 2.0, 3.0, 3.0, 2.0 }, { 2.0, 7.0, 9.0, 9.0, 7.0, 2.0, 1.0, 1.0, 1.0 }, { 2.0, 6.0, 7.0, 7.0, 6.0, 2.0, 3.0, 3.0, 1.0 }, { 1.0, 3.0, 5.0, 5.0, 3.0, 2.0, 6.0, 6.0, 2.0 }, { 1.0, 1.0, 2.0, 2.0, 1.0, 2.0, 6.0, 6.0, 2.0 }, { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 3.0, 3.0, 1.0 } }; // Leave the following implementations to the imagination: void DivideImageIntoRegions( Image originalImage, out Image[][] regions ); void GetNthMostCommonColorInRegion( Image region, int n, out Color color ); TKey FindMaximum<TKey, TValue>( Map<TKey, TValue> map ); // The method: Color[] GetPrimaryScheme( Image image, int ncolors, int M = 9, int N = 9 ) { Color[] scheme = new Color[ncolors]; Image[][] regions = new Image[M][N]; DivideImageIntoRegions( image, regions ); for( int i = 0; i < ncolors; i++ ) { Map<Color, float> colorScores = new Map<Color, float>(); for( int m = 0; m < M; m++ ) for( int n = 0; n < N; n++ ) { Color theColor; GetNthMostCommonColorInRegion( region, i, theColor ); if( colorScores[theColor] == null ) { colorScores[theColor] = 0; } colorScores[theColor] += weights[m][n]; } scheme[i] = FindMaximum( colorScores ); } return scheme; }

En cuanto a lo anterior, está claro que si hay una región con poca variabilidad, tendrá el mismo segundo color más común que el color más común. Para ajustar, el segundo color más común en un caso así podría ser nulo, contra lo que uno podría precaverse:

if( theColor != null ) continue; if( colorScores[theColor] == null ) { colorScores[theColor] = 0; } colorScores[theColor] += weights[m][n]; }


  1. Para encontrar los colores X principales, screencap la aplicación. Ejecute un histograma de color en la imagen. Los principales X colores en el histograma son el tema. Editar: si se usan degradados, querrá elegir distintos "picos" de colores; es decir, puede tener un montón de colores alrededor de "naranja" si el naranja es uno de los colores principales utilizados en los degradados. Efectivamente, solo imponga una cierta cantidad de distancia entre los colores elegidos del histograma.

  2. Ajustar el esquema de color se puede hacer mejor en el espacio HSV; convierta sus colores al espacio HSV, y si los usuarios quieren que sea "Más brillante", aumente el valor, si quieren que sea más "colorido", aumente la saturación, etc.

  3. La mejor forma de determinar el color del texto es caracterizando las áreas de alta variabilidad (alta frecuencia en el espacio de Fourier). Dentro de esas áreas, debe tener: dos colores, texto y fondo, en cuyo caso su texto es el color menos utilizado; o tendrá varios colores, texto y colores de fondo, en cuyo caso el color del texto es el color más común.


A continuación se incluyen algunas sugerencias y discusiones sobre diferentes enfoques para generar un esquema de color a partir de una imagen:

Primero, inserta / traza tus píxeles en algún espacio de color. Esto puede ser RGB, HSL o algún otro espacio de color. Luego puede usar uno de los siguientes para generar un esquema de color:

  1. Crear un histograma del espacio de color : esto implica dividir el espacio en una cuadrícula y contar los píxeles en cada celda de la cuadrícula. Seleccione las N celdas superiores (cubos de histograma) con la mayoría de los píxeles y promedie los píxeles en cada uno para producir un color por celda. Este puede ser tu esquema de color.

  2. Mediana de corte o alguna otra técnica de partición espacial: esta es una buena mejora sobre el n. ° 1, ya que dividirá el espacio al observar los datos.

  3. Clustering Pixels - Agrupe los píxeles en grupos utilizando una de las muchas técnicas de agrupamiento (k-means, mean-shift, etc.). Luego promedie los píxeles en cada grupo para generar un esquema de color.

Escribí una publicación más detallada sobre los tres enfoques anteriores here

También escribí una aplicación web interactiva que le permite cargar una imagen y crear generar una paleta de colores usando uno de los tres enfoques anteriores. Puedes encontrar el código para ello en github


Al igual que la solución de McWafflestix, los detalles deberán ser modificados, pero mi enfoque general sería ...

(Estoy de acuerdo en que HSV es el espacio correcto)

  1. Tome un histograma de la imagen, fíltrela para suavizar el ruido y encuentre la puntuación más alta donde V y S se encuentran en una gama (posiblemente dinámica) de posibles colores "sujetos". Un pájaro rojo en un cielo azul requerirá que seamos lo suficientemente inteligentes como para no basar nuestro esquema en el azul, pero en el rojo. Esto puede requerir algunas suposiciones sobre la composición de la foto, como "centrado en el marco" y el análisis de la "regla de los terceros" podría darle una probabilidad de que un color sea relevante. De todos modos, este es nuestro el color base.

  2. A lo largo de las líneas de Kuler, calcula los colores que complementan la base moviéndose alrededor de la rueda de colores. Puntos extra para un cumplido calculado si también apareció prominentemente en el histograma del paso 1.

  3. Use el color base y los cumplidos calculados para obtener colores adjuntos agradables, como versiones más claras y oscuras de cada uno, más o menos saturadas, etc.



Hago esto para encontrar la paleta utilizada para las imágenes (de obras de arte).

  1. Empiezo con imagemagick y cambio el tamaño de una imagen grande a un tamaño realizable (es decir, 400 px en la dimensión más grande). De hecho, esto ayuda a convertir diferencias sutiles de color local en menos píxeles con un promedio de esos colores.

  2. Haga un bucle a través de cada píxel presente en la imagen redimensionada, leyendo los valores RGB para cada píxel, convierta el RGB a HSB y almacene los valores HSB en una matriz.

  3. Para cada color de píxel encontrado, luego divido el rango Hue (0,255) por 16, el rango Saturación (0,100) por 10 y el rango de Brillo (0,100) por 10. Redondee el resultado hacia arriba o hacia abajo a un número entero. Esto ayuda a agrupar píxeles en categorías de colores similares.

    Entonces, un píxel con HSB de 223,64,76 estaría en la categoría 14,6,8

    Dentro de cada categoría, aún puede encontrar el color exacto de cada píxel, pero en su mayor parte las categorías mismas son una coincidencia de color cercana a la imagen de origen.

    Elija dividir el HSB en divisiones más finas si desea una mejor replicación del color de las categorías. es decir. divide cada H, S, B por 8,5,5 en lugar de 16,10,10.

  4. Cuente las categorías de color más prevalentes, clasifique y muestre. Descarto categorías de color con muy pocos conteos de píxeles.

Nota: Esto está diseñado para ilustraciones que tienen muy pocos píxeles con valores de color idénticos (es decir, pinturas con sombras y degradados).

En su mayor parte, una página HTML probablemente tiene más píxeles que coinciden exactamente con un valor de color específico (es decir, el color de fondo, el color del texto, etc. van a tener el mismo color donde aparezcan).


Llego un poco tarde a esto, pero implementaría un Mapa Kohonen (http://en.wikipedia.org/wiki/Self-organizing_map) en un espacio de color 3D. El número de puntos en el mapa sería el número de colores distintos que desea para su paleta, luego entrene su mapa usando todos los píxeles de la imagen. No lo he intentado yo mismo, pero estoy seguro de que alguien más ya lo ha pensado.


Promedie el tono, la saturación y el brillo por separado, manteniendo los valores mínimos / máximos.

Bloquee el matiz objetivo de todos los colores al promedio e interpole la saturación y el brillo para los puntos x entre los límites. Esto debería devolver un esquema con un modelo de color igual al de la foto pero con una variación simple. Tal vez incluso obtendrás el aspecto de Apple.

Solo espero que no tengas 3 tonos de vomito de perro.



Ya hay muchas buenas sugerencias sobre cómo encontrar los colores primarios y probaré enfoques similares. Para encontrar el color del texto, tengo otra sugerencia.

Calcule el histograma para cada línea en la imagen de arriba a abajo. Cada vez que llegue a la línea de base de una línea, debería haber una fuerte caída en la frecuencia del color del texto. La frecuencia permanecerá baja hasta que llegue a las letras mayúsculas de la línea siguiente y un segundo paso cuando llegue a las letras minúsculas.

Si hay otro pico fuerte que se vuelve aún más grande cuando alcanzas la línea de base, has encontrado el color de fondo. Un fondo degradado suavizará este pico y los cambios de los picos, cuando ingrese o salga de una nueva línea, se suavizarán mediante antialiasing.


La cuantización del color es el mismo proceso utilizado para elegir la paleta para GIF de bajo color. Para obtener una paleta de colores a partir de una imagen fotográfica, utilicé Quantize.js de Nick Rabinowitz, que se basa en el MMCQ de Leptonica (cuantificación de corte mediana modificada).

Aplicación web en vivo , about .