myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
   » Plugin für Firefox
   » Plugin für IE
   » Gadget für Windows
» Regeln
» Wie poste ich richtig?
» Datenschutzerklärung
» wbb-FAQ

Mitglieder
» Liste / Suche
» Stadt / Anleitung dazu
» Wer ist wo online?

Angebote
» ASP.NET Webspace
» Bücher
» Zeitschriften
   » dot.net magazin

Ressourcen
» guide to C#
» openbook: Visual C#
» openbook: OO
» MSDN Webcasts
» Search.Net

Team
» Kontakt
» Übersicht
» Wir über uns
» Impressum

» Unsere MiniCity
MiniCity
» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Entwicklung » Grafik und Sound » Schnelle Konvertierung von Grayscale zu RGB (WPF)
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

Schnelle Konvertierung von Grayscale zu RGB (WPF)

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
robbb26
myCSharp.de-Mitglied

Dabei seit: 09.08.2017
Beiträge: 6
Entwicklungsumgebung: Visual Studio 2010-2017


robbb26 ist offline

Schnelle Konvertierung von Grayscale zu RGB (WPF)

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo liebe Gemeinde,

ich arbeite momentan an einem Projekt von meiner Arbeit aus, bei dem ich ein 8-Bit Graustufenbild in ein 24-Bit RGB umwandeln muss, um es "künstlich" blau oder grün einzufärben.
Da ich das Bild von der Kamera als byte-Pixel-Array zurück bekomme war mein bisheriger Ansatz ein 3x so langes byte-Array anzulegen und den Grauwert über eine Schleife an die jeweilige Stelle (grün/blau) einzutragen, daraus eine BitmapSource zu erzeugen und es anschließend als Image auf der GUI anzuzeigen.

Es geht jetzt vor allem um den Live-View, also das schnelle hintereinander grabben der Bilder. Ein Bild ist 1920x1200 Pixel x 3-Bit pro Pixel. In einer Schleife dauert das auf der Zielplattform zu lang (10fps).

Gibt es einen schnellen und ressourcensparenden Ansatz, den ich weiter verfolgen könnte?

Grüße und danke schon mal im Voraus.
10.08.2017 11:52 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
LaTino LaTino ist männlich
myCSharp.de-Poweruser/ Experte

images/avatars/avatar-1871.jpg


Dabei seit: 03.04.2006
Beiträge: 2.690
Entwicklungsumgebung: VS 2008 / VS 2017 / VS Code
Herkunft: Thüringen


LaTino ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Das erklärt noch nicht, wozu du ein 24Bit-Bild brauchst. Was hindert dich denn, mit Graustufen zu arbeiten, anstatt das umständlich umzurechnen?

LaTino
10.08.2017 12:32 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
robbb26
myCSharp.de-Mitglied

Dabei seit: 09.08.2017
Beiträge: 6
Entwicklungsumgebung: Visual Studio 2010-2017

Themenstarter Thema begonnen von robbb26

robbb26 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Naja wie gesagt, das Live-Bild soll ja dann eingefärbt sein, statt in Graustufen angezeigt zu werden.
Hab im Anhang mal Beispielbilder, einmal Graustufen (so wie es von der Kamera kommt) und einmal grün gefärbt (so wie es am Ende angezeigt werden soll).


Dateianhang:
rar hep2.rar (32,29 KB, 14 mal heruntergeladen)
10.08.2017 12:50 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Taipi88 Taipi88 ist männlich
myCSharp.de-Mitglied

images/avatars/avatar-3220.jpg


Dabei seit: 02.02.2010
Beiträge: 620
Entwicklungsumgebung: VS 2010
Herkunft: Mainz


Taipi88 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hi,

mal für den Fall, dass du wirklich 24bpp brauchen solltest - was genau dauert denn eigentlich zu lange? Sicher die Konvertierung?

Falls dem so wäre - probier mal AForge.Imaging - damit geht GrayScale to 24bpp-RGB (ohne Coloring) so:

