MBOB Geschrieben March 9, 2020 at 09:39 Share Geschrieben March 9, 2020 at 09:39 Hallo Community Ich habe über den BrickViewer Zugriff auch das Thermal Imaging Bricklet und sehe auch ein LiveBild. Ich habe über Visual Basic .NET Zugriff auf das Bricklet mit der richtigen UID über den USB Anschluss Wie bekomme ich das LiveBild als BMP in die PictureBox? 1. Der ExampleCode hilft mir leider nicht! -----------ANFANG---------- ' Callback subroutine for high contrast image callback Sub HighContrastImageCB(ByVal sender As BrickletThermalImaging, _ ByVal image As Byte()) ' image is an array of size 80*60 with a 8 bit grey value for each element End Sub -----------ENDE---------- 2. Abfrage der 4800 Arrays und mit "bitmap.setpixel" das PictureBox-Bild pixel-weise zusammenzusetzen scheint mir sehr umständlich! Ziel: 1. LiveBild > PictureBox 2. Color Palette = HotCold Zitieren Link zu diesem Kommentar Share on other sites More sharing options...
rtrbt Geschrieben March 9, 2020 at 15:29 Share Geschrieben March 9, 2020 at 15:29 Moin, Du wirst vermutlich nicht darum herum kommen, das Bild pixelweise zu bauen, du kannst aber, damit es schneller läuft (Falls die Performance ein Problem sein sollte) mit Bitmap.LockBits arbeiten. Die Hot-Cold-Palette im Brick Viewer ist recht simpel aufgebaut: Alle Werte kleiner als 33 sind Cold (also RGB 0, 0, 255), alle über 223 heiß (also RGB 255, 0, 0). Zitieren Link zu diesem Kommentar Share on other sites More sharing options...
MBOB Geschrieben March 9, 2020 at 16:44 Autor Share Geschrieben March 9, 2020 at 16:44 Hallo! Danke für die Info, da komme ich schon etwas weiter. Das Auslesen der 4800 Arrays dauert mit .GetTemperatureImage(1) und .GetTemperatureImage(2) u.s.w. eine Ewigkeit! Scheinbar ist der CallBack-Ansatz besser. Leider habe ich diesen Ansatz noch nicht verstanden? Hast Du eine einfache Erklärung für mich? Zitieren Link zu diesem Kommentar Share on other sites More sharing options...
rtrbt Geschrieben March 10, 2020 at 08:48 Share Geschrieben March 10, 2020 at 08:48 15 hours ago, MBOB said: Das Auslesen der 4800 Arrays dauert mit .GetTemperatureImage(1) und .GetTemperatureImage(2) u.s.w. eine Ewigkeit! Wenn du das Bild, was dir GetTemperatureImage zurückgibt nicht in einer Variable zwischenspeicherst, wird bei jeder Pixelabfrage mit .GetTemperatureImage(x) das ganze Bild neu abgerufen. Das Bricklet muss dann für jeden Pixel das ganze Bild schicken, es schafft aber nur ungefähr 4 Bilder pro Sekunde, deshalb dauert das dann 1200 Sekunden pro Bild. Du kannst mal folgendes versuchen: Dim img as Byte() = ti.GetHighContrastImage() und dann immer mit img(x) die Pixel lesen. 15 hours ago, MBOB said: Scheinbar ist der CallBack-Ansatz besser. Leider habe ich diesen Ansatz noch nicht verstanden? Hast Du eine einfache Erklärung für mich? Der Callback-Ansatz ist schneller, weil das Bricklet dann von sich aus Daten schicken darf. Damit sollten bis zu 9 Bilder pro Sekunde möglich sein. Es gibt hier ein Beispiel. Durch den SetImageTransferConfig wird dem Bricklet mitgeteilt, dass es Callbacks schicken darf. Die Zeile AddHandler ti.HighContrastImageCallback, AddressOf HighContrastImageCB registriert den Sub HighContrastImageCB als die Funktion die (automatisch) ausgeführt werden soll, wenn ein neues Bild ankommt. Du kannst dann in dem Sub (nach dem "image is an array of ..." Kommentar) das Bild aus dem image-Parameter auslesen und in die PictureBox schreiben. Zitieren Link zu diesem Kommentar Share on other sites More sharing options...
MBOB Geschrieben March 10, 2020 at 11:35 Autor Share Geschrieben March 10, 2020 at 11:35 Danke; bin einen Schritt weiter! Der IMAGE-Parameter ist eine Byte-Variable. Meine BITMAP-Variable ist eine Bitmap-Variable. Daher kann ich IMAGE nicht nach BITMAP kopieren! Ist hier die BIT-weise Befüllung des BITMAPs notwendig oder gibt es da noch eine Abkürzung / Vereinfachung? Zitieren Link zu diesem Kommentar Share on other sites More sharing options...
rtrbt Geschrieben March 10, 2020 at 12:48 Share Geschrieben March 10, 2020 at 12:48 Du musst die Bitmap byte-weise befüllen: Ein Pixel im Thermal-Bild ist nicht ein Bit sondern ein Byte. Ob du den Wert dann als cold/nichts/hot betrachtest hängt von deiner Farbpalette ab. Im Brick Viewer sind es 0-32 -> cold, 33 -> 222 -> schwarz, 223-255 -> hot. Zitieren Link zu diesem Kommentar Share on other sites More sharing options...
MBOB Geschrieben June 8, 2020 at 09:16 Autor Share Geschrieben June 8, 2020 at 09:16 Anbei das Bild des BrickViewers. Bei mir (VB-Programm) sieht das Bild (rötliches Muster, da ich Byte-Werte nur als RED-Intensivität dargestellt habe) unstrukturiert aus, obwohl ich die 4800 Bytes Zeile 0, dann Zeile 1 u.s.w. auslese !?!?! Alle anderen Parameter habe ich auf Standart-Parameter lassen Kann ich bitte einen ausführlicheren Beispiel-Code haben, als euer Beispiel-Code https://github.com/Tinkerforge/thermal-imaging-bricklet/raw/master/software/examples/vbnet/ExampleCallback.vb Zitieren Link zu diesem Kommentar Share on other sites More sharing options...
rtrbt Geschrieben June 8, 2020 at 09:41 Share Geschrieben June 8, 2020 at 09:41 Moin, Am einfachsten ist es vermutlich, wenn du deinen Code postest, dann kann man darin den Fehler suchen. Zitieren Link zu diesem Kommentar Share on other sites More sharing options...
MBOB Geschrieben June 8, 2020 at 10:48 Autor Share Geschrieben June 8, 2020 at 10:48 Sub HighContrastImageCB(ByVal sender As BrickletThermalImaging, ByVal image As Byte()) Dim myBitmap As New Bitmap("c:\temp\ir8060.jpg") Dim img As Byte() = image Dim i As Single Dim x As Single Dim y As Single Dim img_color(4800) As Color Dim img_highest As Byte For i = 0 To 4799 img_color(i) = Color.FromArgb(0, img(i), 0, img(i)) 'RGB(255, 0, 0) Next i For y = 0 To 59 For x = 0 To 79 myBitmap.SetPixel(x, y, img_color(x * y)) Next x Next y PicBox_IR.Image = myBitmap End Sub Zitieren Link zu diesem Kommentar Share on other sites More sharing options...
rtrbt Geschrieben June 8, 2020 at 11:49 Share Geschrieben June 8, 2020 at 11:49 Ich habe das nicht getestet, aber folgende Dinge fallen mir auf: 54 minutes ago, MBOB said: myBitmap.SetPixel(x, y, img_color(x * y)) Da musst du anders auf den konkreten Wert aus img_color zugreifen: Du willst ja den Pixel x,y, also Spalte x, Zeile y. Damit du in dem eindimensionalen Array den korrekten Pixel auswählst, musst du also y Zeilen überspringen (die sind jeweils 80 Pixel lang) und dann den x-ten Pixel auswählen. Das sollte so funtionieren: myBitmap.SetPixel(x, y, img_color(y * 80 + x)) 57 minutes ago, MBOB said: img_color(i) = Color.FromArgb(0, img(i), 0, img(i)) 'RGB(255, 0, 0) Hier legst du als Farbe immer eine an, die einen Alpha-Wert von 0 (also vollständig transparent) hat. Das erzeugt bei dir dann kein Problem, weil du das Bild als jpg speicherst, was keine Transparenz kann, aber wenn du z.B. eine PNG anlegen würdest, oder das Bild direkt in eine GUI zeichnen, dann würdest du nichts mehr sehen. So sollte es klappen: img_color(i) = Color.FromArgb(255, img(i), 0, img(i)) 'RGB(255, 0, 0) Alternativ kannst du den Alpha-Wert auch weglassen: img_color(i) = Color.FromArgb(img(i), 0, img(i)) 'RGB(255, 0, 0) Zitieren Link zu diesem Kommentar Share on other sites More sharing options...
MBOB Geschrieben June 8, 2020 at 11:59 Autor Share Geschrieben June 8, 2020 at 11:59 Super jetzt klappt es, war mein Denkfehler! Zitieren Link zu diesem Kommentar Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.