I have created a synthetic slanted edge image on photoshop to test the available MTF measuring tools. The tools I tested were the following:
MTF Mapper.
sfrmat2.
sfrmat3.
SE_MTF_2xNyquist (ImageJ).
MTF Mapper looks like a great and easy to use tool, but I have encountered two problems:
The values of the calculated MTF are different from the other tools.
I was not able to plot the MTF with the cycles/mm or linepairs/mm units instead of cycles/pixel.
I have not changed any setting in any of these tools. Am I doing something wrong?
Please find attached the image I used to perform the measurement and the results.
I had a quick look at the attached "test_mtf.jpg". The file does not appear to have an embedded ICC profile, so MTF Mapper assumes that the contents of the image is encoded using an sRGB TRC (basically, that the image has gamma = 2.2, although I use the actual sRGB TRC).
If the file actually has a linear TRC (or no TRC, or gamma = 1.0) then this is the cause of the difference you are seeing between MTF Mapper and the other tools. I think that they assume (by default) that the image intensity has a linear encoding; I have seen some evidence that suggests that sfrmat always treats the data as a linear encoding; not sure about the ImageJ plugin.
If you know that the image actually has a linear encoding (maybe because you used a linear colour space in Photoshop), then you can override MTF Mapper's default behaviour with the "-l" or "--linear" options (somewhat inaccurately called "Linear gamma (8-bit)" in the preferences dialogue of the GUI). That should produce the same curves as the other tools.
(Just for completeness, I would like to mention that MTF Mapper assumes that 16-bit images use a linear encoding, unless the image file contains an ICC profile.)
As for the lp/mm question: converting between cycles/pixel and lp/mm is just a straightforward scaling of the frequency axis. You have to know the pixel size (or more accurately, the photosite pitch of the sensor). Let us say your pixel size is 4.0 micron. The conversion from cycles/pixel to lp/mm is then just
f_lpmm = f_cp * (1000 / 4.0)
where f_cp is the resolution in cycles/pixel. You appear to be extracting MTF Mapper's SFR curve (either from "edge_sfr_values.txt" or "raw_sfr_values.txt"). In that case, as you probably already know, you can assume that f_cp = i/64 where i runs from 0 to 63 to cover the 64 values in the SFR curve. I give an equivalent scaling in the MTF Mapper user guide (section 9, page 38, equation 1) if you know the sensor height and number of pixels (in the sensor height direction).
You can ask MTF Mapper to produce some of its outputs in lp/mm, but the frequency scale of the SFR curve outputs will always be in cycles/pixel, even if you use the "--pixelsize" option to tell MTF Mapper what the pixel size is. I suppose I could produce a new output file that explicitly provides the spatial frequency values corresponding to each point on the SFR curve, but I cannot change the format of the existing files without breaking a lot of scripts people wrote to ingest MTF Mapper outputs.
Lastly, I should add that that you can use the mtf_generate_rectangle tool included with MTF Mapper to produce synthetic images that have a known analytical MTF/SFR curve. The tool currently supports Gaussian PSFs, as well as lens diffraction + photosite aperture models, some with added aberrations. The images produced by this tool have been tested/validated by other users. The SFR of your attached "test_mtf.jpg" image is relatively "soft", so producing it in Photoshop is ok, but keep in mind that Photoshop cannot accurately simulate much sharper edges, unless you do your own supersampling using Photoshop. Just to give an example, you can produce an image of a square using the command:
mtf_generate_rectangle -l -d 500 -n 0 -m 0.07 -a 3.5 -o test_gaussian.png
which will produce an 8-bit linear intensity image containing a square with edges that are 500 pixels in length, tilted at 3.5 degrees, with zero simulated noise. The simulated PSF (and thus MTF) in this case will be a Gaussian, with an MTF50 value of 0.07 cycles/pixel. I usually replace the "-l" flag (which specifies that the output image must have its intensity encoded using an 8-bit linear encoding, as opposed to 8-bit with sRGB encoding) with "--b16", which gives you a 16-bit image with linear encoding.
You can directly use the mtf_generate_rectangle tool to produce an image containing a single edge by specifying a target polygon (--target-poly option) --- let me know if you would like more details on this process. The main advantage of using mtf_generate_rectangle is that you can easily created slanted edges with very sharp PSFs, e.g., one with an MTF50 value of 0.45 cycles/pixel (which is quite sharp), corresponding to a Gaussian PSF with a standard deviation of 0.416 pixels, which cannot be generated accurately in e.g. Photoshop unless you script some kind of supersampling.
-Frans
Last edit: Frans van den Bergh 2019-03-18
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hello!
I have created a synthetic slanted edge image on photoshop to test the available MTF measuring tools. The tools I tested were the following:
MTF Mapper looks like a great and easy to use tool, but I have encountered two problems:
I have not changed any setting in any of these tools. Am I doing something wrong?
Please find attached the image I used to perform the measurement and the results.
Last edit: Lucas Martinelli Reia 2019-03-18
Hi Lucas,
I had a quick look at the attached "test_mtf.jpg". The file does not appear to have an embedded ICC profile, so MTF Mapper assumes that the contents of the image is encoded using an sRGB TRC (basically, that the image has gamma = 2.2, although I use the actual sRGB TRC).
If the file actually has a linear TRC (or no TRC, or gamma = 1.0) then this is the cause of the difference you are seeing between MTF Mapper and the other tools. I think that they assume (by default) that the image intensity has a linear encoding; I have seen some evidence that suggests that sfrmat always treats the data as a linear encoding; not sure about the ImageJ plugin.
If you know that the image actually has a linear encoding (maybe because you used a linear colour space in Photoshop), then you can override MTF Mapper's default behaviour with the "-l" or "--linear" options (somewhat inaccurately called "Linear gamma (8-bit)" in the preferences dialogue of the GUI). That should produce the same curves as the other tools.
(Just for completeness, I would like to mention that MTF Mapper assumes that 16-bit images use a linear encoding, unless the image file contains an ICC profile.)
As for the lp/mm question: converting between cycles/pixel and lp/mm is just a straightforward scaling of the frequency axis. You have to know the pixel size (or more accurately, the photosite pitch of the sensor). Let us say your pixel size is 4.0 micron. The conversion from cycles/pixel to lp/mm is then just
f_lpmm = f_cp * (1000 / 4.0)
where f_cp is the resolution in cycles/pixel. You appear to be extracting MTF Mapper's SFR curve (either from "edge_sfr_values.txt" or "raw_sfr_values.txt"). In that case, as you probably already know, you can assume that f_cp = i/64 where i runs from 0 to 63 to cover the 64 values in the SFR curve. I give an equivalent scaling in the MTF Mapper user guide (section 9, page 38, equation 1) if you know the sensor height and number of pixels (in the sensor height direction).
You can ask MTF Mapper to produce some of its outputs in lp/mm, but the frequency scale of the SFR curve outputs will always be in cycles/pixel, even if you use the "--pixelsize" option to tell MTF Mapper what the pixel size is. I suppose I could produce a new output file that explicitly provides the spatial frequency values corresponding to each point on the SFR curve, but I cannot change the format of the existing files without breaking a lot of scripts people wrote to ingest MTF Mapper outputs.
Lastly, I should add that that you can use the mtf_generate_rectangle tool included with MTF Mapper to produce synthetic images that have a known analytical MTF/SFR curve. The tool currently supports Gaussian PSFs, as well as lens diffraction + photosite aperture models, some with added aberrations. The images produced by this tool have been tested/validated by other users. The SFR of your attached "test_mtf.jpg" image is relatively "soft", so producing it in Photoshop is ok, but keep in mind that Photoshop cannot accurately simulate much sharper edges, unless you do your own supersampling using Photoshop. Just to give an example, you can produce an image of a square using the command:
mtf_generate_rectangle -l -d 500 -n 0 -m 0.07 -a 3.5 -o test_gaussian.png
which will produce an 8-bit linear intensity image containing a square with edges that are 500 pixels in length, tilted at 3.5 degrees, with zero simulated noise. The simulated PSF (and thus MTF) in this case will be a Gaussian, with an MTF50 value of 0.07 cycles/pixel. I usually replace the "-l" flag (which specifies that the output image must have its intensity encoded using an 8-bit linear encoding, as opposed to 8-bit with sRGB encoding) with "--b16", which gives you a 16-bit image with linear encoding.
You can directly use the mtf_generate_rectangle tool to produce an image containing a single edge by specifying a target polygon (--target-poly option) --- let me know if you would like more details on this process. The main advantage of using mtf_generate_rectangle is that you can easily created slanted edges with very sharp PSFs, e.g., one with an MTF50 value of 0.45 cycles/pixel (which is quite sharp), corresponding to a Gaussian PSF with a standard deviation of 0.416 pixels, which cannot be generated accurately in e.g. Photoshop unless you script some kind of supersampling.
-Frans
Last edit: Frans van den Bergh 2019-03-18