Hi everybody,
I have a number of 16bit images. The highest gray value is 65535 in all of them. The lowest gray value varies between 20000 and 40000. How can I transform all images in a linear fashion leaving the highest gray value at 65535 and set the lowest to 30000? With Enhance Contrast I can stretch the distribution in such a manner that the lowest gray value is zero. But I want to stretch the distribution in some images and condens it in others. Thank you, Thomas -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Thomas
|
Thomas, this is a math problem in four steps,
1. Translate the values from the current minimum of 20000 to a minimum of zero by subtracting 20000 from the pixel value. 2. Calculate a new value between 0 and 1 by dividing it by the existing range (65535 - 20000) 3. Multiply that value by the desired range (65535 - 30000) 4. Finally translate the value by adding the new minimum (and rounding it) newValue = round( ((oldValue - oldMin)/oldRange)*newRange + newMin) I tested this for these values and results 20,000, 30,000, 40,000, and 65,535 30,000, 37,787, 45,574, and 65,535 To increase the speed, newRange/oldRange can be moved outside the loop as it is a constant. If you have a few times more pixels than 65,535 - 20,000 (45,535 + 1) and many files I suggest pre-calculating each value into an array as a lookup table. if speed matters. HTH Nate On Fri, Jun 12, 2020 at 2:32 PM Thomas Fischer <[hidden email]> wrote: > Hi everybody, > > I have a number of 16bit images. The highest gray value is 65535 in all of > them. The lowest gray value varies between 20000 and 40000. How can I > transform all images in a linear fashion leaving the highest gray value at > 65535 and set the lowest to 30000? > > With Enhance Contrast I can stretch the distribution in such a manner that > the lowest gray value is zero. But I want to stretch the distribution in > some images and condens it in others. > > Thank you, Thomas > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Robert, excellent and best approach- with one recommendation, instead of simply subtracting 20000 from everything use the Math>Macro>(v=v*20000) which would subtract that value from all pixels and would be much faster than a array while not changing the range of any of them. Just a suggestion.
Bob ________________________________ From: Robert Lockwood <[hidden email]> Sent: Friday, June 12, 2020 7:49 PM To: [hidden email] <[hidden email]> Subject: Re: linear transform Thomas, this is a math problem in four steps, 1. Translate the values from the current minimum of 20000 to a minimum of zero by subtracting 20000 from the pixel value. 2. Calculate a new value between 0 and 1 by dividing it by the existing range (65535 - 20000) 3. Multiply that value by the desired range (65535 - 30000) 4. Finally translate the value by adding the new minimum (and rounding it) newValue = round( ((oldValue - oldMin)/oldRange)*newRange + newMin)( I tested this for these values and results 20,000, 30,000, 40,000, and 65,535 30,000, 37,787, 45,574, and 65,535 To increase the speed, newRange/oldRange can be moved outside the loop as it is a constant. If you have a few times more pixels than 65,535 - 20,000 (45,535 + 1) and many files I suggest pre-calculating each value into an array as a lookup table. if speed matters. HTH Nate On Fri, Jun 12, 2020 at 2:32 PM Thomas Fischer <[hidden email]> wrote: > Hi everybody, > > I have a number of 16bit images. The highest gray value is 65535 in all of > them. The lowest gray value varies between 20000 and 40000. How can I > transform all images in a linear fashion leaving the highest gray value at > 65535 and set the lowest to 30000? > > With Enhance Contrast I can stretch the distribution in such a manner that > the lowest gray value is zero. But I want to stretch the distribution in > some images and condens it in others. > > Thank you, Thomas > > -- > ImageJ mailing list: https://eur05.safelinks.protection.outlook.com/?url=http%3A%2F%2Fimagej.nih.gov%2Fij%2Flist.html&data=02%7C01%7C%7Ce9ac4880ab2b428012c508d80f2bc62d%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637276027973125539&sdata=XrP9B1AVEwWhJEeX2GJk9V07blnxdxdD92fv4FSbG2Y%3D&reserved=0 > -- ImageJ mailing list: https://eur05.safelinks.protection.outlook.com/?url=http%3A%2F%2Fimagej.nih.gov%2Fij%2Flist.html&data=02%7C01%7C%7Ce9ac4880ab2b428012c508d80f2bc62d%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637276027973135535&sdata=P8JR93MtOyspCWEIZUpuo0%2BX5tIhhVCMldq4jLiG8kM%3D&reserved=0 -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Thanks to both Roberts,
I confess that I use imagej in a very simple way. Unless I find a code on the internet I embed the result of the macro recorder in a shell script which replaces the variable parameters. Since the present task lends itself to batch programming I have two questions. 1) I know how to extract the list of histogram values and from that I can extract the lowest bin which is different in every image. But there must be a possibility to get the MIN that is shown on the histogram window directly, without the detour via the whole histogram. 2) Could you point out how the core of the math operations looks like. I do know the input and output periphery. Thanks again, Thomas Am Sa., 13. Juni 2020 um 02:43 Uhr schrieb Robert Smith <[hidden email] >: > Robert, excellent and best approach- with one recommendation, instead of > simply subtracting 20000 from everything use the Math>Macro>(v=v*20000) > which would subtract that value from all pixels and would be much faster > than a array while not changing the range of any of them. Just a > suggestion. > Bob > > > ________________________________ > From: Robert Lockwood <[hidden email]> > Sent: Friday, June 12, 2020 7:49 PM > To: [hidden email] <[hidden email]> > Subject: Re: linear transform > > Thomas, this is a math problem in four steps, > 1. Translate the values from the current minimum of 20000 to a minimum of > zero by subtracting 20000 from the pixel value. > 2. Calculate a new value between 0 and 1 by dividing it by the existing > range (65535 - 20000) > 3. Multiply that value by the desired range (65535 - 30000) > 4. Finally translate the value by adding the new minimum (and rounding it) > newValue = round( ((oldValue - oldMin)/oldRange)*newRange + newMin)( > > I tested this for these values and results > 20,000, 30,000, 40,000, and 65,535 > 30,000, 37,787, 45,574, and 65,535 > > To increase the speed, newRange/oldRange can be moved outside the loop as > it is a constant. > If you have a few times more pixels than 65,535 - 20,000 (45,535 + 1) and > many files I suggest pre-calculating each value into an array as a lookup > table. if speed matters. > > HTH > Nate > > > On Fri, Jun 12, 2020 at 2:32 PM Thomas Fischer <[hidden email]> > wrote: > > > Hi everybody, > > > > I have a number of 16bit images. The highest gray value is 65535 in all > of > > them. The lowest gray value varies between 20000 and 40000. How can I > > transform all images in a linear fashion leaving the highest gray value > at > > 65535 and set the lowest to 30000? > > > > With Enhance Contrast I can stretch the distribution in such a manner > that > > the lowest gray value is zero. But I want to stretch the distribution in > > some images and condens it in others. > > > > Thank you, Thomas > > > > -- > > ImageJ mailing list: > https://eur05.safelinks.protection.outlook.com/?url=http%3A%2F%2Fimagej.nih.gov%2Fij%2Flist.html&data=02%7C01%7C%7Ce9ac4880ab2b428012c508d80f2bc62d%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637276027973125539&sdata=XrP9B1AVEwWhJEeX2GJk9V07blnxdxdD92fv4FSbG2Y%3D&reserved=0 > > > > -- > ImageJ mailing list: > https://eur05.safelinks.protection.outlook.com/?url=http%3A%2F%2Fimagej.nih.gov%2Fij%2Flist.html&data=02%7C01%7C%7Ce9ac4880ab2b428012c508d80f2bc62d%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637276027973135535&sdata=P8JR93MtOyspCWEIZUpuo0%2BX5tIhhVCMldq4jLiG8kM%3D&reserved=0 > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Thomas
|
In reply to this post by Robert Smith
Dear Bob,
I'm really not an expert of these pixels operations but like Nelson Mandela said: "I never lose. I either win or learn". Thus if what I will be writing below is wrong, I will then be able to learn from my errors! But in order to subtract 20000 from everything shouldn't you rather use the Math>Macro>(v=v-20000) [instead of the Math>Macro>(v=v*20000) your wrote ?] Also wouldn't it even be simpler to just use the Process>Math>Substract...>20000 ? My best regards, Philippe Philippe CARL Laboratoire de Bioimagerie et Pathologies UMR 7021 CNRS - Université de Strasbourg Faculté de Pharmacie 74 route du Rhin 67401 ILLKIRCH Tel : +33(0)3 68 85 42 89 ----- Mail original ----- De: "Robert Smith" <[hidden email]> À: "imagej" <[hidden email]> Envoyé: Samedi 13 Juin 2020 02:42:06 Objet: Re: linear transform Robert, excellent and best approach- with one recommendation, instead of simply subtracting 20000 from everything use the Math>Macro>(v=v*20000) which would subtract that value from all pixels and would be much faster than a array while not changing the range of any of them. Just a suggestion. Bob ________________________________ From: Robert Lockwood <[hidden email]> Sent: Friday, June 12, 2020 7:49 PM To: [hidden email] <[hidden email]> Subject: Re: linear transform Thomas, this is a math problem in four steps, 1. Translate the values from the current minimum of 20000 to a minimum of zero by subtracting 20000 from the pixel value. 2. Calculate a new value between 0 and 1 by dividing it by the existing range (65535 - 20000) 3. Multiply that value by the desired range (65535 - 30000) 4. Finally translate the value by adding the new minimum (and rounding it) newValue = round( ((oldValue - oldMin)/oldRange)*newRange + newMin)( I tested this for these values and results 20,000, 30,000, 40,000, and 65,535 30,000, 37,787, 45,574, and 65,535 To increase the speed, newRange/oldRange can be moved outside the loop as it is a constant. If you have a few times more pixels than 65,535 - 20,000 (45,535 + 1) and many files I suggest pre-calculating each value into an array as a lookup table. if speed matters. HTH Nate On Fri, Jun 12, 2020 at 2:32 PM Thomas Fischer <[hidden email]> wrote: > Hi everybody, > > I have a number of 16bit images. The highest gray value is 65535 in all of > them. The lowest gray value varies between 20000 and 40000. How can I > transform all images in a linear fashion leaving the highest gray value at > 65535 and set the lowest to 30000? > > With Enhance Contrast I can stretch the distribution in such a manner that > the lowest gray value is zero. But I want to stretch the distribution in > some images and condens it in others. > > Thank you, Thomas > > -- > ImageJ mailing list: https://eur05.safelinks.protection.outlook.com/?url=http%3A%2F%2Fimagej.nih.gov%2Fij%2Flist.html&data=02%7C01%7C%7Ce9ac4880ab2b428012c508d80f2bc62d%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637276027973125539&sdata=XrP9B1AVEwWhJEeX2GJk9V07blnxdxdD92fv4FSbG2Y%3D&reserved=0 > -- ImageJ mailing list: https://eur05.safelinks.protection.outlook.com/?url=http%3A%2F%2Fimagej.nih.gov%2Fij%2Flist.html&data=02%7C01%7C%7Ce9ac4880ab2b428012c508d80f2bc62d%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637276027973135535&sdata=P8JR93MtOyspCWEIZUpuo0%2BX5tIhhVCMldq4jLiG8kM%3D&reserved=0 -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
You are absolutely correct young man, I didn't catch the error untill after I hit the send key. Finger dyslexia in an old man. My apologies, and however no you would only subtract the 20000, thereby lowering
the overall level of the image while maintaining the orginial range of intensity. Again, I apologize. Bob 😊 ________________________________ From: ImageJ Interest Group <[hidden email]> on behalf of CARL Philippe (LBP) <[hidden email]> Sent: Saturday, June 13, 2020 9:36 AM To: [hidden email] <[hidden email]> Subject: Re: linear transform Dear Bob, I'm really not an expert of these pixels operations but like Nelson Mandela said: "I never lose. I either win or learn". Thus if what I will be writing below is wrong, I will then be able to learn from my errors! But in order to subtract 20000 from everything shouldn't you rather use the Math>Macro>(v=v-20000) [instead of the Math>Macro>(v=v*20000) your wrote ?] Also wouldn't it even be simpler to just use the Process>Math>Substract...>20000 ? My best regards, Philippe Philippe CARL Laboratoire de Bioimagerie et Pathologies UMR 7021 CNRS - Université de Strasbourg Faculté de Pharmacie 74 route du Rhin 67401 ILLKIRCH Tel : +33(0)3 68 85 42 89 ----- Mail original ----- De: "Robert Smith" <[hidden email]> À: "imagej" <[hidden email]> Envoyé: Samedi 13 Juin 2020 02:42:06 Objet: Re: linear transform Robert, excellent and best approach- with one recommendation, instead of simply subtracting 20000 from everything use the Math>Macro>(v=v*20000) which would subtract that value from all pixels and would be much faster than a array while not changing the range of any of them. Just a suggestion. Bob ________________________________ From: Robert Lockwood <[hidden email]> Sent: Friday, June 12, 2020 7:49 PM To: [hidden email] <[hidden email]> Subject: Re: linear transform Thomas, this is a math problem in four steps, 1. Translate the values from the current minimum of 20000 to a minimum of zero by subtracting 20000 from the pixel value. 2. Calculate a new value between 0 and 1 by dividing it by the existing range (65535 - 20000) 3. Multiply that value by the desired range (65535 - 30000) 4. Finally translate the value by adding the new minimum (and rounding it) newValue = round( ((oldValue - oldMin)/oldRange)*newRange + newMin)( I tested this for these values and results 20,000, 30,000, 40,000, and 65,535 30,000, 37,787, 45,574, and 65,535 To increase the speed, newRange/oldRange can be moved outside the loop as it is a constant. If you have a few times more pixels than 65,535 - 20,000 (45,535 + 1) and many files I suggest pre-calculating each value into an array as a lookup table. if speed matters. HTH Nate On Fri, Jun 12, 2020 at 2:32 PM Thomas Fischer <[hidden email]> wrote: > Hi everybody, > > I have a number of 16bit images. The highest gray value is 65535 in all of > them. The lowest gray value varies between 20000 and 40000. How can I > transform all images in a linear fashion leaving the highest gray value at > 65535 and set the lowest to 30000? > > With Enhance Contrast I can stretch the distribution in such a manner that > the lowest gray value is zero. But I want to stretch the distribution in > some images and condens it in others. > > Thank you, Thomas > > -- > ImageJ mailing list: https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fimagej.nih.gov%2Fij%2Flist.html&data=02%7C01%7C%7Ce8a57509af6943a4d14808d80f9ee006%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637276522322408782&sdata=r%2FwhGAIrnLekJKjNmRex4q6u4MbiSzxNF3cBwGJ3d54%3D&reserved=0 > -- ImageJ mailing list: https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fimagej.nih.gov%2Fij%2Flist.html&data=02%7C01%7C%7Ce8a57509af6943a4d14808d80f9ee006%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637276522322418776&sdata=3TWpGU7jGzY2UCW2Rjz0Ut29kCwlI4Q6N%2Few2ZVXhmM%3D&reserved=0 -- ImageJ mailing list: https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fimagej.nih.gov%2Fij%2Flist.html&data=02%7C01%7C%7Ce8a57509af6943a4d14808d80f9ee006%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637276522322418776&sdata=3TWpGU7jGzY2UCW2Rjz0Ut29kCwlI4Q6N%2Few2ZVXhmM%3D&reserved=0 -- ImageJ mailing list: https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fimagej.nih.gov%2Fij%2Flist.html&data=02%7C01%7C%7Ce8a57509af6943a4d14808d80f9ee006%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637276522322418776&sdata=3TWpGU7jGzY2UCW2Rjz0Ut29kCwlI4Q6N%2Few2ZVXhmM%3D&reserved=0 -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by foxtango
Good day Thomas,
the following macro code applies the desired linear transformation to all values of a 16bit image. (Test image appended.) // imagej-macro "linTrans" (Herbie G., 13. June 2020) requires("1.53b"); run("Revert"); w = getWidth; h = getHeight; img = getImageID; getRawStatistics( n, mn, currMin ); max = 65635; min = 30000; // desired minimum b = ( max - min ); b /= ( max - currMin ); a = max * ( 1 - b ); run("Plot Profile"); // ???? selectImage( img ); for ( j=0; j<h; j++ ) { for ( i=0; i<w; i++ ) { setPixel( i, j, linTrans( a, b, getPixel( i, j ) ) ); } } run("Plot Profile"); // ???? exit(); function linTrans( x, y, z ) { return round( x + y * z ); } // imagej-macro "linTrans" (Herbie G., 13. June 2020) Paste the above macro code to an empty macro window (Plugins >> New >> Macro), open the test image, then run the macro. With the test image you get two profiles along the image diagonal, one taken before the transformation, the other after the transformation. If your image doesn't have a selection, you must comment or eliminate the code lines denoted with "????". Please note that transforming an image per macro code is slow. You need a plugin to perform fast pixel-wise operations. Regards Herbie :::::::::::::::::::::::::::::::::::::::::::: Am 12.06.20 um 22:58 schrieb Thomas Fischer: > Hi everybody, > > I have a number of 16bit images. The highest gray value is 65535 in all of > them. The lowest gray value varies between 20000 and 40000. How can I > transform all images in a linear fashion leaving the highest gray value at > 65535 and set the lowest to 30000? > > With Enhance Contrast I can stretch the distribution in such a manner that > the lowest gray value is zero. But I want to stretch the distribution in > some images and condens it in others. > > Thank you, Thomas ImageJ mailing list: http://imagej.nih.gov/ij/list.html 20019.tif (11K) Download Attachment |
In reply to this post by foxtango
Sorry Thomas,
there was a little typo in the code! Please correct the value according to: max = 65535; Attached please find an additional test image. Regards Herbie :::::::::::::::::::::::::::::::::::::::::::: Good day Thomas, the following macro code applies the desired linear transformation to all values of a 16bit image. (Test image appended.) // imagej-macro "linTrans" (Herbie G., 13. June 2020) requires("1.53b"); run("Revert"); w = getWidth; h = getHeight; img = getImageID; getRawStatistics( n, mn, currMin ); max = 65635; min = 30000; // desired minimum b = ( max - min ); b /= ( max - currMin ); a = max * ( 1 - b ); run("Plot Profile"); // ???? selectImage( img ); for ( j=0; j<h; j++ ) { for ( i=0; i<w; i++ ) { setPixel( i, j, linTrans( a, b, getPixel( i, j ) ) ); } } run("Plot Profile"); // ???? exit(); function linTrans( x, y, z ) { return round( x + y * z ); } // imagej-macro "linTrans" (Herbie G., 13. June 2020) Paste the above macro code to an empty macro window (Plugins >> New >> Macro), open the test image, then run the macro. With the test image you get two profiles along the image diagonal, one taken before the transformation, the other after the transformation. If your image doesn't have a selection, you must comment or eliminate the code lines denoted with "????". Please note that transforming an image per macro code is slow. You need a plugin to perform fast pixel-wise operations. Regards Herbie :::::::::::::::::::::::::::::::::::::::::::: Am 12.06.20 um 22:58 schrieb Thomas Fischer: > Hi everybody, > > I have a number of 16bit images. The highest gray value is 65535 in all of > them. The lowest gray value varies between 20000 and 40000. How can I > transform all images in a linear fashion leaving the highest gray value at > 65535 and set the lowest to 30000? > > With Enhance Contrast I can stretch the distribution in such a manner that > the lowest gray value is zero. But I want to stretch the distribution in > some images and condens it in others. > > Thank you, Thomas -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by foxtango
Good day Thomas,
the following code is about 10 times faster than the previous: // imagej-macro "linTrans" (Herbie G., 14. June 2020) requires("1.53b"); run("Revert"); setOption("ScaleConversions", false); w = getWidth; h = getHeight; img = getImageID; getRawStatistics( n, mn, currMin ); max = 65535; min = 30000; // desired minimum b = ( max - min ); b /= ( max - currMin ); a = max * ( 1 - b ); run("Plot Profile"); // ???? selectImage( img ); run( "32-bit" ); run("Multiply...", "value=&b"); run("Add...", "value=&a"); run( "16-bit"); run("Plot Profile"); // ???? exit(); // imagej-macro "linTrans" (Herbie G., 14. June 2020) A plugin will be even faster... Regards Herbie :::::::::::::::::::::::::::::::::::::::::::: Sorry Thomas, there was a little typo in the code! Please correct the value according to: max = 65535; Attached please find an additional test image. Regards Herbie :::::::::::::::::::::::::::::::::::::::::::: Good day Thomas, the following macro code applies the desired linear transformation to all values of a 16bit image. (Test image appended.) // imagej-macro "linTrans" (Herbie G., 13. June 2020) requires("1.53b"); run("Revert"); w = getWidth; h = getHeight; img = getImageID; getRawStatistics( n, mn, currMin ); max = 65635; min = 30000; // desired minimum b = ( max - min ); b /= ( max - currMin ); a = max * ( 1 - b ); run("Plot Profile"); // ???? selectImage( img ); for ( j=0; j<h; j++ ) { for ( i=0; i<w; i++ ) { setPixel( i, j, linTrans( a, b, getPixel( i, j ) ) ); } } run("Plot Profile"); // ???? exit(); function linTrans( x, y, z ) { return round( x + y * z ); } // imagej-macro "linTrans" (Herbie G., 13. June 2020) Paste the above macro code to an empty macro window (Plugins >> New >> Macro), open the test image, then run the macro. With the test image you get two profiles along the image diagonal, one taken before the transformation, the other after the transformation. If your image doesn't have a selection, you must comment or eliminate the code lines denoted with "????". Please note that transforming an image per macro code is slow. You need a plugin to perform fast pixel-wise operations. Regards Herbie :::::::::::::::::::::::::::::::::::::::::::: Am 12.06.20 um 22:58 schrieb Thomas Fischer: > Hi everybody, > > I have a number of 16bit images. The highest gray value is 65535 in all of > them. The lowest gray value varies between 20000 and 40000. How can I > transform all images in a linear fashion leaving the highest gray value at > 65535 and set the lowest to 30000? > > With Enhance Contrast I can stretch the distribution in such a manner that > the lowest gray value is zero. But I want to stretch the distribution in > some images and condens it in others. > > Thank you, Thomas -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by foxtango
For those of you interested in this thread,
here is the conversion-macro for batch-processing: // imagej-macro "linTrans_Dir" (Herbie G., 15. June 2020) requires( "1.53b" ); srce = getDirectory( "Choose the Source Directory" ) dest = getDirectory( "Choose the Destination Directory" ); min = 30000; // desired minimum max = 65535; d = max - min; setOption( "ScaleConversions", false ); list = getFileList( srce ); setBatchMode( true ); for ( i=0; i<list.length; i++ ) { open( srce + list[i] ); linTrans_fast( d, max ); save( dest + list[i] ); close(); } setBatchMode( false ); exit(); function linTrans_fast( b, mx ) { getRawStatistics( n, mn, currMin ); b /= ( mx - currMin ); a = mx * ( 1 - b ); run( "32-bit" ); run( "Multiply...", "value=&b" ); run( "Add...", "value=&a" ); run( "16-bit" ); } // imagej-macro "linTrans_Dir" (Herbie G., 15. June 2020) Regards Herbie :::::::::::::::::::::::::::::::::::::::::::: Good day Thomas, the following code is about 10 times faster than the previous: // imagej-macro "linTrans" (Herbie G., 14. June 2020) requires("1.53b"); run("Revert"); setOption("ScaleConversions", false); w = getWidth; h = getHeight; img = getImageID; getRawStatistics( n, mn, currMin ); max = 65535; min = 30000; // desired minimum b = ( max - min ); b /= ( max - currMin ); a = max * ( 1 - b ); run("Plot Profile"); // ???? selectImage( img ); run( "32-bit" ); run("Multiply...", "value=&b"); run("Add...", "value=&a"); run( "16-bit"); run("Plot Profile"); // ???? exit(); // imagej-macro "linTrans" (Herbie G., 14. June 2020) A plugin will be even faster... Regards Herbie :::::::::::::::::::::::::::::::::::::::::::: Sorry Thomas, there was a little typo in the code! Please correct the value according to: max = 65535; Attached please find an additional test image. Regards Herbie :::::::::::::::::::::::::::::::::::::::::::: Good day Thomas, the following macro code applies the desired linear transformation to all values of a 16bit image. (Test image appended.) // imagej-macro "linTrans" (Herbie G., 13. June 2020) requires("1.53b"); run("Revert"); w = getWidth; h = getHeight; img = getImageID; getRawStatistics( n, mn, currMin ); max = 65635; min = 30000; // desired minimum b = ( max - min ); b /= ( max - currMin ); a = max * ( 1 - b ); run("Plot Profile"); // ???? selectImage( img ); for ( j=0; j<h; j++ ) { for ( i=0; i<w; i++ ) { setPixel( i, j, linTrans( a, b, getPixel( i, j ) ) ); } } run("Plot Profile"); // ???? exit(); function linTrans( x, y, z ) { return round( x + y * z ); } // imagej-macro "linTrans" (Herbie G., 13. June 2020) Paste the above macro code to an empty macro window (Plugins >> New >> Macro), open the test image, then run the macro. With the test image you get two profiles along the image diagonal, one taken before the transformation, the other after the transformation. If your image doesn't have a selection, you must comment or eliminate the code lines denoted with "????". Please note that transforming an image per macro code is slow. You need a plugin to perform fast pixel-wise operations. Regards Herbie :::::::::::::::::::::::::::::::::::::::::::: Am 12.06.20 um 22:58 schrieb Thomas Fischer: > Hi everybody, > > I have a number of 16bit images. The highest gray value is 65535 in all of > them. The lowest gray value varies between 20000 and 40000. How can I > transform all images in a linear fashion leaving the highest gray value at > 65535 and set the lowest to 30000? > > With Enhance Contrast I can stretch the distribution in such a manner that > the lowest gray value is zero. But I want to stretch the distribution in > some images and condens it in others. > > Thank you, Thomas -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Free forum by Nabble | Edit this page |