Main Content

measureSharpness

Measure spatial frequency response using test chart

Description

esfrChart Object

Use an esfrChart object when you want to automatically detect the slanted-edge regions of interest (ROIs) of an Enhanced or Extended version of the Imatest® eSFR test chart [1].

sharpnessValues = measureSharpness(chart) measures the spatial frequency response (SFR) at all slanted-edge ROIs of an Imatest eSFR test chart.

sharpnessValues = measureSharpness(chart,Name=Value) adjusts the ROIs and measurements using name-value arguments. For example, you can specify the values of the frequency response at which to report the corresponding spatial frequency by using the PercentResponse name-value argument.

example

[sharpnessValues,averageSharpness] = measureSharpness(___) also returns the average SFR of vertical and horizontal ROIs, using any combination of input arguments from previous syntaxes.

Test Chart Image (since R2024a)

Use a test chart image for other types of test charts that are not supported by the esfrChart object. You must identify the positions of the slanted-edge ROIs.

sharpnessValues = measureSharpness(im,roiPositions) measures the SFR at all ROIs located at roiPositions within test chart image im. The returned sharpness table includes the frequency for each ROI at which the response drops to 50% of the initial and peak values.

sharpnessValues = measureSharpness(im,roiPositions,PercentResponse=p) also specifies the values of the frequency response at which to report the corresponding spatial frequency using the PercentResponse name-value argument.

Examples

collapse all

Read an image of an eSFR chart into the workspace.

I = imread("eSFRTestImage.jpg");

Create an esfrChart object, then display the chart with ROI annotations. The 60 slanted edge ROIs are labeled with green numbers.

chart = esfrChart(I);
displayChart(chart,displayColorROIs=false, ...
    displayGrayROIs=false,displayRegistrationPoints=false)

Figure eSFR test chart contains an axes object. The hidden axes object contains 61 objects of type image, text.

Measure the edge sharpness in ROIs 25-28, and return the measurements in sharpnessTable. Include measurements of the MTF70 and MTF30 by specifying the PercentResponse name-value argument.

sharpnessTable = measureSharpness(chart,ROIIndex=25:28,PercentResponse=[70 30])
sharpnessTable=4×9 table
    ROI    slopeAngle    confidenceFlag        SFR           comment                          MTF70                                           MTF70P                                        MTF30                                       MTF30P                 
    ___    __________    ______________    ____________    ____________    ____________________________________________    ____________________________________________    ________________________________________    ________________________________________

    25       4.2612          true          {84x5 table}    {0x0 double}    0.061813    0.059159    0.052978     0.06016    0.061813    0.059159    0.052978     0.06016    0.10726    0.11137    0.10976    0.11064    0.10726    0.11137    0.10976    0.11064
    26       5.0749          true          {84x5 table}    {0x0 double}     0.18617     0.18573     0.18613     0.18623     0.18617     0.18573     0.18613     0.18623    0.26279    0.26419     0.2628    0.26398    0.26279    0.26419     0.2628    0.26398
    27       4.7436          true          {84x5 table}    {0x0 double}    0.069296    0.069197    0.064096    0.068951    0.069296    0.069197    0.064096    0.068951    0.21611    0.21953    0.21891    0.21977    0.21611    0.21953    0.21891    0.21977
    28       4.7982          true          {84x5 table}    {0x0 double}     0.19005     0.20272     0.19611      0.1999     0.19005     0.20243     0.19595      0.1999    0.26278    0.27244     0.2617     0.2707    0.26278    0.27228    0.26164     0.2707

Select the fourth row in the sharpness table, which corresponds to ROI 28. Display the SFR plot of the ROI.

idx = 4;
plotSFR(sharpnessTable(idx,:))

Figure SFR Plots for ROI 28 contains an axes object. The axes object with title ROI 28, xlabel Spatial Frequency (Line pairs per pixel), ylabel SFR (Spatial Frequency Response) contains 8 objects of type line. These objects represent Red Channel, Green Channel, Blue Channel, Luminance Channel, Red Channel Beyond Nyquist, Green Channel Beyond Nyquist, Blue Channel Beyond Nyquist, Luminance Channel Beyond Nyquist.

