Hi!
I'm working on some threshold methods, and came across the source for the colour threshold tool, which had a conversion matrix (for RGB to XYZ) slightly different from the one I'm used to seeing. From ColorThresholder.java source: public void getLab(ImageProcessor ip, byte[] L, byte[] a, byte[] b) { ... X = 0.430587 * rf + 0.341545 * gf + 0.178336 * bf; Y = 0.222021 * rf + 0.706645 * gf + 0.0713342* bf; Z = 0.0201837* rf + 0.129551 * gf + 0.939234 * bf; ... } From ColorSpaceConverter.java source: public double[][] M = {{0.4124, 0.3576, 0.1805}, {0.2126, 0.7152, 0.0722}, {0.0193, 0.1192, 0.9505}}; Maybe there is an extra calculation step I've overlooked which compensates for this discrepancy, but I didn't see it. Any reason why this is different? Sincerely, Jonas Ogaard Research Institute for Internal Medicine Oslo University Hospital Rikshospitalet -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Hi Jonas,
to some degree, the difference of the RGB<->Lab converters seems to be the white point. In this respect, note that the ColorSpaceConverter divides x, y, z by the white point tristimulus; it seems to me that the ColorThresholder doesn't. But that does not explain all of the discrepancy. In addition, there are different procedures around for different definitions of RGB color spaces such as sRGB. Also, there are several Lab color space definitions around; as I understand it even different CIELab spaces. In practice, as long as you don't do very careful color management in all your acquisition and processing, I think that the inconsistencies in the code are not very important (but I agree that they are not very nice). Michael ________________________________________________________________ On May 7, 2015, at 10:18, Jonas Øgaard wrote: > Hi! > > I'm working on some threshold methods, and came across the source for the > colour threshold tool, which had a conversion matrix (for RGB to XYZ) > slightly different from the one I'm used to seeing. > > From ColorThresholder.java source: > > public void getLab(ImageProcessor ip, byte[] L, byte[] a, byte[] b) { > > ... > > X = 0.430587 * rf + 0.341545 * gf + 0.178336 * bf; > Y = 0.222021 * rf + 0.706645 * gf + 0.0713342* bf; > Z = 0.0201837* rf + 0.129551 * gf + 0.939234 * bf; > > ... > > } > > > From ColorSpaceConverter.java source: > > public double[][] M = {{0.4124, 0.3576, 0.1805}, > {0.2126, 0.7152, 0.0722}, > {0.0193, 0.1192, 0.9505}}; > > > Maybe there is an extra calculation step I've overlooked which compensates > for this discrepancy, but I didn't see it. > > Any reason why this is different? > > Sincerely, > > Jonas Ogaard > Research Institute for Internal Medicine > Oslo University Hospital Rikshospitalet > > -- > 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 Jonas Øgaard
Hello Jonas,
from what I see the linear mapping in ColorSpaceConverter.java appears to be correct, assuming that *linear* RGB components are used for the transformation (i.e., no Gamma-corrected sRGB values!). Because of the built-in nonlinearities, the CIE-transformations are generally quite sensitive to small inaccuracies of the matrix values, such that inverse transformations often do not give proper results. Many implementations do have this problem. For comparison, you may want to have a look at our Lab color space implementation (among others) to be found here: http://sourceforge.net/p/imagingbook/code/HEAD/tree/trunk/common/src-common/imagingbook/pub/color/image/LabColorSpace.java --Wilhelm www.imagingbook.com http://sourceforge.net/projects/imagingbook > -----Original Message----- > From: ImageJ Interest Group [mailto:[hidden email]] On Behalf Of > Jonas Øgaard > Sent: Thursday, May 07, 2015 10:19 AM > To: [hidden email] > Subject: RGB to LAB (via XYZ) as per ColorSpaceConverter.java vs Colour > Thresholder > > Hi! > > I'm working on some threshold methods, and came across the source for the > colour threshold tool, which had a conversion matrix (for RGB to XYZ) > slightly different from the one I'm used to seeing. > > From ColorThresholder.java source: > > public void getLab(ImageProcessor ip, byte[] L, byte[] a, byte[] b) { > > ... > > X = 0.430587 * rf + 0.341545 * gf + 0.178336 * bf; > Y = 0.222021 * rf + 0.706645 * gf + 0.0713342* bf; > Z = 0.0201837* rf + 0.129551 * gf + 0.939234 * bf; > > ... > > } > > > From ColorSpaceConverter.java source: > > public double[][] M = {{0.4124, 0.3576, 0.1805}, > {0.2126, 0.7152, 0.0722}, > {0.0193, 0.1192, 0.9505}}; > > > Maybe there is an extra calculation step I've overlooked which compensates > for this discrepancy, but I didn't see it. > > Any reason why this is different? > > Sincerely, > > Jonas Ogaard > Research Institute for Internal Medicine > Oslo University Hospital Rikshospitalet > > -- > 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 Jonas Øgaard
On Thursday 07 May 2015 10:18:52 Jonas Øgaard wrote:
> Hi! > > I'm working on some threshold methods, and came across the source for the > colour threshold tool, which had a conversion matrix (for RGB to XYZ) > slightly different from the one I'm used to seeing. > > Maybe there is an extra calculation step I've overlooked which compensates > for this discrepancy, but I didn't see it. > > Any reason why this is different? The one in the colour threshold is probably originating from the Threshold_Colour plugin. The values in there were -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Burger Wilhelm
Hi,
Thanks for getting back on this. I understand that there are slight variations in the conversion schemes used in different systems, but for there to be two different implementations (with different parameters) of the same procedure within the same software seems a bit odd to me. I've tested the thresholds up against external libraries such as libvips and opencv, at first checking only against the code used in the RGB<->LAB converter. Everything seemed honkey dorey in theory, but the thresholding (in ImageJ) was still off. It took me a while to figure out that there are TWO different algorithms doing thresholding and RGB<->LAB conversion. I will most likely do a rewrite of the thresholder for in-house usage. Is Landini still maintaining the Thresholding code? Sincerely, Jonas Ogaard On Thu, May 7, 2015 at 5:24 PM, Burger Wilhelm < [hidden email]> wrote: > Hello Jonas, > > from what I see the linear mapping in ColorSpaceConverter.java appears to > be correct, assuming that *linear* RGB components are used for the > transformation (i.e., no Gamma-corrected sRGB values!). Because of the > built-in nonlinearities, the CIE-transformations are generally quite > sensitive to small inaccuracies of the matrix values, such that inverse > transformations often do not give proper results. Many implementations do > have this problem. For comparison, you may want to have a look at our Lab > color space implementation (among others) to be found here: > > > http://sourceforge.net/p/imagingbook/code/HEAD/tree/trunk/common/src-common/imagingbook/pub/color/image/LabColorSpace.java > > > --Wilhelm > www.imagingbook.com > http://sourceforge.net/projects/imagingbook > > > > > -----Original Message----- > > From: ImageJ Interest Group [mailto:[hidden email]] On Behalf Of > > Jonas Øgaard > > Sent: Thursday, May 07, 2015 10:19 AM > > To: [hidden email] > > Subject: RGB to LAB (via XYZ) as per ColorSpaceConverter.java vs Colour > > Thresholder > > > > Hi! > > > > I'm working on some threshold methods, and came across the source for the > > colour threshold tool, which had a conversion matrix (for RGB to XYZ) > > slightly different from the one I'm used to seeing. > > > > From ColorThresholder.java source: > > > > public void getLab(ImageProcessor ip, byte[] L, byte[] a, byte[] b) { > > > > ... > > > > X = 0.430587 * rf + 0.341545 * gf + 0.178336 * bf; > > Y = 0.222021 * rf + 0.706645 * gf + 0.0713342* bf; > > Z = 0.0201837* rf + 0.129551 * gf + 0.939234 * bf; > > > > ... > > > > } > > > > > > From ColorSpaceConverter.java source: > > > > public double[][] M = {{0.4124, 0.3576, 0.1805}, > > {0.2126, 0.7152, 0.0722}, > > {0.0193, 0.1192, 0.9505}}; > > > > > > Maybe there is an extra calculation step I've overlooked which > compensates > > for this discrepancy, but I didn't see it. > > > > Any reason why this is different? > > > > Sincerely, > > > > Jonas Ogaard > > Research Institute for Internal Medicine > > Oslo University Hospital Rikshospitalet > > > > -- > > 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 Jonas Øgaard
On Thursday 07 May 2015 10:18:52 Jonas Øgaard wrote:
> I'm working on some threshold methods, and came across the source for the > colour threshold tool, which had a conversion matrix (for RGB to XYZ) > slightly different from the one I'm used to seeing. > > Maybe there is an extra calculation step I've overlooked which compensates > for this discrepancy, but I didn't see it. Oops! message sent before finished. The colour threshold built in IJ is probably originating from the Threshold_Colour plugin which I modified from an early plugin HSB thresholder by Bob Dougherty The values were taken at that time from: http://www.brucelindbloom.com/index.html?WorkingSpaceInfo.html#Specifications http://www.easyrgb.com/math.php?MATH=M7#text7 I found that the matrix in the plugin is the PAL/SECAM D5 : http://www.thomasdideriksen.dk/misc/File%20Formats/XYZ-RGB%20Matrices.pdf and yours is the sRGB to XYZ one. If there is a compelling reason to change it to sRGB, please let me know as I would like to keep the Threshold_Colour plugin changes synchronised and might affect some other code as well. Cheers Gabriel -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Jonas Øgaard
On Thursday 07 May 2015 17:35:10 Jonas Øgaard wrote:
> I understand that there are slight variations in the conversion schemes > used in different systems, but for there to be two different > implementations (with different parameters) of the same procedure within > the same software seems a bit odd to me. It should not be difficult to understand, considering that the hundreds of plugins available are written by different people at different times, most often independently, so there is no guarantee that implementations are identical. We should be happy that the code is available and we can find these things out. > I've tested the thresholds up against external libraries such as libvips > and opencv, at first checking only against the code used in the RGB<->LAB > converter. Everything seemed honkey dorey in theory, but the thresholding > (in ImageJ) was still off. It took me a while to figure out that there are > TWO different algorithms doing thresholding and RGB<->LAB conversion. The other issue that you should consider is that the threshold colour plugin uses 8bit containers to store the Lab and other colour spaces channels. So the resolution of the components will be different to what you get if you store results in 32bit images which is what the colour space converter does. Unfortunately ImageJ does not support 32bit RGB images so the thresholder does what it can be practically achieved at the moment. Also note that most thresholding methods support 8 (and some 16bit) histograms. If you try to process a 32bit greyscale image, it is first binned down and the threshold computed from the binned image. > I will most likely do a rewrite of the thresholder for in-house usage. Is > Landini still maintaining the Thresholding code? Yes, I am maintaining the original version in this page: http://www.mecourse.com/landinig/software/software.html As I mentioned earlier, the colour threshold in ImageJ appeared later and I believe that it is based on that code (Wayne would be able to confirm this). I would happily consider changing to the sRBG D65 matrix in that plugin instead of the PAL/SECAM one, for compatibility with other libraries and perhaps Wayne would also would do so with the built-in code in IJ. I also would be grateful for other people's opinions, on whether this is the best option. Regards Gabriel -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Jonas Øgaard
On May 7, 2015, at 4:18 AM, Jonas Øgaard <[hidden email]> wrote:
> > Hi! > > I'm working on some threshold methods, and came across the source for the > colour threshold tool, which had a conversion matrix (for RGB to XYZ) > slightly different from the one I'm used to seeing. > > From ColorThresholder.java source: > > public void getLab(ImageProcessor ip, byte[] L, byte[] a, byte[] b) { > > ... > > X = 0.430587 * rf + 0.341545 * gf + 0.178336 * bf; > Y = 0.222021 * rf + 0.706645 * gf + 0.0713342* bf; > Z = 0.0201837* rf + 0.129551 * gf + 0.939234 * bf; > > ... > > } > > > From ColorSpaceConverter.java source: > > public double[][] M = {{0.4124, 0.3576, 0.1805}, > {0.2126, 0.7152, 0.0722}, > {0.0193, 0.1192, 0.9505}}; > > > Maybe there is an extra calculation step I've overlooked which compensates > for this discrepancy, but I didn't see it. > > Any reason why this is different? In the latest ImageJ daily build (1.49t10), the ColorThresholder (Image>Adjust>Color Threshold) uses the ColorSpaceConverter (Image>Type>Lab Stack) to do RGB to Lab conversions, so there is no longer a discrepancy. -wayne -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Michael Schmid
**It seems some emails are getting dropped between me and the mailing list,
I apologize if there are double postings coming in.** On Thu, May 7, 2015 at 6:15 PM, Gabriel Landini <[hidden email]> wrote: > > The colour threshold built in IJ is probably originating from the > Threshold_Colour plugin which I modified from an early plugin HSB > thresholder > by Bob Dougherty > The values were taken at that time from: > > http://www.brucelindbloom.com/index.html?WorkingSpaceInfo.html#Specifications > http://www.easyrgb.com/math.php?MATH=M7#text7 > > I found that the matrix in the plugin is the PAL/SECAM D5 : > http://www.thomasdideriksen.dk/misc/File%20Formats/XYZ-RGB%20Matrices.pdf > and yours is the sRGB to XYZ one. > > If there is a compelling reason to change it to sRGB, please let me know > as I > would like to keep the Threshold_Colour plugin changes synchronised and > might > affect some other code as well. > > Cheers > > Gabriel Ah now I understand. I'm guessing for most people it doesn't quite make a difference, as long as the analysis is based on the thresholds/alterations directly from the Threshold_Colour code (as I have myself for quite a few years). There are a couple of pros and cons I can think of from the top of my head, the biggest two of which would be: Con: The fact that the thresholding values based on PAL/SECAM is what people are expecting when using the plug-in these days (i.e. rerunning past tests would yield different results if using a new matrix). Pro: On the other hand, since methods available on several other image analysis suites (including the code in ColorSpaceConverter.java of ImageJ) assumes values in the sRGB (with D65 white point) format as default, it makes sense to at least offer this (as an alternative) to bridge compatibility. For my own part, as long as I'm aware of it (which I should have been from reading the source of your original matrix - afterall it is pretty explicitly stated ;-) I'm fine. Thank you very much for helping me pin down the problem! Sometimes colour theory beat my head in! > > I understand that there are slight variations in the conversion schemes > > used in different systems, but for there to be two different > > implementations (with different parameters) of the same procedure within > > the same software seems a bit odd to me. > > It should not be difficult to understand, considering that the hundreds of > plugins available are written by different people at different times, most > often independently, so there is no guarantee that implementations are > identical. We should be happy that the code is available and we can find these > things out. > > contribution both you and the other authors have made to the code behind ImageJ and it's plugins -- I did not mean to criticize! My concern was coined part because I was not sure if they were different intentionally, and part because they are such important toolsets (at least to my workflows) which may have severe analytical side effects if not 'synchronized'. The other issue that you should consider is that the threshold colour plugin > uses 8bit containers to store the Lab and other colour spaces channels. So the > resolution of the components will be different to what you get if you store > results in 32bit images which is what the colour space converter does. > > Unfortunately ImageJ does not support 32bit RGB images so the thresholder does > what it can be practically achieved at the moment. Also note that most > thresholding methods support 8 (and some 16bit) histograms. If you try to > process a 32bit greyscale image, it is first binned down and the threshold > computed from the binned image. > > I have indeed seen slight variations (~1point/256) due to different deviation from the sRGB vs PAL/SECAM. > I will most likely do a rewrite of the thresholder for in-house usage. Is > > Landini still maintaining the Thresholding code? > > Yes, I am maintaining the original version in this page:http://www.mecourse.com/landinig/software/software.html > As I mentioned earlier, the colour threshold in ImageJ appeared later and I > believe that it is based on that code (Wayne would be able to confirm this). > > I would happily consider changing to the sRBG D65 matrix in that plugin > instead of the PAL/SECAM one, for compatibility with other libraries and > perhaps Wayne would also would do so with the built-in code in IJ. > I also would be grateful for other people's opinions, on whether this is the > best option. > > Setting aside what I've already mentioned about benefiting from using the same colorprofile within different modules/plugins/functionalities of ImageJ, very little colorimetric/photo-equiment these days yield PAL profiled images. On the other hand, a ridiculous high percentage (~99%) are based on sRGB. While it may have made sense to originally write a thresholder for a specific workflow involving a PAL-encoding image capturing device, these days images are (mostly) coded with sRGB. As for a practical resolution: Adding a duplicate LAB-option, labelled sRGB while keeping the PAL/SECAM one either as LAB or LAB (original). Alternatively adding a second select box to chose color profile. Thank you again very much for all your kind feedback, and great code behind ImageJ. I hope to one day be able to repay my gratitude with some plugins of my own! Sincerely, Jonas Ogaard -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Rasband, Wayne (NIH/NIMH) [E]
On Friday 08 May 2015 05:02:56 Wayne wrote:
> In the latest ImageJ daily build (1.49t10), the ColorThresholder > (Image>Adjust>Color Threshold) uses the ColorSpaceConverter (Image>Type>Lab > Stack) to do RGB to Lab conversions, so there is no longer a discrepancy. Thanks Wayne. The plugin at my page is also modified accordingly. Cheers Gabriel -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Hi,
Awesome Wayne! I checked out the daily build - the resulting values are still showing deviance from what you get by running single channel L-channel thresholding after RGB->LAB conversion. Specifically L-values of 197 and upwards are blank, whereas by manually using RGB->LAB (in all my test images) the L-channel is populated all the way to maximum (100). I'm guessing it's an issue with normalization, although I've got a hard time explaining why the new maxima is at 196... Sincerely, Jonas Ogaard On Fri, May 8, 2015 at 1:48 PM, Gabriel Landini <[hidden email]> wrote: > On Friday 08 May 2015 05:02:56 Wayne wrote: > > In the latest ImageJ daily build (1.49t10), the ColorThresholder > > (Image>Adjust>Color Threshold) uses the ColorSpaceConverter > (Image>Type>Lab > > Stack) to do RGB to Lab conversions, so there is no longer a discrepancy. > > Thanks Wayne. The plugin at my page is also modified accordingly. > Cheers > > Gabriel > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
On Saturday 09 May 2015 08:54:02 Jonas Øgaard wrote:
> I checked out the daily build - the resulting values are still showing > deviance from what you get by running single channel L-channel thresholding > after RGB->LAB conversion. Specifically L-values of 197 and upwards are > blank, whereas by manually using RGB->LAB (in all my test images) the > L-channel is populated all the way to maximum (100). Hi Jonas, I convert RGB to LSB and now the histograms of the colour thresholder and the one from the Histogram command on the 32bit Lab stack show pretty much the same distribution (save the change in vertical scale and the previously mention binning an of the histograms). Not sure if this is is causing confusion, but just in case: the sliders of the colour thresholder actually do not show the Lab values, but the 8bit histogram where the channel values have been packed into. More importantly, they span the maximum *possible* range (not actual min and max values in the image) of L. While the default histogram of the L channel in the 32bit stack would also be 8bit, but restricted to the min and max valued *in the image*). So if you want an autothreshold algorithm to perform the same as the applet perhaps you need to scale the 32bit images to the possible Lab ranges (L:0..100. a and b: -125...125 or -128...128 depending on the implementation). Alternatively please provide an example and description of the exact procedure you are following so we can be reproduce it. Cheers Gabriel -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Hi again,
I've set up some test images to clarify what happens at my end: Image: http://y9.no/test.png Histograms: http://y9.no/histograms.jpg Here you see the two histograms of the RGB->LAB converted image, packed to occuring values (top left) and to available values (lower left). The threshold however, is skewed far towards left. Do you mean that the histogram packs light range dynamically such that maximum (=100) will always be the most intense pixel in the image? Note that since there are values at maximum in my image, it probably means it is slightly over exposed, but that doesn't really affect the Lab-ranges (aside from having brightness occurring at max levels). What I would expect to see would be the histogram of available values (lower left) to be identifcal to thresholding histogram. Please let me know if I have misunderstood anything -- it may very well be :D Sincerely, Jonas Ogaard On Sat, May 9, 2015 at 10:46 AM, Gabriel Landini <[hidden email]> wrote: > On Saturday 09 May 2015 08:54:02 Jonas Øgaard wrote: > > I checked out the daily build - the resulting values are still showing > > deviance from what you get by running single channel L-channel > thresholding > > after RGB->LAB conversion. Specifically L-values of 197 and upwards are > > blank, whereas by manually using RGB->LAB (in all my test images) the > > L-channel is populated all the way to maximum (100). > > Hi Jonas, > I convert RGB to LSB and now the histograms of the colour thresholder and > the > one from the Histogram command on the 32bit Lab stack show pretty much the > same distribution (save the change in vertical scale and the previously > mention binning an of the histograms). > > Not sure if this is is causing confusion, but just in case: the sliders of > the > colour thresholder actually do not show the Lab values, but the 8bit > histogram > where the channel values have been packed into. More importantly, they span > the maximum *possible* range (not actual min and max values in the image) > of > L. While the default histogram of the L channel in the 32bit stack would > also > be 8bit, but restricted to the min and max valued *in the image*). > > So if you want an autothreshold algorithm to perform the same as the applet > perhaps you need to scale the 32bit images to the possible Lab ranges > (L:0..100. a and b: -125...125 or -128...128 depending on the > implementation). > > Alternatively please provide an example and description of the exact > procedure > you are following so we can be reproduce it. > Cheers > > Gabriel > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
On Saturday 09 May 2015 12:08:34 you wrote:
> Here you see the two histograms of the RGB->LAB converted image, packed to > occuring values (top left) and to available values (lower left). > The threshold however, is skewed far towards left. Ah, yes I see what you mean now. The previous version had the L component correctly scaled, but the current version does not. I believe the L channel is being scaled to 125, when in reality it should be to 100. This is the line I believe needs to be changed (125 to 100) in ColorThresholder.java int L1 = (int) Math.round((values[0] / 125.0) * 245.0); but I am not exactly sure why the next number is 245 instead of 255... Wayne might be able to clarify this. I see that the a and b components are also scaled this way to 245. int a1 = (int) Math.round(((values[1] + 125.0) / 250.0) * 245.0); int b1 = (int) Math.round(((values[2] + 125.0) / 250.0) * 245.0); > Do you mean that the histogram packs light range dynamically such that > maximum (=100) will always be the most intense pixel in the image? What I mean is that the default "Histogram command" on the 32bit image generated by hand: RGB to Lab Stack uses the image value range to define the histogram range. So the bin width will be different (wider) than if you pack the whole range of possible values (what the applet does). Consequently applying the same autothreshold procedure to two (slightly) different histograms might not give exactly the same result. You would need to scale to the the colour space range to get the same results by hand and with the applet. Regards Gabriel -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
On May 9, 2015, at 6:46 AM, Gabriel Landini <[hidden email]> wrote:
> > On Saturday 09 May 2015 12:08:34 you wrote: >> Here you see the two histograms of the RGB->LAB converted image, packed to >> occuring values (top left) and to available values (lower left). > >> The threshold however, is skewed far towards left. > > Ah, yes I see what you mean now. The previous version had the L component > correctly scaled, but the current version does not. I believe the L channel is > being scaled to 125, when in reality it should be to 100. This is the line I > believe needs to be changed (125 to 100) in ColorThresholder.java > > int L1 = (int) Math.round((values[0] / 125.0) * 245.0); > > but I am not exactly sure why the next number is 245 instead of 255... > Wayne might be able to clarify this. In yesterday’s daily build, the ColorThresholder was scaling using code taken from the Color Space Converter plugin at http://imagej.nih.gov/ij/plugins/color-space-converter.html This is the plugin that the Image>Type>Lab Stack command is based on. In today’s daily build (1.49t13), scaling is done the using L = (int) (values[0] * 2.55); a = (int) (Math.floor((1.0625 * values[1] + 128) + 0.5)); b = (int) (Math.floor((1.0625 * values[2] + 128) + 0.5)); which is the way it was done in the original version of the ColorThresholder. The ‘L' values are assumed to have a range of 0 to 100 and the ‘a’ and ‘b’ values are assumed to have a range of -120 to 120. -wayne > I see that the a and b components are also scaled this way to 245. > > int a1 = (int) Math.round(((values[1] + 125.0) / 250.0) * 245.0); > int b1 = (int) Math.round(((values[2] + 125.0) / 250.0) * 245.0); > >> Do you mean that the histogram packs light range dynamically such that >> maximum (=100) will always be the most intense pixel in the image? > > What I mean is that the default "Histogram command" on the 32bit image > generated by hand: RGB to Lab Stack uses the image value range to define the > histogram range. So the bin width will be different (wider) than if you pack > the whole range of possible values (what the applet does). Consequently > applying the same autothreshold procedure to two (slightly) different > histograms might not give exactly the same result. You would need to scale to > the the colour space range to get the same results by hand and with the > applet. > > Regards > > Gabriel > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
I can't either quite understand why values of 245 were used, nor the -120
to 120 in the current version (typically -127 to 127 are used at convenience of 8-bit precision) -- however it may be in line with different implementation of the LAB/XYZ algorithm, since it appears to yield correct results (in all ImageJ RGB->LAB and ImageJ Thresholder and OpenCV and libVips). Thank you for your efforts and patience. You have made me a very happy number cruncher! Sincerely, Jonas Ogaard On Sat, May 9, 2015 at 6:07 PM, Rasband, Wayne (NIH/NIMH) [E] < [hidden email]> wrote: > On May 9, 2015, at 6:46 AM, Gabriel Landini <[hidden email]> wrote: > > > > On Saturday 09 May 2015 12:08:34 you wrote: > >> Here you see the two histograms of the RGB->LAB converted image, packed > to > >> occuring values (top left) and to available values (lower left). > > > >> The threshold however, is skewed far towards left. > > > > Ah, yes I see what you mean now. The previous version had the L component > > correctly scaled, but the current version does not. I believe the L > channel is > > being scaled to 125, when in reality it should be to 100. This is the > line I > > believe needs to be changed (125 to 100) in ColorThresholder.java > > > > int L1 = (int) Math.round((values[0] / 125.0) * 245.0); > > > > but I am not exactly sure why the next number is 245 instead of 255... > > Wayne might be able to clarify this. > > In yesterday’s daily build, the ColorThresholder was scaling using code > taken from the Color Space Converter plugin at > > http://imagej.nih.gov/ij/plugins/color-space-converter.html > > This is the plugin that the Image>Type>Lab Stack command is based on. In > today’s daily build (1.49t13), scaling is done the using > > L = (int) (values[0] * 2.55); > a = (int) (Math.floor((1.0625 * values[1] + 128) + 0.5)); > b = (int) (Math.floor((1.0625 * values[2] + 128) + 0.5)); > > which is the way it was done in the original version of the > ColorThresholder. The ‘L' values are assumed to have a range of 0 to 100 > and the ‘a’ and ‘b’ values are assumed to have a range of -120 to 120. > > -wayne > > > I see that the a and b components are also scaled this way to 245. > > > > int a1 = (int) Math.round(((values[1] + 125.0) / 250.0) * 245.0); > > int b1 = (int) Math.round(((values[2] + 125.0) / 250.0) * 245.0); > > > >> Do you mean that the histogram packs light range dynamically such that > >> maximum (=100) will always be the most intense pixel in the image? > > > > What I mean is that the default "Histogram command" on the 32bit image > > generated by hand: RGB to Lab Stack uses the image value range to define > the > > histogram range. So the bin width will be different (wider) than if you > pack > > the whole range of possible values (what the applet does). Consequently > > applying the same autothreshold procedure to two (slightly) different > > histograms might not give exactly the same result. You would need to > scale to > > the the colour space range to get the same results by hand and with the > > applet. > > > > Regards > > > > Gabriel > > > > -- > > 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 |