Page 1 of 5

Heat map with lots of events

Posted: 2014-01-05T17:16:04-07:00
by DrEvil
I'm looking for ways to generate a 2d heatmap from a list of 'events' that provide a variable additive influence that should ultimately be normalized and mapped to a color range. There will be potentially tens of thousands of events that may result in arbitrarily large accumulations of influence across areas of the 2d image. Effectively I need to accumulate the events into a floating point image, and then using the minimum and maximum pixel values map each pixel color back to a custom color ramp.

Most of my use cases will use only an accumulation of the event weighting in order to visualize, but certain analytics will need to visualize multiple competing weightings, such as one sides influence being represented as negative weightings and the other as positive, and then a different color ramp for the negative ranges than the positive.

It doesn't appear that the sparse color operations will actually accumulate additively the values as I'm looking for, though some form of sparse color functionality sounds like it would be ideal, as I could provide the events as point colors with magnitudes and let the library fill in the colors in between. I'm thinking if perhaps the way I need to normalize them is not compatible with performing with imagemagick.

I did a quick and dirty but slow implementation in an OpenGL pixel shader where for each pixel, the list of events were iterated and the event cost was accumulated for every event within its radius of the pixel, then that value was color mapped back to my heat color ramp using a configurable min and max cost range. Is there a way to do something like that with ImageMagick? Where I could give it a large data set and then run operations at the pixel level in order to generate the data needed? From my understanding of the process, its not something that can be built incrementally per event(like as a draw circle), unless you incrementally draw circle events into a floating point image buffer to accumulate the costs, extract the min and max pixel values, and then from that image generate an rgb image using the costs mapped to the desired color ramp.

Any help is appreciated. Thanks.

Re: Heat map with lots of events

Posted: 2014-01-06T10:55:53-07:00
by snibgo
I'm trying to break down your problem into primitives. Perhaps it is something like this:

1. Given a coordinate and radius, generate a radial-gradient that is white at the coordinate and black outside the radius. The gradient is linear (but could be something else). The generated values are the weights attributed to one event.

2. Repeat step 1 for each event (thousands).

3. Each event has a temperature. I assume this is a number from zero to quantum.

4. In the result, each pixel value is sigma(step_1_pixel * temperature * sign)/num_events across all the events where sign is +1 or -1.

If this breakdown is correct, it is simple in ImageMagick. But it probably isn't correct. You mention min and max pixels and I don't see where that fits into my breakdown.

Re: Heat map with lots of events

Posted: 2014-01-06T11:32:29-07:00
by snibgo
The result from step 4 is a greyscale image from 0 to quantum. This can readily be turned into a false-colour image.

Perhaps step 4 should be:

4. In the result, each pixel value is max(step_1_pixel * temperature * sign) across all the events where sign is +1 or -1.

Re: Heat map with lots of events

Posted: 2014-01-06T12:42:47-07:00
by DrEvil
I assume you mean a grey scale with a floating point color value or 32 bit 1 channel image or something.

The first part ought to be as simple as rendering radial gradients into an image with additive blending. The additive pixel values will accumulate arbitrarily for all the events. Afterwards I just need to look through each pixel of the image to find the min and max values, and finally using that min and max range renormalize the accumulation image back values back to my color ramp for visualization.

Re: Heat map with lots of events

Posted: 2014-01-06T13:49:13-07:00
by snibgo
DrEvil wrote:I assume you mean a grey scale with a floating point color value or 32 bit 1 channel image or something.
Yes. I normally use 16-bit integers so quantum is 65535. But you might prefer 32-bit or floating-point.
DrEvil wrote:Afterwards I just need to look through each pixel of the image to find the min and max values, and finally using that min and max range renormalize the accumulation image back values back to my color ramp for visualization.
I should add a step 5:

5. Convert this greyscale image to some colour ramp. (This can be done with "-auto-level" followed by a "-clut".)

Re: Heat map with lots of events

Posted: 2014-01-06T14:24:33-07:00
by DrEvil
Can you point me in the right direction for generating an additive floating point image with radial gradients ?

Thanks for your time.



As an aside. Perhaps this is not doable, but are there any mechanisms to visualize 3d event sets? One down side to doing a 2d heightmap is the blending and loss of the event information for overlapping areas of an environment.

Re: Heat map with lots of events

Posted: 2014-01-06T14:49:10-07:00
by snibgo
Step (1) of my breakdown would be something like this (Windows syntax so line-continuation is "^"):

Code: Select all

convert ^
  -size 100x100 ^
  radial-gradient: ^
  -background #000 ^
  -extent 600x400-180-80 ^
  g-000.png
This creates a gradient diameter 100 centred at (230,130). Note that 230-100/2 = 180 and 130-100/2 = 80. This could be multiplied by a temperature that is normalised to zero to one, eg 0.25:

Code: Select all

convert ^
  -size 100x100 ^
  radial-gradient: ^
  -background #000 ^
  -extent 600x400-180-80 ^
  -evaluate Multiply 0.25 ^
  gr-000.png