Print the MTF70 and MTF30 measurements of the ROI. Compare the measurements against the plot.

The MTF70 measurement of the red and blue color channels are slightly smaller than 0.2, while the MTF70 measurement of the green and luminance channels are slightly larger than 0.2. These measurements agree with a visual inspection of the SFR plot, on which an SFR value of 0.7 occurs at spatial frequencies around 0.2 line pairs per pixel.

mtf70 = sharpnessTable.MTF70(idx,:)
mtf70 = 1×4

    0.1900    0.2027    0.1961    0.1999

The MTF30 measurement of the blue color channel is noticeably smaller than the MTF30 measurement of the other color channels. This measurement agrees with a visual inspection of the SFR plot, on which the SFR curve of the blue channel drops off more quickly than the other channels.

mtf30 = sharpnessTable.MTF30(idx,:)
mtf30 = 1×4

    0.2628    0.2724    0.2617    0.2707

Read and display an image of a custom test chart with slanted edge ROIs.

I = imread("slantedSquare.jpg");
imshow(I)

Figure contains an axes object. The axes object contains an object of type image.

Draw ROIs for the edges, starting at the top and moving clockwise.

numROIs = 4;
roiPos = zeros(numROIs,4);
for cnt = 1:numROIs
    hrect = drawrectangle;
    roiPos(cnt,:) = hrect.Position;
end  

Figure contains an axes object. The axes object contains 5 objects of type image, images.roi.rectangle.

Calculate the SFR, MTF50, and MTF50P for the selected ROIs.

sharpnessValues = measureSharpness(I,roiPos)
sharpnessValues=4×8 table
    ROI    slopeAngle    confidenceFlag         SFR           comment                        MTF50                                       MTF50P                           ROIPosition       
    ___    __________    ______________    _____________    ____________    ________________________________________    ________________________________________    ________________________

     1       3.9977          true          { 95×5 table}    {0×0 double}    0.18531    0.18554    0.17757    0.18482    0.18531    0.18554    0.17757    0.18482    205     85    269     93
     2       4.0233          true          {109×5 table}    {0×0 double}    0.18567    0.18623     0.1767    0.18533    0.18567    0.18623     0.1767    0.18533    508    188    107    234
     3       3.9977          true          {104×5 table}    {0×0 double}    0.18401    0.18393    0.17425    0.18317    0.18401    0.18393    0.17425    0.18317    243    468    295    102
     4       3.9827          true          {119×5 table}    {0×0 double}    0.18556    0.18624    0.17595    0.18534    0.18556    0.18624    0.17595    0.18534    101    215    117    242

Input Arguments

collapse all

eSFR chart, specified as an esfrChart object.

Since R2024a

Test chart image, specified as an RGB image or a grayscale image.

Since R2024a

ROI positions, specified as an n-by-4 numeric array, where n is the number of ROIs. Each ROI has the form [X Y Width Height], where X and Y are the coordinates of the top-left corner of the ROI. Width and Height are the width and height of the ROI, in pixels.

For horizontal edges, specify ROIs with a horizontal aspect ratio (a greater width than height). Likewise, for vertical edges, specify ROIs with a vertical aspect ratio (a greater height than width).

Name-Value Arguments

Specify optional pairs of arguments as Name1=Value1,...,NameN=ValueN, where Name is the argument name and Value is the corresponding value. Name-value arguments must appear after other arguments, but the order of the pairs does not matter.

Example: sharpnessValues = measureSharpness(chart,PercentResponse=30) reports the corresponding spatial frequency at which the SFR drops to 30% of the initial value and peak value.

Before R2021a, use commas to separate each name and value, and enclose Name in quotes.

