Quiero recuperar el color de la mayoría en una imagen de fondo en .NET. ¿Es posible?¿Cómo obtener un color de mayoría en una imagen?
Respuesta
Puede recorrer todos los píxeles de la imagen y utilizar el método getPixel para determinar el valor RGB. A continuación, puede tener un diccionario que almacena el valor ARGB junto con un recuento. A continuación, puede ver qué valor ARGB está presente más en la imagen.
var list = new Dictionary<int, int>();
Bitmap myImage = (Bitmap)Bitmap.FromFile("C:/test.jpeg");
for (int x = 0; x < myImage.Width; x++)
{
for (int y = 0; y < myImage.Height; y++)
{
int rgb = myImage.GetPixel(x, y).ToArgb();
if (!list.ContainsKey(rgb))
list.Add(rgb, 1);
else
list[rgb]++;
}
}
Como se indicó, esto no simpatiza con colores similares. Si quisiera un color de mayoría más 'general', podría tener un umbral de similitud. p.ej. en lugar de:
if (!list.ContainsKey(rgb))
list.Add(rgb, 1);
else
list[rgb]++;
que podría hacer:
var added = false;
for (int i = 0; i < 10; i++)
{
if (list.ContainsKey(rgb+i))
{
list[rgb+i]++;
added = true;
break;
}
if (list.ContainsKey(rgb-i))
{
list[rgb-i]++;
added = true;
break;
}
}
if(!added)
list.Add(rgb, 1);
Se podría hasta el umbral de 10 a todo lo que sea necesario.
Si se trata de un jpeg de "color verdadero" ... podrían ser toneladas de valores en el diccionario con muy pocos recuentos por tecla. –
De acuerdo. Necesitarás algún tipo de agrupamiento o binning para trabajar decentemente. Con este podría tener 2 píxeles perfectamente rojos y una tonelada de variantes sutiles de negro y salir con el rojo como color de la mayoría. – RandomEngy
Bueno, técnicamente hablando, el rojo sería el color de la mayoría. – CeejeeB
También puede encontrar este desafío algoritmo de desbordamiento de pila útil:
Algorithm challenge: Generate color scheme from an image
Ten en cuenta también la creación de un histograma de la imagen - y tomando el color más elevada valorada como la 'mayoría de color': http://www.phpclasses.org/browse/file/15953.html
Suponiendo que usted caracteriza el color de cada píxel usando RGB (versus, por ejemplo, CMYK), podría construir una matriz en 3D (una dimensión cada una para R, G y B). Luego, decida el número de bandejas que desea tener en cada dimensión: mientras más bandejas, mayor será la diferenciación entre matices similares.
Una vez hecho esto, simplemente itere a través de una representación de mapa de bits de su imagen sumando los # píxeles que caen en cada una de las celdas en su matriz 3d. La celda con la suma más alta será el color predominante.
Es probable que desee que su algoritmo sea fácilmente configurable para las # bandejas en cada dimensión para que pueda ajustar cuánto discrimina entre colores similares.
image = new Bitmap("C:\\test.bmp", true);
int x, y;
// Loop through the images pixels to product 3d histogram
for(x=0; x<image.Width; x++)
{
for(y=0; y<image.Height; y++)
{
Color pixelColor = image.GetPixel(x, y);
// Increment color count in appropriate cell of your 3d histogram here
...
}
}
Esto devolverá el color promedio de la imagen.
static Color AverageColor(string fileName)
{
using (var bmp = new Bitmap(fileName))
{
int width = bmp.Width;
int height = bmp.Height;
int red = 0;
int green = 0;
int blue = 0;
int alpha = 0;
for (int x = 0; x < width; x++)
for (int y = 0; y < height; y++)
{
var pixel = bmp.GetPixel(x, y);
red += pixel.R;
green += pixel.G;
blue += pixel.B;
alpha += pixel.A;
}
Func<int, int> avg = c => c/(width * height);
red = avg(red);
green = avg(green);
blue = avg(blue);
alpha = avg(alpha);
var color = Color.FromArgb(alpha, red, green, blue);
return color;
}
}
No creo que el resultado califique como "color de la mayoría", ya que puede que no haya ni siquiera un píxel que tenga un color medio. – Kaniu
Muy cierto ... y es por eso que pedí más detalles en mi comentario bajo la pregunta. Sin respuesta, esta es mi entrada. –
Esto devolverá el color promedio de la imagen con el acceso inseguro al puntero. Nota: el código solo está adaptado para 24bppRgb, podría adaptarse para otros formatos de píxeles.
unsafe static Color GetColor(string filename)
{
using (var image = (Bitmap)Bitmap.FromFile(filename))
{
if (image.PixelFormat != PixelFormat.Format24bppRgb) throw new NotSupportedException(String.Format("Unsupported pixel format: {0}", image.PixelFormat));
var pixelSize = 3;
var bounds = new Rectangle(0, 0, image.Width, image.Height);
var data = image.LockBits(bounds, ImageLockMode.ReadOnly, image.PixelFormat);
long r = 0;
long g = 0;
long b = 0;
for (int y = 0; y < data.Height; ++y)
{
byte* row = (byte*)data.Scan0 + (y * data.Stride);
for (int x = 0; x < data.Width; ++x)
{
var pos = x * pixelSize;
b += row[pos];
g += row[pos + 1];
r += row[pos + 2];
}
}
r = r/(data.Width * data.Height);
g = g/(data.Width * data.Height);
b = b/(data.Width * data.Height);
image.UnlockBits(data);
return Color.FromArgb((int)r, (int)g, (int)b);
}
}
+1 por rendimiento. Llamar a GetPixel en cada píxel es extremadamente lento. – RandomEngy
Extremadamente lento es un poco exagerado. Pude usar el método GetPixel para analizar cuadros de video a 15 fps 800x600. Entonces, si el póster solo necesita analizar una sola imagen, GetPixel es más que adecuado. – CeejeeB
- 1. Obtener color de imagen
- 2. Cómo obtener una imagen en color en el iPhone SDK
- 3. Cómo teñir una imagen/mostrar un color?
- 4. CSS: cómo convertir una imagen en color a una imagen de color gris o negro/blanco
- 5. Java - Obtener una imagen de un JPanel
- 6. ¿Cómo obtener el color de coordenada x, y de un píxel de una imagen?
- 7. ¿Cómo obtener el color de un píxel en una UIView?
- 8. cómo agregar un color superponer sobre una imagen con CSS
- 9. Calcular el color promedio de un área en una imagen
- 10. Detectando una mancha de color en una imagen
- 11. Reemplazar un color en particular dentro de una imagen con otro color
- 12. Obtener el color promedio de la imagen mediante Javascript
- 13. ¿Cómo puedo cambiar el color de una imagen en Silverlight/WP7 (máscara de color)?
- 14. ¿Cómo obtener una Imagen Buffered desde un Componente en Java?
- 15. PHPExcel: Cómo obtener un CELL COLOR
- 16. ¿Es posible obtener el color de imagen promedio con RMagick?
- 17. ¿Cómo obtener el color promedio o principal de una imagen con javascript?
- 18. Cómo cambiar el color de una imagen usando jquery
- 19. ¿Cómo obtener metadatos de una imagen?
- 20. ¿Cómo puedo encontrar el color dominante de una imagen?
- 21. Efectivamente el ciclo de color de una imagen en Java
- 22. ¿Cómo rellenar la imagen de OpenCV con un solo color?
- 23. voltear y rotar una imagen en color en MATLAB
- 24. ¿Cómo obtener una imagen Bufferer desde un SVG?
- 25. ¿Cómo hacer clic en un enlace y obtener su color?
- 26. ¿Cómo obtener un InputStream desde una Imagen Buffered?
- 27. reemplazar el color en una imagen en C#
- 28. ¿Cómo coloco un borde alrededor de una imagen en WPF?
- 29. Obteniendo el color más común de una imagen
- 30. cómo obtener una ruta absoluta para una imagen en drupal?
¿Puede aclarar el significado de 'mayoría de color'? ¿Te refieres al color más utilizado en una imagen? el color promedio de una imagen; el valor "más alto" de color equivalente RGB? – Seidr
Probablemente necesites aclarar a qué te refieres con "color de la mayoría". Para la mayoría de las imágenes, es poco probable que un solo color constituya una mayoría apropiada. Supongo que te refieres al color más frecuente (píxel por píxel) o al componente dominante (ya sea R, G o B). – MusiGenesis
¿Necesita velocidad o precisión? ¿Desea también el color más utilizado, el color promedio o el color de tendencia? ¿Necesitas RGB mezclado o sperated? –