VB.net Thermal Imaging interpolation advice
VB.net Thermal Imaging interpolation advice
VB.net Thermal Imaging interpolation advice
VB.net Thermal Imaging interpolation advice
VB.net Thermal Imaging interpolation advice
VB.net Thermal Imaging interpolation advice VB.net Thermal Imaging interpolation advice VB.net Thermal Imaging interpolation advice VB.net Thermal Imaging interpolation advice VB.net Thermal Imaging interpolation advice VB.net Thermal Imaging interpolation advice VB.net Thermal Imaging interpolation advice VB.net Thermal Imaging interpolation advice
VB.net Thermal Imaging interpolation advice VB.net Thermal Imaging interpolation advice
VB.net Thermal Imaging interpolation advice
Go Back  Xtreme Visual Basic Talk > > > VB.net Thermal Imaging interpolation advice


Reply
 
Thread Tools Display Modes
  #1  
Old 11-20-2015, 05:46 PM
Blankenship Blankenship is offline
Newcomer
 
Join Date: Nov 2015
Posts: 1
Default VB.net Thermal Imaging interpolation advice


Hello all,

First time poster here in this forum.

I have created a quick and dirty VB.net app to display Thermal Imaging data from a MLX90620 imaging sensor. It has a 16X4 grid that gives a temperature per pixel.

As you can see from the attached image I am receiving all temperature information in an array and assigning a HEX color depending on what the temperature is. I created the "color map" from a website that had a user defined gradient.

I am somewhat new to dealing with palette's. As you can see from the youtube video I created I am not interpolating the colors for a smooth transition between pixels.

https://www.youtube.com/watch?v=wfuiXUZHd1A

Here is a code snippet of how I am currently setting the colors per pixel on the grid :

Code:

Public Function getColor(ByVal myTemperature As Single) As String

        ' http://web-tech.ga-usa.com/2012/05/creating-a-custom-hot-to-cold-temperature-color-gradient-for-use-with-rrdtool/

        If myTemperature >= 85 Then
            getColor = "#FF0EF0"
            Exit Function
        End If

        If myTemperature < 85 And myTemperature >= 83.6 Then
            getColor = "#FF0DF0"
            Exit Function
        End If

        If myTemperature < 86.6 And myTemperature >= 82.19 Then
            getColor = "#FF0DF0"
            Exit Function
        End If

        If myTemperature < 82.19 And myTemperature >= 80.78 Then
            getColor = "#FF0BF0"
            Exit Function
        End If
Exit Function
Does interpolation "blend" the colors between 2 pixels, this is what I do not understand.

Any help would be appreciated.

Thanks
Attached Images
File Type: jpg MLXVBNET.JPG (203.1 KB, 11 views)
Reply With Quote
  #2  
Old 12-22-2015, 05:00 AM
Goggy's Avatar
Goggy Goggy is offline
Contributor
 
Join Date: Sep 2005
Location: Enschede,The Netherlands
Posts: 670
Default

Interpolation, calculates die value between 2 numbers. so yes it can be used to blend 2 colors.

there are several ways to do this, linear being the simplest. for more information see https://en.wikipedia.org/wiki/Interpolation

Here's an example of the simplest form