Example: sharpnessValues = measureSharpness(chart,"PercentResponse",30) reports the corresponding spatial frequency at which the SFR drops to 30% of the initial value and peak value.

Value of the frequency response at which to report the corresponding spatial frequency, specified as an integer or a vector of integers in the range [1, 100].

Each value of PercentResponse adds two columns to the sharpness and averageSharpness output arguments. The first column gives the modulation transfer function (MTF) measurement. MTF is the frequency at which the SFR drops to the specified percent of the initial value, where the initial value is the value at a spatial frequency of 0. The second column gives the peak MTF, which is the frequency at which the SFR drops to the specified percent of the maximum SFR value.

For example, when PercentResponse has the value 50, the sharpness table has the columns MTF50 and MTF50P. These columns indicate the frequency at which the SFR drops to 50% of the initial value and peak value, respectively.

Example: 30

ROI indices to include in the measurements, specified as a positive integer or a vector of positive integers with values between 1 and the number of ROIs. By default, the measureSharpness function includes all ROI indices in the measurements.

Note

measureSharpness uses the intersection of ROIs specified by ROIIndex and ROIOrientation.

You can specify this argument only when you use a chart object, chart.

Example: 29:32

Data Types: single | double | int8 | int16 | int32 | uint8 | uint16 | uint32

ROI orientation, specified as "both", "vertical", or "horizontal". The measureSharpness function performs measurements only on ROIs with the specified orientation.

Note

measureSharpness uses the intersection of ROIs specified by ROIIndex and ROIOrientation.

You can specify this argument only when you use a chart object, chart.

Data Types: char | string

Output Arguments

collapse all

SFR measurements of edges, returned as a table. The table has one row for each measured ROI. The table always has these variables (columns):

VariableDescription
ROIIndex of the sampled ROI.
slopeAngleAngle between the slanted-edge and pure vertical or horizontal, depending on the ROI orientation. The angle is measured in degrees.
confidenceFlag

Boolean flag that indicates whether the sharpness measurement is reliable. confidenceFlag is true when the measurement is reliable. confidenceFlag is false when the measurement is unreliable due to these conditions:

  • slopeAngle is less than 3.5 degrees or more than 15 degrees.

  • The contrast within the ROI is less than 20%.

The contrast of a slanted-edge ROI is defined as 100*(IHigh - ILow)/(IHigh + ILow), where IHigh and ILow are the estimated average intensities of the high and low intensity regions across the edge. For color images, the function computes contrast for only the red channel.

SFR

Spatial frequency response of the edge in the ROI, returned as a scalar cell array containing a table. The table has f rows, where f is the number of frequency samples.

For test chart objects and color images, the table has five columns: the frequency value, and the red, green, blue, and luminance values corresponding to that frequency. Luminance (Y) is a linear combination of the red (R), green (G), and blue (B) channels according to:

Y = 0.213R + 0.715G + 0.072B

For grayscale images, the table has two columns: the frequency value, and the intensity values corresponding to that frequency.

commentIf confidenceFlag is false, then comment describes the reason the measurement is unreliable. If confidenceFlag is true, then comment is an empty vector, [].

Each value of PercentResponse adds two variables to the table:

VariableDescription
MTFn

Frequency at which the SFR drops to percent n of the initial value.

For test chart objects and color images, MTFn is returned as a 4-element vector representing the MTF measurements in the red, green, blue, and luminance channels, respectively.

For grayscale images, MTFn is returned as a numeric scalar.

MTFnP

Frequency at which the SFR drops to percent n of the peak value.

For test chart objects and color images, MTFnP is returned as a 4-element vector representing the MTF measurements in the red, green, blue, and luminance channels, respectively.

For grayscale images, MTFnP is returned as a numeric scalar.

If you specify a test chart image im, then the table has an additional variable:

VariableDescription
ROIPositionsPosition of the ROI, returned as a 4-element vector of the form [X Y Width Height]. X and Y are the coordinates of the top-left corner of the ROI. Width and Height are the width and height of the ROI, in pixels.

