Heatmap-Images: Are there 32-bit Tiffs with negative or floating point values?


#1

Dear community,

I am new to Julia and so far was unable to find an answer to my problem: I am trying to generate heatmaps to locate signal changes in an image stack. My signal cannot only increase, but also decrease. Accordingly, I could have negative values.

In Fiji/ImageJ 32bit Tiffs can encode floating point numbers and negative values.

Is there any chance to do generate Tiffs with floating point numbers and negative values?

I mean, yes, I could calculate some “normalisation” to make sure all values are between 0 and 1 so I could clamp it to the range of the tiff, but I’d rather prevent that, because it makes interpretation more difficult for other people.

Thank you in advance for your help.

Moses


#2

You can do it with GMT. See this example Instead of the @tut_relief.nc you would use your own grid (because Tiff floats are grids, not images)


#3

@joa-quim Thank you for that hint (I know, it has been some time, but I had to postpone that project for a while).

Do you by any chance know how to produce a greyscale image? GMT by default seems to produce rainbow/RGB-images.
This code produces an RGB-image, but I need a tif with the float values.

using GMT
TestImageNeg32Bit2 = reshape(collect(-49:50), (10, 10))
grdimage(TestImageNeg32Bit2, fmt="tif", show=true)

Furthermore, do you know how to save a grid as tif?
gmtwrite("C:/Julia/TestImage.tif", TestImageNeg32Bit2) produces a file that I cannot open (at least not in Fiji/ImageJ).


#4

GMT has lots of different color scales and one of them is gray (just type makecpt() to see their names).

But I’m afraid you are still confusing grids and images. They are different things and you must learn the difference. Grids (2D) are something like z = f(x,y) and that z is normally a floating point number (but it can also be an integer). To see a grid one normally assign a color to each element of z and than we get an image (that’s what you did with your first command). Images hold directly the color information and one only have to display them.

When you say that you need a tif with float values you are saying that you want a grid. And that’s fine. Those tifs are normally called geotiff DEM (because they are used to represent Digital Terrain Models). To create them with GMT, you need to provide extra information to the driver.

gmtwrite("C:/Julia/TestImage.tif=gd:GTiff", TestImageNeg32Bit2)

Sorry for the still cryptic for non-initiated =gd:GTiff that we need in order to save geotiffs, but that is well explained in the GMT documentation (not the GMT Julia wrapper) and means use GDAL lib to save the file (the =gd) and save to geotiff format (the :GTiff part). By not specifying the =gd:GTiff like you did in your second command, the file was written in the default netCDF format and that’s why ImageJ was not able to read it.


#5

Thank you @joa-quim for the solution.

I had already tried to use color=“gray”, but got an error. Turns out there seems to be an error in my combination of Atom/Juno/Julia 1.0, because once I use the command in a fresh instance, it works. However, if I want to change the color, I get an error. As I had started from color=“rainbow”, I was not able to change the color-coding.

Thanks for clarifying. I did not know about grids before, because I am coming from a biological/ pharmaceutical field.
I am doing a lot of microscopic imaging, but images are just regarded as a “map of values”, each value representing a photon-count/intensity value (we are using quantitative cameras, monochrome, not RGB). The values are the important part, the color is for display purposes only. Whether I display the image in yellow, red, grey or rainbow is not important, as long as I can read out or access the intensity value.
I frequently use those images, i.e. maps of values, to do some math (e.g. devide one image by another for normalisation or ratio calculation). That’s why I always asked about “images”. As far as I understand it now, my “images” are basically grids that are displayed in greyscale by default.

That explains the problem I observed with the display: grdimage always assigns RGB to the displayed image. The different shades of gray are encoded in RGB, not in black/white as I expected it. But saving the grid works fine, so this is not really an issue.

I had tried to understand all the different options, but with no background in grids, geological business and the different file formats, I was at a complete loss.


#6

Strange. This works fine for me

grdimage(TestImageNeg32Bit2, fmt="tif", color=:gray, show=true)

and you can even restrict the gray levels (from 0 to 100)

grdimage(TestImageNeg32Bit2, fmt="tif", color="100/220", show=true)

Yes, know what you mean. Satellite images often do the same with data represented as numbers from 0 to 65535 (known as 2 byte unsigned integers) and we mast scale them to [0 255] when we want to seem them.

Yes, I understand that but GMT is enormously configurable and it uses those short sized options to do it (full docs in here and here) that are not easy at all to convert to something more verbose with obliging to write an entire page of options.


#7

That solved the problem.

I had used the syntax color="rainbow" or color="gray", because it was written like this in one of the examples. Using your syntax I can switch between colors without triggering errors.

Out of curiosity and only, if it is not too long/difficult to answer: Why do you scale the range 0-65535 to 0-255? Doesn’t that mean, that you loose information? Or is that the reason, why you are using float grids then?


#8

Than can’t be the reason. Since v0.5.0 color="gray" or color=:gray are equivavent. Any optional string that can safely be converted to symbol (I mean, with no errors) can be used either as a string or as a symbol.

Only for visualization. Screens cannot display more than 256 (2^8) different values per channel, which gives 2^24 different colors + eventual transparency, or only 256 gray shades for gray images.

Storing grids in floats is not mandatory. We can save them in integers too if by doing that we are not loosing info, or loose just a little bit but gain high compression rates.


#9

As expected, the problem with the syntax color="gray" vs.color=:graywas due to my installation. After updating thejulia-client` package of Atom, both syntaxes work fine now.