Hallo,
Ich will in einem Bild (farbig) die höchst vorkommende Farbe finden.
Muss ich das Bild in anderes Format umwandeln ? oder ?
Ich habe .jpg Format.
Wenn man ein Graubild hat, ist das nicht schwer, die im Bild meist vorkommeder Farbe zu finden.
definiert man einen Array
int Farbe[255]
z.B. Wenn im Graubild ein Farbton 122 kommt
Farbe[122]=Farbe[122]+1
im Farbbild ist anders. Man hat drei Dimensionen.
Deswegen soll man einen drei dimensionalen Array.
wollte wissen, ob es bessere Losüng gibt ?
danke
ok du willst also die am häufigsten vorkommende farbe feststellen. da legst du dir am besten ein dictionary an und gehst das bild pixel für pixel durch. wenn du dann eine farbe triffst, die noch nicht im dictionary ist, speicherst du die farbe im key und trägst als value 1 ein, anderenfalls erhöhst du nur den value um 1.
zuletzt gehst du nur noch das komplette dictionary durch und holst dir den key mit dem größten value.
evtl wäre es vorteilhaft vorher in ein bmp zu konvertieren aber das kann ich nciht mit gewissheit sagen.
was dir sicher hilft:
[GetPixel und SetPixel um Längen geschlagen. 800 mal schneller ](http://www.mycsharp.de/wbb2/thread.php?threadid=29667)
funktioniert aber sehr langsam. (mehr als 1 Minute)
woran kann es liegen ?
danke
private void maxFarbeFinden()
{
long pixelColor,key;
Dictionary<long,int > farbenList=new Dictionary<long,int>();
long index,farbe;
Boolean hatWert;
int i,j,wert;
wert = 0;
key = 0;
for (i = 0; i < bildWidth - 1; i++)
for (j = 0; j < bildHeight -1; j++)
{
pixelColor = bild.GetPixel(i, j).ToArgb();
hatWert = false;
foreach (KeyValuePair<long, int> item in farbenList)
{
if (item.Key==pixelColor)
{
//item.Value = item.Value + 1;
key = pixelColor;
wert = item.Value;
hatWert = true;
}
}
if (hatWert == false)
{
farbenList.Add(pixelColor, 1);
}
else
{
farbenList.Remove(key);
farbenList.Add(key,wert + 1);
}
}
}
benutz doch bitte die [C(das nicht mitnehmen)SHARP] dinger, ja? Steht auch irgendwo in den Regeln.
Achtung. Nur auf die schnelle, ungetestet ...
private void maxFarbeFinden()
{
Dictionary<Int64,int > farbenList=new Dictionary<Int64,int>();
for (int i = 0; i < bildWidth - 1; i++)
for (int j = 0; j < bildHeight -1; j++)
{
// Sollte noch gegen die schnellere Methode getauscht werden !!!
Int64 pixelColor = bild.GetPixel(i, j).ToArgb();
Int64 Dummy;
if (fabenList.TryGetValue(pixelColor, Dummy))
farbenList[pixelColor] = 1;
else
farbenList[pixelColor] += 1;
}
}
**"Zufall ist das Pseudonym Gottes, wenn er nicht selbst unterschreiben will.” **
Anatole France
// Sollte noch gegen die schnellere Methode getauscht werden !!!
er meint das: GetPixel und SetPixel um Längen geschlagen. 800 mal schneller
danke. läuft jett schneller
int Dummy;
if (!(farbenList.TryGetValue(pixelColor, out Dummy)))
farbenList[pixelColor] = 1;
else
{
farbenList[pixelColor] += 1;
if (farbenList[pixelColor] > maxWert)
{
maxWert = farbenList[pixelColor];
maxFarbe = pixelColor;
}
}
}
danke. läuft jett schneller
if (farbenList[pixelColor] > maxWert) { maxWert = farbenList[pixelColor]; maxFarbe = pixelColor; }
Wofür soll das an der Stelle gut sein 🤔
Da entstehen wieder unnötig viele Abfragen.
Mach doch NACH dem kompletten Erfassen des Bildes einem
separaten Durchlauf
ungestestet
int maxWert = 0;
foreach (var PixelFarbe in farbenList)
if PixelFarbe.Value > maxWert
maxWert = PixelFarbe.Value
um den Maximalwert zu ermitteln. Dann wird jeder Datensatz nur einmal angefasst.
(Falls du nicht mit .net 3.5 arbeitest, musst du "var" noch durch "KeyValuePair<Int64, int>" ersetzen.
mfg Hajoseb
**"Zufall ist das Pseudonym Gottes, wenn er nicht selbst unterschreiben will.” **
Anatole France