In the last post we looked at how it’s possible to take temperature data from a thermal image and use the Data Visualization Extension to connect that information to locations in a 3D Forge viewer scene.
In this post we look at how we can use the events from the same extension to display a simple tooltip showing the temperature when one of these locations is hovered over.
Let’s start by looking at what we get from the thermal image. It’s pretty simple: we have colour. As we’re averaging a number of pixels it’s likely to be on a gradient, across the chosen palette, so we’re going to have to do a little work to get the numeric temperature value it represents.
Last time we talked about using this site to generate synthetic thermal image. The site doesn’t specifically talk about the palette that’s used for the image generation, but the closest I could find is Rainbow HC from the FLIR website:
This palette includes all the colours shown in the source scene:
Looking at the palette’s legend, I worked on the assumption that the palette could be defined as follows. Bear in mind that I’ve chosen a colour range that mostly makes sense for an office, rather than what is shown in FLIR’s image.
You can see that at a basic level we’re working with just 6 colour stops.
The process to check a colour against this list is fairly simple. First we need a version of the colour stops but with the HTML colour names converted to RGB values. You can find an example of a function that can do this work here.
Then, whenever a sprite is hovered over, we take the HEX colour assigned to it (I tend to store strings for each one rather than having the overhead of storing a THREE.Vector3), convert it to a THREE.Vector3() containing R, G and B values, then check the Euclidean distance between it and each of the colour stops. Here’s a function that does this (should be obvious what colorToRGB() and indexOfSmallest() do… the former is mentioned above while the latter returns the index of the smallest item in an array):
The stops variable contains the colour stops that have been converted to RGB. The return value of this function is pretty simple: it’s a numeric value derived by adding the bottom end of the temperature range to position of the closest stop multiplied by the “stop size” (there must be at least 2 colour stops to avoid a divide by zero, by the way… proper error checking is left as an exercise for the reader ;-).
With just 6 stops the effect is fairly coarse:
Now this is where things got interesting. Initially I started thinking about how best to get finer-grained temperatures… I started down the route of looking at the distance from the closest stop and determining in which direction to approximate a better value. But then I thought, “hang on, how about just adding a few intermediate values into the array of stops?”. It turns out that adding intermediate stops – going from 6 to 11 to 21 to 41 to 81 to 161, and on – allows you to get a *much* more fine-grained temperature value using exactly the same code.
So far I found that having 81 stops – using stops = addStopsRec(stops, 4) during initialization – works well enough for my purposes (the temperature isn’t precise, anyway, so there’s not need to go further). And it seems responsive enough during a mouse-hover event:
The tooltips clearly work in a more 3D view, too.
I haven't provided a complete example for this functionality, but it should be possible to replicate fairly easy based on the pointers I've given.
I’m now quite pleased with where we are with this proof-of-concept, at least in terms of the visualization possibilities. Hopefully it’ll be something that’s properly viable, assuming our computer vision magicians find a way to determine the 3D camera information for a particular shot.