Jump to content

Thermal Imaging - Visual Basic .NET Code - PictureBox


Recommended Posts

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

Link to comment
Share on other sites

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).

Link to comment
Share on other sites

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?

 

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

  • 2 months later...

grafik.thumb.png.8f5dea27bc046679561e921ee540f2b7.pnggrafik.png.74b94546f2a784b0641829e458a23cf6.png

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

 

Link to comment
Share on other sites

    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

 

Link to comment
Share on other sites

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)

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...