Ich möchte die Mehrheit Farbe in einem Hintergrundbild in .NET abrufen. Ist es möglich?Wie erhält man eine Mehrheitsfarbe in einem Bild?
Antwort
Sie können alle Pixel im Bild durchlaufen und mithilfe der getPixel-Methode den RGB-Wert ermitteln. Sie können dann ein Wörterbuch haben, das den ARGB-Wert zusammen mit einer Zählung speichert. Sie können dann sehen, welcher ARGB-Wert am meisten im Bild vorhanden ist.
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]++;
}
}
Wie bereits erwähnt, hat dies keine Sympathie für ähnliche Farben. Wenn Sie eine mehr generelle Farbe wünschen, können Sie einen Schwellenwert für Ähnlichkeit haben. z.B. statt:
if (!list.ContainsKey(rgb))
list.Add(rgb, 1);
else
list[rgb]++;
könnten Sie tun:
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);
Sie könnten die Schwelle von 10, was auch immer Sie benötigt werden.
Wenn dies eine "echte Farbe" JPEG ist ... das könnte Tonnen von Werten im Wörterbuch mit sehr wenigen Zählimpulsen pro Schlüssel sein. –
Einverstanden. Sie benötigen eine Art Binning oder Gruppierung, um anständig zu arbeiten. Mit diesem könnte man 2 perfekt rote Pixel und eine Tonne subtile Varianten von Schwarz haben und mit Rot als Hauptfarbe herauskommen. – RandomEngy
Technisch gesehen wäre Rot dann die Hauptfarbe. – CeejeeB
Sie können auch diese Algorithmus Herausforderung auf Stack-Überlauf nützlich finden:
Algorithm challenge: Generate color scheme from an image
Sehen Sie sich auch ein Histogramm des Bildes zu schaffen - und unter der höchsten Wert Farbe wie die ‚Mehrheit Farbe‘: http://www.phpclasses.org/browse/file/15953.html
Angenommen, Sie charakterisieren die Farbe jedes Pixels mit RGB (im Gegensatz zu, sagen wir CMYK), könnten Sie ein 3D-Array (jeweils eine Dimension für R, G und B) bauen. Entscheiden Sie sich dann für die Anzahl der Fächer, die Sie in jeder Dimension haben möchten - je mehr Fächer, desto größer ist die Differenzierung zwischen ähnlichen Farbtönen.
Sobald das erledigt ist, durchlaufen Sie einfach eine Bitmap-Darstellung Ihres Bildes summieren die # Pixel, die in jede der Zellen in Ihrem 3D-Array fällt. Die Zelle mit der höchsten Summe wird die vorherrschende Farbe sein.
Wahrscheinlich möchten Sie Ihren Algorithmus für die # Bins in jeder Dimension leicht konfigurierbar machen, damit Sie einstellen können, wie stark er zwischen ähnlichen Farben unterscheidet.
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
...
}
}
Dies wird die durchschnittliche Farbe für das Bild zurück.
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;
}
}
Ich glaube nicht, dass das Ergebnis als "Mehrheitsfarbe" gilt, da es nicht einmal ein Pixel gibt, das eine durchschnittliche Farbe hat. – Kaniu
Sehr wahr ... und deshalb fragte ich in meinem Kommentar unter der Frage nach mehr Details. Keine Antwort, das ist mein Eintrag. –
Dies wird die durchschnittliche Farbe für das Bild mit unsicheren Zeiger Zugriff zurückgeben. Hinweis: Code ist nur für 24bppRgb angepasst, könnte für andere Pixelformate angepasst werden.
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 für die Leistung. Der Aufruf von GetPixel auf jedem einzelnen Pixel ist extrem langsam. – RandomEngy
Extrem langsam ist ein bisschen übertrieben. Ich konnte die GetPixel-Methode verwenden, um Videoframes mit 15fps 800x600 zu analysieren. Wenn das Poster also nur ein einzelnes Bild analysieren muss, ist GetPixel mehr als ausreichend. – CeejeeB
- 1. Wie erhält man Zeichenkoordinaten in einem Textblock?
- 2. Wie erhält man eine Kindprozessspeicherung in node.js?
- 3. Wie erhält man eine ALAsset-URL von einem PHAsset?
- 4. Wie erhält man eine Ressourcen-ID mit einem bekannten Ressourcennamen?
- 5. Wie erhält man Parameternamen aus einem Ausdrucksbaum?
- 6. Wie erkennt man eine Laserlinie in einem Bild mit Python?
- 7. TkInter: Wie erhält man eine tatsächliche Textänderung?
- 8. Wie man Bild mit seinem Namen und irgendeiner Erweiterung erhält?
- 9. Wie erhält man eine Aggregation nach Typ?
- 10. Wie erhält man Schriftgrößen?
- 11. Wie ersetzt man eine Kontur (Rechteck) in einem Bild mit einem neuen Bild mit Python?
- 12. Wie erhält man den Kategorietitel in einem Beitrag in Wordpress?
- 13. Wie erhält man den Index eines Elements in einem Array?
- 14. Wie man Werte von einem Dialogformular in VB.NET erhält?
- 15. Wie erhält man mehrere Namen in einem jQuery-Elementselektor?
- 16. Wie erhält man Benutzerrollen in einem JSP/Servlet?
- 17. wie man Artikelfrequenz in einem R Datenrahmen hintereinander erhält?
- 18. Matlab: Wie erhält man alle Achsengriffe in einem Zahlenpunkt?
- 19. Wie erhält man alle Klassennamen in einem Paket?
- 20. Wie man relative Ergänzung eines data.frames in einem anderen erhält?
- 21. Wie erhält man die Art von Elementen in einem Container?
- 22. Wie erhält man Werte aus einem mehrdimensionalen Array in Twig?
- 23. Wie erhält man einen Wert aus einem Datenrahmen in Pandas?
- 24. Wie erhält man den Index eines Artikels in einem Array?
- 25. Wie erhält man eine Schätzung aus der Regression in Excel?
- 26. Wie man div erhält, um oben auf einem Bild zu übertragen?
- 27. Wie erhält man fortlaufende Zeichen in C#?
- 28. Wie erhält man eine Zeichenfolge aus geöffneter Gruppenansicht in ExpandableListView?
- 29. Wie erhält man eine Anzahl von Zeilen in einem Datenspeichermodell in Google Appengine?
- 30. Wie erhält man den Objektnamen?
Können Sie die Bedeutung von 'Mehrheit Farbe' klären? Meinst du die Farbe, die am häufigsten in einem Bild verwendet wird? die durchschnittliche Farbe eines Bildes; der 'höchste' Farbäquivalent RGB? – Seidr
Sie müssen wahrscheinlich klären, was Sie mit "Mehrheitsfarbe" meinen. Bei den meisten Bildern ist es unwahrscheinlich, dass eine Farbe eine richtige Mehrheit darstellt. Ich nehme an, Sie meinen entweder die häufigste Farbe (Pixel für Pixel) oder die dominierende Komponente (entweder R, G oder B). – MusiGenesis
Benötigen Sie Geschwindigkeit oder Genauigkeit? Möchten Sie auch die am häufigsten verwendete Farbe, durchschnittliche Farbe oder Trendfarbe? Brauchen Sie RGB gemischt oder speriert? –