Hallo,
ich arbeite immer noch an Bildverarbeitung. Das was ich im letzten Threads besprochen hatte, Hardwarebeschleunigung, habe ich jetzt mal verworfen, da ich nicht mit WPF arbeiten möchte und das mit Bitmaps nicht ganz so geht, an OpenGL etc. wollte ich mich jetzt auch noch nicht trauen, geht bisher nur um Lernzwecke. Dennoch möchte ich eine Methode haben, mit der sich gut und schnell arbeiten lässt.
Bisher hatte ich Unsafe-Code und LockBits in einer Klasse, so wie hier in etwa: github.com/LuizZak/FastBitmap/…/FastBitmap/FastBitmap.cs
Aber ich möchte das ein bisschen ausweiten - mehrere Farbräume zum Beispiel - deshalb habe ich bisschen bei MATLAB und OpenCV geschaut und dort wird mit mehrdimensionalen Matrizen und Vektoren gearbeitet als "Farben". Das macht bei mir glaube ich nicht ganz so viel Sinn, da ich ja gezwungenermaßen mit LockBits arbeiten muss und da habe ich ja schon einen schönen Byte-Array mit Pointer und das dann noch jedes mal umzurechnen verschwendet glaube ich zu viel Rechenleistung. Allgemein ist mein Problem aber, dass ich nicht weiß was besser/schnell ist von folgenden Varianten:
Vorab: Es gibt 3 Strukturen; BGR, HSV und Gray mit jeweils 3 und 1 Byte und mehreren nützlichen Funktionen.
1. Für jeden Farbraum eine unsafe FastBitmap-Klasse, wobei der Array umgerechnet wird auf den jeweiligen Farbraum z.B. GrayScale hat dann nur noch ein Byte pro Pixel. GetPixel und SetPixel geben dann eine Structure "Gray" zurück. Dabei kann ich einfach
2. Eine generische unsafe Klasse BitmapContainer, welche je nach eingegebener Struktur eine Struktur zurück gibt. Hierbei würde GetPixel und SetPixel auch mit Strukturen arbeiten, jedoch haben wir eine Vereinheitlichung. Das Problem ist, dass Unsafe-Code generische Typen nicht mag, sprich funktioniert nicht, deshalb muss ich mit Marshal arbeiten und ich weiß nicht inwiefern das langsamer ist oder vielleicht auch schneller, wie sind eure Erfahrungen dort? Code:
Wiederrum ist es glaube ich nicht sonderlich gut dauernd mit Structurs zu arbeiten.
3. Eine unsafe Klasse BitmapContainer, welche mit Byte-Arrays arbeitet als Farben. Da sehen Get und Set dann so aus: (wobei colorsize = Größe der Farbe)
Ich weiß hier wieder nicht ob Marshal-Copy nicht doch schneller wäre. Außerdem habe ich einen Memory-Leak, wenn ich die Funktion GetPixel aufrufe.
Also vielleicht könnt ihr mir da weiterhelfen, eine der Methoden auszusuchen und/oder zu verbessern oder eine bessere vorzuschlagen, ich sitze schon ziemlich lang daran
EDIT: Bin gerade noch auf die Idee gekommen, wenn dann mit einem float Array zu arbeiten, weil ja nicht alle Farbenräume Integer-Werte haben. Bilder in einem anderen Farbraum, also umgekrempelter Array, werden am Ende wieder zu einem RGB-Bild zusammengestückelt, da machen Matrizen eventuell doch Sinn Man merkt, ich verzweifel.
ich arbeite immer noch an Bildverarbeitung. Das was ich im letzten Threads besprochen hatte, Hardwarebeschleunigung, habe ich jetzt mal verworfen, da ich nicht mit WPF arbeiten möchte und das mit Bitmaps nicht ganz so geht, an OpenGL etc. wollte ich mich jetzt auch noch nicht trauen, geht bisher nur um Lernzwecke. Dennoch möchte ich eine Methode haben, mit der sich gut und schnell arbeiten lässt.
Bisher hatte ich Unsafe-Code und LockBits in einer Klasse, so wie hier in etwa: github.com/LuizZak/FastBitmap/…/FastBitmap/FastBitmap.cs
Aber ich möchte das ein bisschen ausweiten - mehrere Farbräume zum Beispiel - deshalb habe ich bisschen bei MATLAB und OpenCV geschaut und dort wird mit mehrdimensionalen Matrizen und Vektoren gearbeitet als "Farben". Das macht bei mir glaube ich nicht ganz so viel Sinn, da ich ja gezwungenermaßen mit LockBits arbeiten muss und da habe ich ja schon einen schönen Byte-Array mit Pointer und das dann noch jedes mal umzurechnen verschwendet glaube ich zu viel Rechenleistung. Allgemein ist mein Problem aber, dass ich nicht weiß was besser/schnell ist von folgenden Varianten:
Vorab: Es gibt 3 Strukturen; BGR, HSV und Gray mit jeweils 3 und 1 Byte und mehreren nützlichen Funktionen.
1. Für jeden Farbraum eine unsafe FastBitmap-Klasse, wobei der Array umgerechnet wird auf den jeweiligen Farbraum z.B. GrayScale hat dann nur noch ein Byte pro Pixel. GetPixel und SetPixel geben dann eine Structure "Gray" zurück. Dabei kann ich einfach
*(Gray*)(ptr + X * sizeof(Gray) + Y * Stride)
machen. Jedoch ist es unpraktisch mehrere Klassen zu haben, vor allem, wenn man eigene Farbräume hat mit nur 2 Byte z.B. könnte man nicht damit arbeiten. Auch ist es langsam, dauernd Structures zu erstellen.2. Eine generische unsafe Klasse BitmapContainer, welche je nach eingegebener Struktur eine Struktur zurück gibt. Hierbei würde GetPixel und SetPixel auch mit Strukturen arbeiten, jedoch haben wir eine Vereinheitlichung. Das Problem ist, dass Unsafe-Code generische Typen nicht mag, sprich funktioniert nicht, deshalb muss ich mit Marshal arbeiten und ich weiß nicht inwiefern das langsamer ist oder vielleicht auch schneller, wie sind eure Erfahrungen dort? Code:
Wiederrum ist es glaube ich nicht sonderlich gut dauernd mit Structurs zu arbeiten.
3. Eine unsafe Klasse BitmapContainer, welche mit Byte-Arrays arbeitet als Farben. Da sehen Get und Set dann so aus: (wobei colorsize = Größe der Farbe)
C#-Quellcode
- public byte[] GetPixel(int X, int Y)
- {
- byte[] color = new byte[colorsize];
- if (X >= 0 && X < Width && Y >= 0 && Y < Height)
- {
- for (int i = 0; i < colorsize; i++) color[i] = *(ptr + Y * stride + X * colorsize + i);
- return color;
- }
- return color;
- }
- public void SetPixel(int X, int Y, byte[] Color)
- {
- if (X >= 0 && X < Width && Y >= 0 && Y < Height)
- {
- for (int i = 0; i < colorsize; i++) *(ptr + Y * stride + X * colorsize + i) = Color[i];
- }
- }
Ich weiß hier wieder nicht ob Marshal-Copy nicht doch schneller wäre. Außerdem habe ich einen Memory-Leak, wenn ich die Funktion GetPixel aufrufe.
Also vielleicht könnt ihr mir da weiterhelfen, eine der Methoden auszusuchen und/oder zu verbessern oder eine bessere vorzuschlagen, ich sitze schon ziemlich lang daran
EDIT: Bin gerade noch auf die Idee gekommen, wenn dann mit einem float Array zu arbeiten, weil ja nicht alle Farbenräume Integer-Werte haben. Bilder in einem anderen Farbraum, also umgekrempelter Array, werden am Ende wieder zu einem RGB-Bild zusammengestückelt, da machen Matrizen eventuell doch Sinn Man merkt, ich verzweifel.
Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „xd-franky-5“ ()