You can find the mean of three gradient images with:

Code: Select all

convert ^
  g-000.png g-001.png g-002.png ^
  -evaluate-sequence Mean ^
  g.png
There are many mechanisms for 3-D visualisations. However, IM contains no explicit 3-D tools.

Re: Heat map with lots of events

Posted: 2014-01-06T15:56:37-07:00
by fmw42
There are many mechanisms for 3-D visualisations. However, IM contains no explicit 3-D tools.
ImageJ (http://rsb.info.nih.gov/ij/) has a pretty good 3D graph plugin. I used it here http://www.fmwconcepts.com/imagemagick/ ... mcrosscorr

Re: Heat map with lots of events

Posted: 2014-01-10T21:15:03-07:00
by DrEvil
snibgo

Does that breakdown suggest that every event would need to be rasterized into the right 'world space' on a giant image and then a 2nd stop to mash that huge set of indivisual images together ? I don't need a mean of the images, I need the values additively blended together

For instance, my 'world size', assuming I did it to scale, would be images of 10000 * 10000 or more depending on the map. I will obviously scale the output by some factor to reduce this, but this solution suggests that the radial gradiants need rasterized separately so that they can be merged in a 2nd step.

It seems like a non starter to generate thousands or tens of thousands of individual images and then merge them. I was hoping for a quick solution of incrementally feeding radial gradient commands to the processor for it to additively blend together, all in a single image, and then a possible second step to remap the color based on the accumulated values.

Re: Heat map with lots of events

Posted: 2014-01-10T21:51:18-07:00
by fmw42
snibgo is more experienced at this than I, but you can create an SVG (text) file to create all your radial gradients and then render that into one image. see http://www.w3.org/TR/SVG/pservers.html#RadialGradients

Re: Heat map with lots of events

Posted: 2014-01-10T21:59:42-07:00
by DrEvil
Aaah, that sounds promising. the missing bit that I still haven't got a solid lead on is how to additively render them into a float texture so that their weights accumulate(additive blending). I think the steps after this are pretty easy.

Re: Heat map with lots of events

Posted: 2014-01-10T22:34:07-07:00
by fmw42
I don't know if this will work, but if you had one SVG file per gradient, you could treat the svg file as an image and use -draw with the image compose plus mode

see
http://www.imagemagick.org/script/magic ... aphics.php

You may be able to loop SVG commands as text strings and pipe them into a file using @-

Re: Heat map with lots of events

Posted: 2014-01-11T01:09:55-07:00
by snibgo
Sure, you can create thousands of files, or add them as you go. For the latter, start with an initial "zero" heatmap:

Code: Select all

convert ^
  -size 600x400 ^
  xc:black ^
  heatmap.png
Then do this for every event:

Code: Select all

convert ^
  heatmap.png ^
  ( -size 100x100 ^
    radial-gradient: ^
    -evaluate Multiply 0.25 ^
    -background #000 ^
    -extent 600x400-180-80 ^
  ) ^
  -compose Plus -composite ^
  heatmap.png
(Compared to my previous script, I've put the multiply before the extent, not after. The effect is the same but more efficient.)

For 10000x10000 images, this variation might be faster. Instead of using "extent" to make the additive image the right size, we simply use "geometry" to position it.

Code: Select all

convert ^
  heatmap.png ^
  ( -size 100x100 ^
    radial-gradient: ^
    -evaluate Multiply 0.25 ^
  ) ^
  -geometry +180+80 ^
  -compose Plus -composite ^
  heatmap.png
This needs to be in floating point, of course, to avoid overflow. When you have all the events, divide by the number to get the mean:

Code: Select all

convert ^
  heatmap.png ^
  -evaluate Divide 9999 ^
  heatmap.png
For "9999" use the actual number of events.

Or you could have one very long command that creates the "zero" heatmap and adds in all the events and divides the result. A bit of fancy bash piping could build the command.

Re: Heat map with lots of events

Posted: 2014-01-11T10:20:53-07:00
by DrEvil
Thanks that helps a lot. It looked like the previous example was built around generating individual images per event and then mashing them together. This one looks nice. Btw I'm not looking to average the accumulated events. At the end I will be normallizing based on the minimum and maximum values in the entire image, not the number of events. After that normalization the values will then be mapped to a color range to create the final heat map. Again I appreciate all the help.

Re: Heat map with lots of events

Posted: 2014-01-11T11:29:12-07:00
by snibgo
For normalisation (instead of division), "-auto-level" will spread or compress pixel values to the range 0 to 65535. You can then use "-clut" for the false colours.

Code: Select all

convert ^
  heatmap.png ^
  -auto-level ^
  ( -size 1x250 ^
    gradient:#004-#804 ^
    gradient:#804-#f00 ^
    gradient:#f00-#f80 ^
    gradient:#f80-#ff0 ^
    gradient:#ff0-#ffa ^
    -append ^
  ) ^
  -clut ^
  heatmap_coloured.png
EDIT: corrected from "+append", to "-append".