Code:
    Public Class Simple
        ''' <summary>
        ''' |-----+ P2
        ''' |    /|
        ''' |   / |
        ''' |--+  |
        ''' | /|  |
        ''' |/ |  |
        ''' +------------------------------
        ''' P1  X
        ''' http://en.wikipedia.org/wiki/Linear_interpolation
        ''' </summary>
        ''' <param name="P1">The p1.</param>
        ''' <param name="P2">The p2.</param>
        ''' <param name="X">The Y value of the point of witch the Y value is calcualted.</param>
        ''' <returns>
        ''' The Y value
        ''' </returns>
        ''' <exception cref="MathematicsError">(P2.X - P1.X) will result in devision by zero</exception>
        Public Shared Function Linear(P1 As System.Drawing.PointF,
                                      P2 As System.Drawing.PointF,
                                      X As Double) As Double
            If P1.X <> P2.X Then
                Return P1.Y + ((P2.Y - P1.Y) * ((X - P1.X) / (P2.X - P1.X)))
            Else
                Throw New MathematicsError("(P2.X - P1.X) will result in devision by zero")
                Return Double.NegativeInfinity
            End If
        End Function
        ''' <summary>
        ''' X1            X2
        ''' +------|----+
        ''' |      |    |
        ''' -------+ CalulationPoint
        ''' |           |
        ''' +-----------+
        ''' X3            X4
        ''' http://en.wikipedia.org/wiki/Bilinear_interpolation
        ''' </summary>
        ''' <param name="X1">The x1.</param>
        ''' <param name="X2">The x2.</param>
        ''' <param name="X3">The x3.</param>
        ''' <param name="X4">The x4.</param>
        ''' <param name="CalulationPoint">The calulation point.</param>
        ''' <returns></returns>
        Public Shared Function Bilinear(X1 As System.Drawing.PointF,
                                        X2 As System.Drawing.PointF,
                                        X3 As System.Drawing.PointF,
                                        X4 As System.Drawing.PointF,
                                        CalulationPoint As System.Drawing.PointF) As Double

            Dim Temp_1 As Double = Linear(X1, X2, CalulationPoint.X)                                                            '((X2.X - CalulationPoint.X) / (X2.X - X1.X)) * X1.Value + ((CalulationPoint.X - X1.X) / (X2.X - X1.X)) * X2.Value
            Dim Temp_2 As Double = Linear(X3, X4, CalulationPoint.X)                                                            '((X2.X - CalulationPoint.X) / (X2.X - X1.X)) * X3.Value + ((CalulationPoint.X - X1.X) / (X2.X - X1.X)) * X4.Value
            Return Linear(New PointF(X1.Y, X1.X), New PointF(X3.Y, X3.X), CalulationPoint.Y)                                      'Return ((X3.Y - CalulationPoint.Y) / (X3.Y - X1.Y)) * Temp_1 + ((CalulationPoint.Y - X1.Y) / (X3.Y - X1.Y)) * Temp_2
        End Function
        ''' <summary>
        ''' Bis the cubic.
        ''' </summary>
        ''' <param name="Points">The points.</param>
        ''' <param name="CalculationPoint">The calculation point.</param>
        ''' <returns></returns>
        ''' <exception cref="MathematicsError">BiCubic Needs 16 Elements to be calculated</exception>
        ''' <exception cref="System.NotImplementedException"></exception>
        Public Shared Function BiCubic(Points() As System.Drawing.Point, CalculationPoint As System.Drawing.Point) As Double
            Try
                If Points.Count <> 16 Then
                    Throw New MathematicsError("BiCubic Needs 16 Elements to be calculated")
                End If
                Throw New NotImplementedException
            Catch ex As Exception
                Return 0
            End Try

        End Function
    End Class
__________________
As finishing touch, god created the Dutch!

utterly useless, but always trying to help
Reply With Quote
  #3  
Old 12-22-2015, 05:07 AM
Goggy's Avatar
Goggy Goggy is offline
Contributor
 
Join Date: Sep 2005
Location: Enschede,The Netherlands
Posts: 670
Default the next step

this example takes a row of colors and interpolates between them and shows the result in a picture box.

class code:

Code:
Namespace Global.System.GoggyInc.Forms
#Region "   BilinearInterpolationControls"
    ''' <summary>
    ''' http://en.wikipedia.org/wiki/Bilinear_interpolation
    ''' </summary>
    ''' <remarks></remarks>
    Public Class BI
        Inherits System.Windows.Forms.PictureBox
#Region "Private Variable(s)"
        Private m_Diff_01 As Integer                                        ' Used to hold the difference in value between 2 R/G/B value's
        Private m_Diff_02 As Integer                                        ' Used to hold the difference in value between 2 R/G/B value's
        Private m_Bytes As Integer
        Private m_OrginalBmp As Bitmap                                      ' The bitmap that will be distorted.
        Private m_OrginalBmpData As BitmapData                              ' The structure containing information about the original bitmap. 
        Private m_IntPtrFirstLineOriginalBmp As IntPtr
        Private m_OrginalRGBValues() As Byte
        Private m_CurrentBitmapPixelX As Integer                            ' X coordinant of the pixel that's being distorted.
        Private m_CurrentBitmapPixelY As Integer
        Private NewPixelOffset As Integer                                   ' Offset to pixel in RGB pixel Array of the distorted bitmap.

        Private RGBTopLeft As Byte()
        Private RGBTopRight As Byte()
        Private RGBBottomLeft As Byte()
        Private RGBBottomRight As Byte()
        Private X As Double
        Private Y As Double

        Private m_Rows As New PixelRows
