Bildpixel - Analyse - Programm

Neue Frage »

Auf diesen Beitrag antworten »
InformaTiger Bildpixel - Analyse - Programm

Hallo,
ich programmiere zur Zeit bzw. bin bereits damit fertig ein Bildpixel - Analyse - Programm zu schreiben. Dieses möchte ich in unterschiedlichen Programmen verwenden. Mein Problem dabei ist: es ist extrem rechenlastig/Zeit aufwändig und mein Programm hängt (manchmal) sich dabei solange auf bis es fertig berechnet hat.

Der Pixel-Analyse-Code:

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
using System;
using System.Drawing;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Test
{
    public class Bitmapfunctions
    {
        public Color[] GetPixelsFromBitmap(Bitmap b)
        {
            List<Color> pixels = new List<Color>();

            for (int i = 0; i < b.Size.Width; i++)
            {
                for (int j = 0; j < b.Size.Height; j++)
                {
                    pixels.Add(b.GetPixel(i, j));
                }
            }

            return pixels.ToArray();
        }

        public Color GetMostFrequentPixel(Bitmap b)
        {
            Color[] pixels = GetPixelsFromBitmap(b);
            Color[] compare = pixels.Distinct().ToArray();
            int[] count = new int[compare.Length];

            for (int i = 0; i < pixels.Length; i++)
            {
                for (int j = 0; j < compare.Length; j++)
                {
                    if (pixels[i] == compare[j])
                    {
                        count[j]++;
                        break;
                    }
                }
            }

            int max = count.Max();

            return compare[Array.IndexOf(count, max)];
        }

        public int FrequencyOfPixel(Bitmap b, Color c)
        {
            int result = 0;

            for (int i = 0; i < b.Size.Width; i++)
            {
                for (int j = 0; j < b.Size.Height; j++)
                {
                    if (b.GetPixel(i, j) == c)
                        result++;
                }
            }

            return result;
        }

        public bool IsPixelExisting(Bitmap b, Color c)
        {
            for (int i = 0; i < b.Size.Width; i++)
            {
                for (int j = 0; j < b.Size.Height; j++)
                {
                    if (b.GetPixel(i, j) == c)
                        return true;
                }
            }

            return false;
        }
    }
}



Was kann man hier optimieren, damit das ganze in einer akzeptablen Zeit abgeschlossen wird bzw. wie kann ich dem Benutzer besser mitteilen wie weit das Programm mit der Berechnung ist?

smile

Mfg
InformaTiger
 
Auf diesen Beitrag antworten »
Karlito

Hallo Informatiker,

- ArrayList mit richtiger größe verwenden, anstatt List
- Damit Benutzeroberfläche nicht einfriert: Threads verwenden.

Das ist das was mir bisher einfällt. Wenn ich heute Abend Zeit und Lust habe, versuche ich mich mal an einer optimierten Variante.

Edit: Für die Mostfrequentpixels eine HashMap<Color, Int> verwenden! Das sollte das Zählen wesentlich schneller machen!

VG,

Karlito
Auf diesen Beitrag antworten »
ed209

Hi,

Es gibt sicher etliche Ratschläge die man generell geben kann, um ein bisschen Performance herauszukrazen. Aber was ich an deiner Stelle erstmal machen würde, ist eine Übersicht zu bekommen welcher Teil deines Programms wieviel Zeit benötigt.
Es gibt Profiler-Programme dafür die dir das sagen, oder du schreibst einfach zu beginn jeder Methode eine kurze Routine, die die Zeit ausgibt.
Dann siehst du welche Teile wirklich lange dauern. Das kannst Du dann versuchen weiter einzugrenen.

Gruß,
ED
Auf diesen Beitrag antworten »
InformaTiger

Ok, ich habe mittlerweile heraus gefunden, dass der Teil mit dem ausgeben der Farben viel Zeit in Anspruch nimmt. Den habe ich jetzt einfach raus genommen. Der nächste Zeitfresser war das Listen von den ganzen Colors.
Und das mit dem Thread habe ich zurzeit mal mit dem Backgroundworker gelöst.

Was bringt aber im unterschied zu der List die ArrayList für Performance vorteile mit sich?

Mfg
InformaTiger
 
Auf diesen Beitrag antworten »
Karlito

Hallo InformaTiger,

die Vermutung, dass eine ArrayList oder nur ein Array besser ist als eine Liste, liegt in der Annahme, dass "List" eine verkettete Liste verwendet. Dazu müssen die Objekte, welche in die Liste aufgenommen werden sollen, in Listenelemente verpackt werden. Es wird sicher nicht allzu viel bringen, aber es sollte einen kleinen Vorteil geben. Miss es doch einfach mal.

VG,

Karlito
Auf diesen Beitrag antworten »
InformaTiger

OK, danke für deine Hilfe smile

Ich habe mittlerweile noch den Quelltext ein wenig angepasst.

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
using System;
using System.Drawing;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;

namespace Run_v3
{
    public class Bitmapfunctions
    {
        public Color[] GetPixelsFromBitmap(Bitmap b)
        {
            ArrayList pixels = new ArrayList();

            for (int i = 0; i < b.Size.Width; i++)
            {
                for (int j = 0; j < b.Size.Height; j++)
                {
                    pixels.Add(b.GetPixel(i, j));
                }
            }

            return pixels.ToArray(typeof(Color)) as Color[];
        }

        public Color GetMostFrequentPixel(Bitmap b, bool ignoreAlpha)
        {
            Color[] pixels = GetPixelsFromBitmap(b);
            Color[] compare = pixels.Distinct().ToArray();
            int[] count = new int[compare.Length];

            if (ignoreAlpha)
            {
                ArrayList temp = new ArrayList();
                for (int i = 0; i < pixels.Length; i++)
                {
                    if (pixels[i].A < 255)
                    {
                        continue;
                    }
                    temp.Add(pixels[i]);
                }
                pixels = temp.ToArray(typeof(Color)) as Color[];
            }

            for (int i = 0; i < pixels.Length; i++)
            {
                for (int j = 0; j < compare.Length; j++)
                {
                    if (pixels[i] == compare[j])
                    {
                        count[j]++;
                        break;
                    }
                }
            }

            int max = count.Max();

            return compare[Array.IndexOf(count, max)];
        }

        public int FrequencyOfPixel(Bitmap b, Color c)
        {
            int result = 0;

            for (int i = 0; i < b.Size.Width; i++)
            {
                for (int j = 0; j < b.Size.Height; j++)
                {
                    if (b.GetPixel(i, j) == c)
                        result++;
                }
            }

            return result;
        }

        public bool IsPixelExisting(Bitmap b, Color c)
        {
            for (int i = 0; i < b.Size.Width; i++)
            {
                for (int j = 0; j < b.Size.Height; j++)
                {
                    if (b.GetPixel(i, j).ToArgb() == c.ToArgb())
                        return true;
                }
            }

            return false;
        }
    }
}


Mfg
InformaTiger
 
Neue Frage »
Antworten »


Verwandte Themen

Die Beliebtesten »
Die Größten »
Die Neuesten »