C#-Code:
var filter = new GrayscaleToRGB();
var rgb = filter.Apply(img);

Alternativ kannst du auch direkt mal folgendes Beispiel anschauen:
 https://gist.github.com/xinmyname/1602389

LG
10.08.2017 12:59 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
robbb26
myCSharp.de-Mitglied

Dabei seit: 09.08.2017
Beiträge: 6
Entwicklungsumgebung: Visual Studio 2010-2017

Themenstarter Thema begonnen von robbb26

robbb26 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Der Tipp ist gut, aber das habe ich schon probiert großes Grinsen
Problem dabei ist, dass die Funktion nur ein Bitmap frisst und ich von der Kamera aber ein byte[] zurück bekomme (und ich unter WPF arbeite und da ja "eigentlich" kein Bitmap verfügbar ist).

Achso und ja die Konvertierung ist der Zeitfresser

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von robbb26 am 10.08.2017 14:10.

10.08.2017 14:09 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

images/avatars/avatar-2981.png


Dabei seit: 20.07.2008
Beiträge: 10.278
Herkunft: Süddeutschland


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Bitte verwende kein Rar/Zip-Upload bei nur zwei Bilder.
Beachte bitte  [Hinweis] Wie poste ich richtig? Punkt 6.1
10.08.2017 14:16 Beiträge des Benutzers | zu Buddylist hinzufügen
MrSparkle MrSparkle ist männlich
myCSharp.de-Team

images/avatars/avatar-2159.gif


Dabei seit: 16.05.2006
Beiträge: 4.657
Herkunft: Leipzig


MrSparkle ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hi robbb26,

bitte nimm dir erstmal die Zeit und einen Profiler, um das Problem genauer einzugrenzen, und diese Frage zu beantworten:

Zitat von Taipi88:
mal für den Fall, dass du wirklich 24bpp brauchen solltest - was genau dauert denn eigentlich zu lange? Sicher die Konvertierung?

Wir wissen ja nicht, was genau bei dir zu lange dauert, und können daher auch nur raten.
10.08.2017 15:44 Beiträge des Benutzers | zu Buddylist hinzufügen
robbb26
myCSharp.de-Mitglied

Dabei seit: 09.08.2017
Beiträge: 6
Entwicklungsumgebung: Visual Studio 2010-2017

Themenstarter Thema begonnen von robbb26

robbb26 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

So nochmal von vorn:

Von der Kamera bekomme ich das Bild als byte-Array. IGrabResult ist ein Interface von der Kamera-DLL, das die Bilder hält.

C#-Code:
byte[] grabResult = IGrabResult.PixelData as byte[];

grabResult ist ein 1920 * 1200 großes Array mit den Graustufen-Werten (8-Bit).

Jetzt erzeuge ich ein 3x so langes Array für 24-Bit RGB und ersetze den jeweiligen Grün- bzw. Blau-Wert durch den Graustufen-Wert aus dem alten Array.

C#-Code:
byte[] RGB = new byte[1920 * 1200 * 3];
int StartIndex = 0;
// für Grün
for (int Index = 1; Index < RGB.Length; Index += 3)
{
RGB[Index] = grabResult[StartIndex];
StartIndex++;
}
// für Blau
for (int Index = 2; Index < RGB.Length; Index += 3)
{
RGB[Index] = grabResult[StartIndex];
StartIndex++;
}

Da diese Schleife knapp 7 Mio durchlaufen werden muss, 10 Bilder pro Sekunde von der Kamera gegrabbt werden und der Zielrechner ein relativ langsamer Atom ist, dauert der Vorgang des künstlichen Einfärbens halt sehr lange.

Gibt es Möglichkeiten diesen Vorgang zu beschleunigen?
14.08.2017 15:54 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Spook Spook ist männlich
myCSharp.de-Mitglied

Dabei seit: 28.10.2008
Beiträge: 172
Entwicklungsumgebung: VS2015 Professional
Herkunft: Esslingen a.N.