#End Region
        Public Sub New()
            Me.Size = New Size(300, 300)
        End Sub
        Public Property Rows() As PixelRows
            Get
                Return m_Rows
            End Get
            Set(ByVal value As PixelRows)
                m_Rows = value
                CreateImage()
            End Set
        End Property
        Protected Overrides Sub OnResize(e As EventArgs)
            MyBase.OnResize(e)
            CreateImage()
        End Sub
        Private Sub CreateImage()
            If Me.Width > 1 AndAlso Me.Height > 1 AndAlso m_Rows.Count > 0 Then
                ' Create a new pitmap to use as image.
                m_OrginalBmp = New Bitmap(Me.Width, Me.Height, PixelFormat.Format24bppRgb)
                ' Lock the bitmap's bits.  
                LockAndGetRGBValues(m_OrginalBmp, m_OrginalBmpData, m_OrginalBmp.PixelFormat, m_IntPtrFirstLineOriginalBmp, m_OrginalRGBValues)
                ' 
                Dim Width As Integer = CInt(Me.Width / (Me.m_Rows(0).Count - 1)) - 1
                Dim Height As Integer = CInt(Me.Height / (Me.m_Rows.Count - 1)) - 1
                '
                For RowIndex As Integer = 0 To Me.m_Rows.Count - 2
                    For ColIndex As Integer = 0 To Me.m_Rows.Item(0).Count - 2

                        RGBTopLeft = {Me.m_Rows(RowIndex).Item(ColIndex).R, Me.m_Rows(RowIndex).Item(ColIndex).G, Me.m_Rows(RowIndex).Item(ColIndex).B}
                        RGBTopRight = {Me.m_Rows(RowIndex).Item(ColIndex + 1).R, Me.m_Rows(RowIndex).Item(ColIndex + 1).G, Me.m_Rows(RowIndex).Item(ColIndex + 1).B}
                        RGBBottomLeft = {Me.m_Rows(RowIndex + 1).Item(ColIndex).R, Me.m_Rows(RowIndex + 1).Item(ColIndex).G, Me.m_Rows(RowIndex + 1).Item(ColIndex).B}
                        RGBBottomRight = {Me.m_Rows(RowIndex + 1).Item(ColIndex + 1).R, Me.m_Rows(RowIndex + 1).Item(ColIndex + 1).G, Me.m_Rows(RowIndex + 1).Item(ColIndex + 1).B}

                        For Me.m_CurrentBitmapPixelY = (RowIndex * Height) To (RowIndex + 1) * Height
                            Y = ((RowIndex + 1) * Height - m_CurrentBitmapPixelY) / (Height)
                            For Me.m_CurrentBitmapPixelX = (ColIndex * Width) To (ColIndex + 1) * Width
                                X = ((ColIndex + 1) * Width - m_CurrentBitmapPixelX) / (Width)
                                NewPixelOffset = (m_OrginalBmpData.Stride * m_CurrentBitmapPixelY) + (m_CurrentBitmapPixelX * 3)
                                ' GDI+ still lies to us, the return format is BGR NOT RGB
                                m_OrginalRGBValues(NewPixelOffset) = CByte(Y * (X * RGBTopLeft(2) + (1 - X) * RGBTopRight(2)) + (1 - Y) * (X * RGBBottomLeft(2) + (1 - X) * RGBBottomRight(2)))
                                m_OrginalRGBValues(NewPixelOffset + 1) = CByte(Y * (X * RGBTopLeft(1) + (1 - X) * RGBTopRight(1)) + (1 - Y) * (X * RGBBottomLeft(1) + (1 - X) * RGBBottomRight(1)))
                                m_OrginalRGBValues(NewPixelOffset + 2) = CByte(Y * (X * RGBTopLeft(0) + (1 - X) * RGBTopRight(0)) + (1 - Y) * (X * RGBBottomLeft(0) + (1 - X) * RGBBottomRight(0)))
                            Next
                        Next
                    Next
                Next

                ' Copy the RGB values to the new bitmap
                System.Runtime.InteropServices.Marshal.Copy(m_OrginalRGBValues, 0, m_IntPtrFirstLineOriginalBmp, m_Bytes)
                ' Unlock the bits.
                m_OrginalBmp.UnlockBits(m_OrginalBmpData)

                Me.Image = m_OrginalBmp
            End If

        End Sub
        Private Sub LockAndGetRGBValues(ByRef Bmp As System.Drawing.Bitmap, _
                                        ByRef BmpData As BitmapData, _
                                        ByRef PixelFormat As PixelFormat, _
                                        ByRef FirstLine As IntPtr, _
                                        ByRef RGBValues() As Byte)
            ' Get the bitmap infromation.
            BmpData = Bmp.LockBits(New System.Drawing.Rectangle(0, 0, Bmp.Width, Bmp.Height), _
                                   Drawing.Imaging.ImageLockMode.ReadWrite, _
                                   PixelFormat)
            ' Get the address of the first line.
            FirstLine = BmpData.Scan0
            ' This code is specific to a bitmap with 24 bits per pixels.
            m_Bytes = BmpData.Stride * Bmp.Height
            ReDim RGBValues(m_Bytes - 1)
            ' Copy the RGB values into the array.
            System.Runtime.InteropServices.Marshal.Copy(BmpData.Scan0, RGBValues, 0, m_Bytes)

        End Sub
    End Class
    Public Class PixelRows
        Inherits List(Of PixelRow)
    End Class
    Public Class PixelRow
        Inherits List(Of Color)
    End Class
