Take the mathematical function (ln) of each pixel

imagej

#1

Hi all,

I am not strong in mathematics or deriving equations so if the solution to this problem is simple I apologize.

I would like guidance on how to take the mathematical function (ln) of every pixel value within a TIFF. file.

The files I am working with are 1024 x 1024 pixels. I would like to perform the following operation on each pixel; ln(pixel value).

May I execute this command through the process>math directly or through a macro?

Examples are welcome, thank you in advance.

Ryan


#2

Based on documentation, using Math > Log may accomplish what you are looking for. However, it may perform scaling depending on your image type. You could do it using a macro with the function log but that would require you to use nested for loops.


#3

Good day Ryan,

Andrew described the way to go and I highly recommend to apply the logarithm to 32bit float images, i.e. first to convert your images to float. Of course this requires gray-scale images.

Don’t forget that the logarithm of zero is minus infinit which normally leads to the value NaN (Not a Number). Furthermore, the logarithm of negative numbers, that are possible with 32bit float images, does not exist in the real-valued world!

Most important however is that logarithmic gray-scales are worthless if you don’t specify the number of decades displayed.

Here is an ImageJ-macro that does this:

// generate testimage
newImage("Untitled", "32-bit ramp", 256, 256, 1);
makeRectangle(0, 0, 1, 256);
run("Set...", "value=0.0000000001");
run("Select None");
//////////////////////////////////////////////////////////////
// logarithm of image with defined number of displayed decades
saveSettings();
if ( nImages < 1 ) { beep(); exit( "No images open !" ); }
if ( bitDepth() != 32 ) { beep(); exit( "Image must be 32bit !" ); }
getRawStatistics( N, mn, mi );
if ( mi < 0 ) { beep(); exit( "All image values must be positive !" ); }
changeValues( 0, 0, NaN );
getRawStatistics( N, mn, mi, mx );
imgName = getTitle();
if ( indexOf( imgName, "." ) > 0 ) { str = split( imgName, "." ); imgName = str[0]; }
Invln10 = 1 / log( 10 );
dec     = 6;
eight   = false;
path    = File.directory;
maxDec  = Invln10 * log( mx / mi );
if ( dec > maxDec ) { dec = maxDec; }
Dialog.create( "Decadic Logarithm Params" );
Dialog.addNumber( "Show", dec, 2, 3, "of " + d2s( maxDec, 2 ) + " Decades" );
Dialog.addCheckbox( "Create and Save 8bit Image", eight );
Dialog.show();
dec   = abs( Dialog.getNumber() );
eight = Dialog.getCheckbox();
run( "Divide...", "value=" + d2s( mx, 9 ) );
run( "Log" );
run( "Multiply...", "value=" + d2s( Invln10, 9 ) );
setMinAndMax( -dec, 0 );
if ( eight ) {
	run( "Duplicate...", "title=temp" );
	selectWindow( "temp" );
	run( "8-bit" );	
	saveAs( "tiff", path + imgName + "_8bit" );
}
restoreSettings;
setBatchMode( false );
exit();

Paste the above macro code to an empty macro window (Plugins >> New >> Macro) and run it.

And yes, you must differentiate the decadic (log or lg), natural (ln), dual (ld), and logarithms with other bases but you can easily convert these.

Regards

Herbie