For more information on accessing the measurements within the table, see Access Sharpness Measurements.

Average SFR measurements of the vertical and horizontal edges, returned as a table with one or two rows. averageSharpness has one row when all sampled ROIs have the same orientation. It has two rows when the sampled ROIs have mixed orientations.

The first two columns of averageSharpness are always present, and represent these variables:

VariableDescription
OrientationOrientation of the averaged SFRs. The value of Orientation is either "horizontal" or "vertical".
SFR

Averaged spatial frequency response of all edges in included ROIs with the orientation specified by Orientation.

SFR is an s-by-5 table, where s is the number of frequency samples. The five columns represent the frequency value, and the averaged red, green, blue, and luminance values corresponding to that frequency.

Luminance (Y) is a linear combination of the red (R), green (G), and blue (B) channels according to:

Y = 0.213R + 0.715G + 0.072B

Each value of PercentResponse adds two variables to the table:

VariableDescription
MTFn

Frequency at which the SFR drops to percent n of the initial value, averaged across all sampled ROIs with the same orientation. MTFn is returned as a 4-element vector representing the averaged MTF measurements in the red, green, blue, and luminance channels, respectively.

MTFnP

Frequency at which the SFR drops to percent n of the peak value, averaged across all sampled ROIs with the same orientation. MTFnP is returned as a 4-element vector representing the averaged MTF measurements in the red, green, blue, and luminance channels, respectively.

For more information on accessing the measurements within the table, see Access Sharpness Measurements.

More About

collapse all

Access Sharpness Measurements

The order of the variables in the sharpness table depends on whether you input a test chart image, im, or an object, chart. If you need to access variables of the sharpness table, refer to variable names and not numeric indices.

For example, to access the slopeAngle variable of the sharpness table, use code such as this.

slopeAngles = sharpnessValues.slopeAngle;

For another example, to access the sharpness measurements of the luminance channel of the ROI with index 3, use code such as this. The first command returns the slopeAngle variable of the sharpness table as a cell array. The second command finds the element of the cell array corresponding to the ROI with index 3, and extracts the element into an SFR table. The third command returns the SFR_Y variable of the SFR table as a numeric column vector.

sfr = sharpnessValues.SFR;
sfr3 = sfr{sharpnessValues.ROI==3};
sfr3Y = sfr3.SFR_Y;

Note that you can perform these three operations in a single command:

sfr3Y = sharpnessValues.SFR{sharpnessValues.ROI==3}.SFR_Y;

For more information, see Access Data in Tables and Access Data in Cell Arrays.

Tips

  • Slanted edges on a properly oriented chart are at an angle of 5 degrees from the horizontal or vertical. Sharpness measurements are not accurate when the edge orientation deviates significantly from 5 degrees.

  • Sharpness is higher toward the center of the imaged region and decreases toward the periphery. Horizontal sharpness is usually higher than vertical sharpness.

Algorithms

The SFR measurement algorithm is based on work by Peter Burns [2] [3]. First, measureSharpness determines the edge position with sub-pixel resolution for each scan line, or row or column of pixels perpendicular to the edge, in the ROI. For example, each row of pixels is a scan line for a near-vertical edge. Next, measureSharpness aligns and averages the scan lines to create an oversampled edge intensity profile. The function takes the derivative of the intensity profile and applies a windowing function. The returned SFR measurement is the absolute value of the Fourier transform of the windowed derivative.

References

[2] Burns, Peter. "Slanted-Edge MTF for Digital Camera and Scanner Analysis." Society for Imaging Science and Technology; Proceedings of the Image Processing, Image Quality, Image Capture Systems Conference. Portland, Oregon, March 2000, pp. 135–138.

[3] Burns, Peter. "sfrmat3: SFR evaluation for digital cameras and scanners." URL: http://losburns.com/imaging/software/SFRedge/sfrmat3_post/index.html.

Version History

Introduced in R2017b

expand all