Spook ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo robbb26,

ich würde dies mit einer lookup table lösen:

C#-Code:
  [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct RGB24
    {
        public byte B;
        public byte G;
        public byte R;

        public RGB24(byte value)
        {
            B = value;
            G = value;
            R = value;
        }
    }

    public class ImageConverter
    {
        private RGB24[] _lut;

        public ImageConverter()
        {
            _lut = new RGB24[256];
            for (int i = 0; i < _lut.Length; i++)
            {
                _lut[i] = new RGB24((byte)i);
            }
        }

        public unsafe byte[] ToRGB24(byte[] data)
        {
            byte[] result = new byte[data.Length * 3];
            fixed (byte* bptr = result)
            {
                RGB24* ptr = (RGB24*)bptr;
                for (int i = 0; i < data.Length; i++)
                {
                    ptr[i] = _lut[data[i]];
                }
            }
            return result;
        }
    }

Grüße
spooky
14.08.2017 16:09 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
robbb26
myCSharp.de-Mitglied

Dabei seit: 09.08.2017
Beiträge: 6
Entwicklungsumgebung: Visual Studio 2010-2017

Themenstarter Thema begonnen von robbb26

robbb26 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Danke erstmal für deine Antwort Spook.
Bin jetzt erst dazu gekommen, dein Snippet auszuprobieren. Es funktioniert auch soweit und ist auch fast doppelt so schnell, wie meine Lösung.
ABER :D : Deine Methode schreibt in dem result-Array den Grausutufen-Wert in alle drei Kanäle (RGB)

So sollte es aussehen (beispielhaft): {0, 78, 0, 0 215, 0, 0, 124, 0, ... }
So sieht es momentan aus: {78, 78, 78, 215, 215 ,215, 124, 124, 124, ...}

Hast du dafür noch eine Lösung?
16.08.2017 09:49 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Th69
myCSharp.de-Poweruser/ Experte

images/avatars/avatar-2578.jpg


Dabei seit: 01.04.2008
Beiträge: 2.667
Entwicklungsumgebung: Visual Studio 2010/12/13/15


Th69 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Kannst du nicht programmieren? Tipp: RGB24-Konstruktor ändern.
16.08.2017 10:11 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Spook Spook ist männlich
myCSharp.de-Mitglied

Dabei seit: 28.10.2008
Beiträge: 172
Entwicklungsumgebung: VS2015 Professional
Herkunft: Esslingen a.N.


Spook ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo robbb26,

bei mir funktioniert es (siehe screenshot).


grüße
spooky

Spook hat dieses Bild angehängt:

rgb24.png

16.08.2017 10:33 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Th69
myCSharp.de-Poweruser/ Experte

images/avatars/avatar-2578.jpg


Dabei seit: 01.04.2008
Beiträge: 2.667
Entwicklungsumgebung: Visual Studio 2010/12/13/15


Th69 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Spook: robbb26 möchte aber eben kein Graubild (also R = G = B), sondern nur ein Farbwert davon gesetzt (und die anderen beiden dann 0) ;-)
16.08.2017 11:29 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Spook Spook ist männlich
myCSharp.de-Mitglied

Dabei seit: 28.10.2008
Beiträge: 172
Entwicklungsumgebung: VS2015 Professional
Herkunft: Esslingen a.N.


Spook ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo Th69,

dann ist deine Antwort natürlich richtig. Daumen hoch

Grüße
spooky
16.08.2017 12:08 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
robbb26
myCSharp.de-Mitglied

Dabei seit: 09.08.2017
Beiträge: 6
Entwicklungsumgebung: Visual Studio 2010-2017

Themenstarter Thema begonnen von robbb26

robbb26 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Danke euch beiden!
Läuft jetzt.
16.08.2017 13:29 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum
Antwort erstellen


© Copyright 2003-2017 myCSharp.de-Team. Alle Rechte vorbehalten. 23.08.2017 04:06