MBOB Posted March 9, 2020 at 09:39 AM Posted March 9, 2020 at 09:39 AM 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 Quote
rtrbt Posted March 9, 2020 at 03:29 PM Posted March 9, 2020 at 03:29 PM 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). Quote
MBOB Posted March 9, 2020 at 04:44 PM Author Posted March 9, 2020 at 04:44 PM 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? Quote
rtrbt Posted March 10, 2020 at 08:48 AM Posted March 10, 2020 at 08:48 AM 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. Quote
MBOB Posted March 10, 2020 at 11:35 AM Author Posted March 10, 2020 at 11:35 AM 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? Quote
rtrbt Posted March 10, 2020 at 12:48 PM Posted March 10, 2020 at 12:48 PM 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. Quote
MBOB Posted June 8, 2020 at 09:16 AM Author Posted June 8, 2020 at 09:16 AM 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 Quote
rtrbt Posted June 8, 2020 at 09:41 AM Posted June 8, 2020 at 09:41 AM Moin, Am einfachsten ist es vermutlich, wenn du deinen Code postest, dann kann man darin den Fehler suchen. Quote
MBOB Posted June 8, 2020 at 10:48 AM Author Posted June 8, 2020 at 10:48 AM 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 Quote
rtrbt Posted June 8, 2020 at 11:49 AM Posted June 8, 2020 at 11:49 AM 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) Quote
MBOB Posted June 8, 2020 at 11:59 AM Author Posted June 8, 2020 at 11:59 AM Super jetzt klappt es, war mein Denkfehler! Quote
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.