#End Region
End Namespace
form code

Code:
Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim Rows As New GoggyInc.Forms.PixelRows
        Dim Row As New GoggyInc.Forms.PixelRow

        Row.Add(Color.Black)
        Row.Add(Color.Blue)
        Row.Add(Color.Yellow)

        Rows.Add(Row)

        Row = New GoggyInc.Forms.PixelRow

        Row.Add(Color.Red)
        Row.Add(Color.Green)
        Row.Add(Color.Purple)

        Rows.Add(Row)

        Me.Bi1.Rows = Rows

    End Sub
End Class
The result being as shown below
Attached Images
File Type: png Result.PNG (765.4 KB, 9 views)
__________________
As finishing touch, god created the Dutch!

utterly useless, but always trying to help
Reply With Quote
  #4  
Old 12-30-2015, 05:51 PM
hDC_0VB.net Thermal Imaging interpolation advice hDC_0 is offline
Contributor

* Expert *
 
Join Date: Feb 2004
Posts: 559
Default Alternative color blending in VB.Net

Not to take away anything from Goggy's code, but just to suggest as an alternative...

Even though DotNet doesn't have a lot of in-built customizable per pixel color interpolation functions,
it does have the ColorBlend constructor that can be useful, for instance when using a LinearGradientBrush (1, 2, 3, 4, 5).

The other way to do color blending:
Moving from a 4x4 matrix to a 5x5 color matrix allows performing nonlinear transformations per this colormatrix transforms article.

Although this is usually used to adjust colors for an a design time generated image
there is no reason (theoretically) it couldn't be used tweak the color intensity of a programmatically generated bitmap.

Just as a forum cross reference I would note that bilinear interpolation of colors tends to leave "gaps" when applied in a nonlinear context
(as Goggy encountered with his code in this thread).

There is not much in terms of GDI+ based functionality (non-WPF, non-XNA) to effectively handle this situation.
However, there is code on the forum that shows a workaround for this inside the attachment to this post,
where it has QuadDistort class that not only has a Interpolate function. but has some "paint missing pixels" code inside the DrawBitmap sub code.

Off forum, even thought they deal with C#, rather than VB, code
I would like to recommend Jack Xu's articles (1, 2) and Practical C# Charts and Graphics book (pdf) for an in depth coverage
of .Net customized color map coding (especially Chapter 6 of the book that details
color interpolation associated with representing 3D surface plots as 2D color maps).

Last edited by hDC_0; 12-30-2015 at 06:51 PM.
Reply With Quote
Reply

Tags
mytemperature, function, exit, getcolor, imaging, colors, created, temperature, vb.net, pixels, color, pixel, interpolation, #ff0df0, thermal, grid, getcolorbyval, public, setting, snippet, code, appreciated, string, #ff0bf0, transition


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
VB.net Thermal Imaging interpolation advice
VB.net Thermal Imaging interpolation advice
VB.net Thermal Imaging interpolation advice VB.net Thermal Imaging interpolation advice
VB.net Thermal Imaging interpolation advice
VB.net Thermal Imaging interpolation advice
VB.net Thermal Imaging interpolation advice VB.net Thermal Imaging interpolation advice VB.net Thermal Imaging interpolation advice VB.net Thermal Imaging interpolation advice VB.net Thermal Imaging interpolation advice VB.net Thermal Imaging interpolation advice VB.net Thermal Imaging interpolation advice
VB.net Thermal Imaging interpolation advice
VB.net Thermal Imaging interpolation advice
 
VB.net Thermal Imaging interpolation advice
VB.net Thermal Imaging interpolation advice
 
-->