A "slanted edge" analysis program

  • Thread starter Thread starter Lorenzo J. Lucchini
  • Start date Start date
Bart said:
For real accurate results, that remains to be verified ...
Testing a (transparent) step wedge may/will reveal 'interesting'
features of hardware *and* of scanner driver software.

True. But test targets cost money, and I'm allergic to expenses ;-)
Well, sooner or later, perhaps I'll go buy an IT8 test target, so that I
have a gray scale for measuring gamma, as well as everything else for
measuring colors.

But not right now. Actually, one of the reasons why I got very
interested in this slanted edge test was its astonishing inexpensiveness :-)

By the way, can the test somehow also tell something about color
corrections? Intuitively, it seems to me that with the ESF and the MTF
for red, green and blue one should be able to fix at least *some* color
correction parameters.
Yes, for straight Gamma only (sRGB profiled images use a
'slope-limited' Gamma). Also beware that Gamma adjustment
may mean 1/Gamma, depending on what is being adjusted where.
This does assume that Gamma is the only non-linearity.

But if I'm not mistaken, Imatest does the same, so I can be content with
it right now.
SFRWin on the other hand allows one to specify a look-up table.
[snip]

Just note that actual MTFs can exceed 1.0, assuming correct
normalization to 1.0 at zero cycles. Edge sharpening halo can achieve
that easily.

Right. I'll have to fix this, as the program currently doesn't give the
zero-cycles point any special treatment, but just normalizes.
[snip]
What kind of provisions?

With noisy images, there can be multiple LSF maxima from a single ESF.
One should decide which maximum to take. I dug up some old Word document
with C code for the SFR calculation. It takes the average between the
leftmost and rightmost maxima.
If your email address in your signature is valid, I can send you that
document.

Yes, it's valid. It's usually full because of spam, but I'm keeping it
clean lately... just don't put "enlargement" in the subject and I should
receive it :-)

Anyway, can noise really cause such problems, besides in "extreme"
situations (i.e. when the measurments would be better thrown away anyway)?

I'm thinking that even a very high spike of noise shouldn't be able to
get higher than the edge constrast, considering that *many* lines are
averaged together to obtain the ESF...

Perhaps *very* bad calibration striping could cause that, but then again
one should probably throw away the scan in such a case.
SNIP


Yes, that's a good goal, although it will take more than a single
slanted edge to get a two-dimensional a-symmetric PSF).

Well, I assume that a vertical+horizontal edge measurement can be
accurate enough for many purposes.

By the way, I've done (but not published) some tests on horizontal edges
(i.e. stepping motor resolution), and the results are a bit depressing!
About 100-200 dpi lower resolution than on the CCD axis, and a
frightening amount of color fringing.
What's worse,
the PSF can (and does) change throughout the image, but a symmetrical
PSF will already allow to improve image quality.
Some hurdles will need to be taken, but the goal is exactly what I am
looking for.

Well, it's a bit soon for this perhaps, but... how do I obtain the PSF
from two (h+v) ESFs?
Perhaps for each point, average the two points on the ESFs that are at
the same distance from the "center" of the function, and weight the
average based on the angle between the points and the two (h+v) axes?

But anyway...
SNIP


Yes, we're not the only ones still looking for the holy grail, it seems.

I'm working on a method that will produce a PSF, based on the ESF
derived from a slanted edge. That PSF can be used in various
deconvolution methods, and it can be used to create a High-pass filter
kernel. Could be useful to incorporate in the final program.

.... of course it can be useful. No need for me to invent the square
wheel when you've already worked on an octagonal one :-)


by LjL
(e-mail address removed)
 
SNIP
What do you propose for image restoration, instead of deconvolution?
("image restoration" obviously being restricted to the things you
can do when you have an ESF or PSF)

Straight deconvolution will 'restore' noise (and graininess) as well
as the signal itself, or the noise is even amplified. There are better
methods like the adaptive (damped) Richardson-Lucy algorithm, but that
is a very processing intensive and thus time consuming operation. The
method used in "Image Analyzer", using the "CGLS" algorithm, is much
faster but slightly noisier than RL.
<http://www.mathcs.emory.edu/~nagy/RestoreTools/index.html>

SNIP
So in your opinion it's ok if I just consider an arbitrary number of
pixels (like Imatest does) as constituting "the edge", without going
to great length trying to have the program make an educated guess?

Yes, although flatbed scanners exhibit a significantly wider ESF with
long tails. Don't be too conservative. The range used by Imatest is
from -6 to +10 in quarter pixel increments, and thus allows to handle
at least a symmetrical PSF with a support of 13 pixels, which would be
for a *very* blurry image.

SNIP
Yes, but there are two other options I've considered:

1) taking *many* DFTs of small (Hanning-windowed) pieces of the LSF,
and then average them together. Wouldn't this avoid the change of
LSF shape that using a single, big window may cause?

Although possible, it's probably more efficient to code the
binning/averaging many single row LSFs, thus approaching the real LSF.
It's the real LSF that needs to be 'DFT'ed. IMO it's not so useful to
perform many DFTs on such a small (e.g. 64 quarter pixels if ranging
from ) array, it becomes less efficient and I think complex. Some
calculations are easier/faster in the frequency domain (e.g.
deconvolution) and others in the spatial domain (averaging and small
kernel convolution). The windowing has only to be done once on the
multiple LSF average (which already has lower noise than single
samples).
2) not using any window, but "cropping" the LSF so that the edges
are (very near) zero. Would this have any chances of working? It
would completely avoid changing the LSF's shape.

Truncation loses information, I don't think that's helpful. Windowing
will further reduce the already low response and it suppresses noise
at the boundaries. That's helpful.

SNIP
Yes, I do this.
MTF=SquareRoot(ImaginaryPart^2+RealPart^2)


Depending on the library implementation, for complex numbers , Abs[z]
gives the modulus |z| .
Also note http://www.library.cornell.edu/nr/bookcpdf/c5-4.pdf (5.4.3)
which is a more robust way of doing it in extreme cases (which may
never occur, but it's still more robust).
Anyway, the method I'm using comes from the document I pointed to in
the other article, so it shouldn't be *too* stupid.

Still, the method you describe sounds much simpler to implement, so
I guess I'll go for it.

In the Netherlands we have a saying, "there are several roads, all
leading to Rome" ;-)
All I did is describe how the ISO suggests to do it, and it seems
relatively simple to code it. Simple code reduces the chance on bugs
and unforeseen 'features'.

Let us see if I've understood this.
[...]

I think I have an even better suggestion. I have some C code examples
from the ISO that shows how it could be implemented. If I can email
the 48KB Word document (is your (e-mail address removed) in the signature
valid?), it'll become quite clear, I'm sure. I also have a 130KB PDF
file you'll love to read because it describes the various steps and
considerations in more detail.

One more remark. I've been having some discussions with Fernando
Carello (also from Italy) about PSFs and types of restoration. He was
willing (if time permits) to attempt to tackle that side of the
challenge. Although I understand that it's always a bit difficult to
fathom a mix of programming styles, it could potentially help (again,
if his time allows).

Bart
 
SNIP
I think I'll go for user selectable, with a default that's
recommended for comparing others' results.

Yep, seems like the pragmatic approach wins.
But all this made me wonder about something else: would it make any
sense to compare the edge *position* of each (red, green and blue)
channel with the edge position in the luminance channel?

Depends on what one wants to investigate, but I see no direct use for
comparison of a color channel with Luminance. Besides Luminance for
sharpness, one could compare R, G, and B for Chromatic aberrations. In
digicams with a Bayer CFA it can be quite revealing what a difference
Raw converters can make. For scanners that seems less of an issue.
I mean. SFRWin gives "red", "blue" and "green" color offsets (for
measuring "color fringing"), but the "green" offset is always zero,
as the other two channels are compared to green.

Would comparing the three channels to luminance, instead, have any
advantage over SFRWin's approach? I don't remember what Imatest does
here.

No advantage for me. Imatest produces a figure for Chromatic
Aberration (http://www.imatest.com/docs/tour_sfr.html#ca).

Bart
 
Bart said:
SNIP

[snip]
So in your opinion it's ok if I just consider an arbitrary number of
pixels (like Imatest does) as constituting "the edge", without going
to great length trying to have the program make an educated guess?

Yes, although flatbed scanners exhibit a significantly wider ESF with
long tails. Don't be too conservative. The range used by Imatest is from
-6 to +10 in quarter pixel increments, and thus allows to handle at
least a symmetrical PSF with a support of 13 pixels, which would be for
a *very* blurry image.

Well, I will use -10 .. +10 for now, if it doesn't get too slow (but
using the "4x bins" thing it should all go much faster, I think).
That should allow plenty of room.
SNIP



Although possible, it's probably more efficient to code the
binning/averaging many single row LSFs, thus approaching the real LSF.
It's the real LSF that needs to be 'DFT'ed. IMO it's not so useful to
perform many DFTs on such a small (e.g. 64 quarter pixels if ranging
from ) array, it becomes less efficient and I think complex. Some
calculations are easier/faster in the frequency domain (e.g.
deconvolution) and others in the spatial domain (averaging and small
kernel convolution). The windowing has only to be done once on the
multiple LSF average (which already has lower noise than single samples).

No, sorry, I didn't mean to take the DFTs of all single-row LSFs.

What I meant is:
- assume you have a (final) LSF that is 128 values long
- you take the windowed DFT of the first 16 values
- then you take the DFT of values from 8 to 24
- then from 16 to 32
- etc
- then you average all these together

I've not just invented this strange thing, I've read it somewhere,
though not in a graphics context, and I might have misinterpreted it.
Truncation loses information, I don't think that's helpful. Windowing
will further reduce the already low response and it suppresses noise at
the boundaries. That's helpful.

I see. Well, at least I guess that taking a "longer" LSF (i.e.
considering more pixels "part of the edge") could help reduce any
artifacts caused by the windowing, since most of the "important" data is
in a small part of the whole LSF.

Also, do you think a Hanning window is a reasonable choice for my
purposes, or should I choose a different window type?
SNIP
Yes, I do this.
MTF=SquareRoot(ImaginaryPart^2+RealPart^2)


Depending on the library implementation, for complex numbers , Abs[z]
gives the modulus |z| .


No, there isn't such a function in FFTW. However, there are functions to
directly obtain a real-to-real FFT; I probably should look at them,
although I'm not sure if the real data they output are the moduli or
simply the real parts of the transform's output.
Also note http://www.library.cornell.edu/nr/bookcpdf/c5-4.pdf (5.4.3)
which is a more robust way of doing it in extreme cases (which may never
occur, but it's still more robust).

Site down at the moment :-) I'm starting to worry that it may somehow be
me...
[snip]

In the Netherlands we have a saying, "there are several roads, all
leading to Rome" ;-)

Tutte le strade portano a Roma (all roads bring to Rome), clearly we
have that too, and in our case, it's actually true ;-) at least for
those roads that were originally built in ancient Roman times.
[snip]
Let us see if I've understood this.

[...]

I think I have an even better suggestion. I have some C code examples
from the ISO that shows how it could be implemented. If I can email the
48KB Word document (is your (e-mail address removed) in the signature valid?),
it'll become quite clear, I'm sure.

It's valid, yes.
Only, how copyrighted is that stuff, and what's the legal state of those
documents? ISO might get upset with both of us, if somehow I wasn't
supposed to read or use their papers (ok, ok, in the real world they
won't even notice we exist I suppose).
I also have a 130KB PDF file you'll
love to read because it describes the various steps and considerations
in more detail.

Sure, if the main concepts can be understood without going too deeply
technical, it'll be most welcome.
One more remark. I've been having some discussions with Fernando Carello
(also from Italy) about PSFs and types of restoration. He was willing
(if time permits) to attempt to tackle that side of the challenge.

I've read through some of the threads you've had with him.
Although I understand that it's always a bit difficult to fathom a mix
of programming styles, it could potentially help (again, if his time
allows).

Sure! And if we work on separate aspects of the issue, the problem of
mixed programming styles is easily solved by having separate
sources/libraries communicate through an interface, you know, like I've
heard real programmers (rarely) do ;-)

Hm, I see a problem though... these PSF MTF ESF DFT regression curve
fitting etc thingies, I don't know how to call most of them in Italian :-D


by LjL
(e-mail address removed)
 
SNIP
Yeah, it's the Unix emulation layer that Cygwin compiled programs
apparently need.
I've uploaded it at
http://ljl.741.com/cygwin1.dll.gz
http://ljl.150m.com/cygwin1.dll.gz

Getting closer, although now it complains about not being to locate
cygfftw3-3.dll (presumably the FFT routine library).

SNIP
It could be: I've scanned some edges at 2400x4800 and resized them
down to see how this affected the MTF (remember the thread
"Multi-sampling and 2400x4800 scanners").

Yes, that's what I was thinking of, interpolation in one direction to
compensate for the aspect ratio.

SNIP
What is single pixel noise -- or, is it "single pixel" as opposed to
what)?

No, the edge seems to be NN interpolated, but the noise is not (there
are single (as opposed to 1x2 pixel) variations).

I'll wait for the next tarball, before making further benchmark tests.

Bart
 
Bart said:
SNIP



Getting closer, although now it complains about not being to locate
cygfftw3-3.dll (presumably the FFT routine library).

Argh! I hoped that at least FFTW was linked statically.

Well,
http://ljl.741.com/cygfftw3-3.dll.gz

as well as, just in case
http://ljl.741.com/cygfftw3_threads-3.dll.gz

Yes, that's what I was thinking of, interpolation in one direction to
compensate for the aspect ratio.

SNIP
What is single pixel noise -- or, is it "single pixel" as opposed to
what)?

No, the edge seems to be NN interpolated, but the noise is not (there
are single (as opposed to 1x2 pixel) variations).

Oh, but I hadn't interpolated *up*, but resized *down*! I've resized the
4800dpi direction to 2400dpi. Anyway, this doesn't matter.
I'll wait for the next tarball, before making further benchmark tests.

It's there. As you might suspect, at
http://ljl.741.com/slantededge-alpha3.tar.gz

I haven't included the libraries, as they're a bit big and my server
doesn't let me upload more than 1 meg or so.

This time I'm positive there is no gamma and no color correction. I've
also used a brand new edge, which if I'm not mistaken is really a razor
blade this time! (No, I don't really know what a razor blade looks like.
So sue me :-)
Anyway, it seems quite sharp, probably sharper than the cutter I was
using before.

There is still something I don't quite understand: the program now
reports that the 10%-90% rise is about 6 pixels, while it was about 4-5
before (and Imatest agreed).
I don't think this is because of the edge, but rather because of the
fact I'm not normalizing the image anymore -- so 10% and 90% "take
longer" to be reached.
Should these 10% and 90% positions fixed as if the image were normalized?


by LjL
(e-mail address removed)
 
Lorenzo said:
Depending on the library implementation, for complex numbers , Abs[z]
gives the modulus |z| .

No, there isn't such a function in FFTW.

FFTW is not a complex-number library. You can easily take the absolute
value of its complex number yourself by sqrt(re*re + im*im), or you can
use the standard C complex math library (or the C++ library via a
typecast).
However, there are functions to
directly obtain a real-to-real FFT; I probably should look at them,
although I'm not sure if the real data they output are the moduli or
simply the real parts of the transform's output.

Neither. The real-to-real interface is primarily for transforms of
real-even or real-odd data (i.e. DCTs and DSTs), which can be expressed
via purely real outputs. They are also for transforms of real data
where the outputs are packed into a real array of the same length, but
the outputs in this case are still complex numbers (just stored in a
different format).

Cordially,
Steven G. Johnson
 
Here is an implementation of Glassman's method of FFT, which wil work
for any N, not just powers of two. If N is not a power of two, it
degenerates to a DFT. The code is lifted from PAL (Public Ada
Library), if I remember correctly, and I do not think there is any
restrictions on it. You will have to convert it to C of course, but
the code is pretty obvious even if yo don't know Ada. Just beware that
unlike C, Ada allows nested subroutines, and that arrays do not
necessarily start with index 0.....

with Ada.Numerics.Short_Complex_Types;
use Ada.Numerics.Short_Complex_Types;

package FFT_Pack is

type Complex_Vector is array(Integer range <>) of Complex;

procedure Debug(X : Complex_Vector);

procedure FFT (FFT_Data : in out Complex_Vector ;
Inverse_Transform : in boolean );

end FFT_Pack;

with Ada.Numerics.Short_Elementary_Functions;
use Ada.Numerics.Short_Elementary_Functions;
with Ada.Text_Io; use Ada.Text_Io;

package body FFT_Pack is

procedure Debug(X : Complex_Vector) is
begin
for I in x'Range loop
Put_Line(Integer'Image(I) & " : "
& Short_Float'Image(X(I).Re) & " "
& Short_Float'Image(X(I).Im));
end loop;
end Debug;

procedure Glassman (A, B, C : in integer;
Data_Vector : in out Complex_Vector ;
Inverse_Transform : in boolean ) is

Temp : Complex_Vector(1..Data_Vector'length);
Counter : integer := Data_Vector'first;
JC : integer := 0;
Two_Pi : constant short_float := 6.28318530717958;
Del, Omega, Sum : Complex;
Angle : short_float;
C_Plus_1 : integer := C + 1;
begin
Temp(Temp'Range) := Data_Vector;
Angle := Two_Pi / (short_float(A * C));
Del := (Cos(Angle), (-(Sin(Angle))));
if (Inverse_Transform) then
Del := Conjugate(Del);
end if;
Omega := (1.0,0.0);

for IC in 1..C loop
for IA in 1..A loop
for IB in 1..B loop
Sum := Temp((((IA - 1)*C + (C-1))*B) + IB);
for JCR in 2..C loop
JC := C_Plus_1 - JCR; -- No need to add C + 1 each
-- time through loop
Sum := Temp((((IA - 1) * C + (JC - 1)) * B)
+ IB) + (Omega * Sum);
end loop; -- JCR
Data_Vector(Counter) := Sum;
Counter := Counter + 1;
end loop; -- IB
Omega := Del * Omega;
end loop; -- IA
end loop; -- IC
end Glassman;

procedure FFT ( FFT_Data : in out Complex_Vector;
Inverse_Transform : in boolean ) is

A : integer := 1;
B : integer := FFT_Data'length;
C : integer := 1;

begin -- FFT

while (B > 1) loop -- define the integers A, B, and C
A := C * A; -- such that A * B * C = FFT_Data'length
C := 2;
while (B mod C) /= 0 loop
C := C + 1;
end loop;
B := B/C; -- B = 1 causes exit from while loop
Glassman (A,B,C, FFT_Data, Inverse_Transform);
end loop;

if Inverse_Transform then -- optional 1/N scaling for inverse
-- transform only
for i in FFT_Data'range loop
FFT_Data(i) := FFT_Data(i) /
short_float(FFT_Data'length);
end loop;
end if;
end FFT;
end FFT_Pack;
 
But all this made me wonder about something else: would it make any
sense to compare the edge *position* of each (red, green and blue)
channel with the edge position in the luminance channel?

That would be a good test.

My point is that there's misalignment between individual channels, so
to combine them (using *any* method) reduces accuracy because the
result is a (fuzzy) mix of all of them. By doing channels individually
you should get more accurate measurements.

In other words (and all other things being equal) I would expect that
individual channels would differ much less in relation to each other,
then any one of them will differ in relation to the combined luminance
or average values.
I mean. SFRWin gives "red", "blue" and "green" color offsets (for
measuring "color fringing"), but the "green" offset is always zero, as
the other two channels are compared to green.

I would do a full permutation and compare all to each other.

Anyway, have fun! :o) And let us know how it turns out!

Don.
 
Well, but I don't plan to stop here. What I'd mostly like to obtain from
all this is a way to "sharpen" my scans using a function that is
tailored to my scanner's specifics (rather than just "unsharp mask as I
see fit").

So, you see, there is a practical application of the measurements I can
obtain, it's not just about knowing how poor the scanner's resolution is.

I agree with that in principle. However, in practical terms I think
that starting with an 8-bit image there's only so much accuracy you
can achieve.

I strongly suspect (but don't know for a fact) that you will not be
able to show a demonstrable difference between any custom sharpening
and just applying unsharp mask at 8-bit depth.

I think you can improve the sharpness considerably more (even at 8-bit
depth) by simply aligning individual channels to each other.
And why do you say I'm measuring the "objective values" of the pixels
instead of their "perceptual values"? I'm mostly trying to measure
resolution, in the form of the MTF.

Because it's all based on those gray pixels which are created because
the scanner can't resolve that border area. So it's much better to
read the actual values of those gray pixels rather than take either an
average or luminance value.

If the three RGB channels are not perfectly aligned (and they never
are!) then combining them in any way will introduce a level of
inaccuracy (fuzziness). In case of luminance that inaccuracy will also
have a green bias, while the average will be more even - which is why
I said that your original idea to use average seems like the "lesser
evil" when compared to the skewed and green-biased luminance values.
So you see that I'm *already* doing measurements that are inherently
"perceptual". So why not be coherent and keep this in mind throughout
the process?

Because perception is subjective. When there is no other way, then
yes, use perception. But since you already have the values of those
gray pixels it just seem much more accurate to use those values.
... I'm doing this already.
The "gray" channel is measured *in addition* to the other three
channels, and is merely a convenience.

That's good. So displaying individual results should be easy.

Don.
 
Don said:
I agree with that in principle. However, in practical terms I think
that starting with an 8-bit image there's only so much accuracy you
can achieve.

Don't be so fixated with my 8 bits. I'll start working with 16 bits,
possibly after buying a USB 2 card, if that needs be.
I strongly suspect (but don't know for a fact) that you will not be
able to show a demonstrable difference between any custom sharpening
and just applying unsharp mask at 8-bit depth.

Well, wait a minute: at any rate, I'll be able to use a *measured* --
instead of just *guessed* -- amount (and kind) of sharpening.

Then I guess you'll be able to obtain the same results by using a "right
amount" of unsharp masking... but that's precisely what I want to avoid,
guessing values!
I'm not an experienced photographer, quite the contrary, and I can't
really tell how much unsharp masking "looks right".
I think you can improve the sharpness considerably more (even at 8-bit
depth) by simply aligning individual channels to each other.

That's another possibility to explore, sure. Imatest, SFRWin and my
program all give some measurement of color aberrations -- channel
misalignment, chiefly.

Certainly, those values could find some use; however, I don't have much
hope: in fact, unsurprisignly, my scanner seems to have very little
color misalignment in the CCD direction, but it does show quite a bit of
misalignment in the motor direction!
But, I thought, that must be because the motor's steps are not very
regular and precise. If that's the cause, then it'll be impossible to
try and re-align the colors, as misalignment will change at every scan line.

Sort of like what you've found out with multi-pass scans alignment..
Because it's all based on those gray pixels which are created because
the scanner can't resolve that border area. So it's much better to
read the actual values of those gray pixels rather than take either an
average or luminance value.

If the three RGB channels are not perfectly aligned (and they never
are!) then combining them in any way will introduce a level of
inaccuracy (fuzziness). In case of luminance that inaccuracy will also
have a green bias, while the average will be more even - which is why
I said that your original idea to use average seems like the "lesser
evil" when compared to the skewed and green-biased luminance values.

At this point, I think I have a better idea: let's *first* measure the
amount of misalignment, and then average the channels to luminance
*after* re-aligning them.

Of course, I must first be sure the way I currently measure misalignment
is correct, as SFRWin gives different results.
But that's (by far) not the only thing that's currently wrong in my
program...
Because perception is subjective. When there is no other way, then
yes, use perception. But since you already have the values of those
gray pixels it just seem much more accurate to use those values.

I'm not sure. Yes, I have the real values, but... my program tries to
answer the question "how much resolution can my scanner get from the
original?". The answer itself depends on the observer's eye, as a person
might be able to see constrasts less than 10%, and another might only
see up to 15%, say.

So, since an average observer *must* be "invented" anyway for the
results to have any practical meaning, then it makes sense to also
adjust them so that the colors the average eye sees best count more, as
they *will* affect perceived resolution.

And "perceived resolution" is the only viable metric: in fact, if I
wanted to measure "real" resolution, I would have to say that my scanner
really does resolve 2400 dpi (which it doesn't), as just before Nyquist,
there is (for example) a 0.00001 response.
Hey, that's still resolution, isn't it! But it's resolution that counts
nothing, as no observer will be able to see it, and sharpening won't
help because noise will overwhelm everything else.
That's good. So displaying individual results should be easy.

Not should, is. The table I output has the fields "Frequency", "Red
response", "Green response", "Blue response", "Luminance response".

If the users wants to take advantage of the luminance results, they can,
but they also can ignore them just as well.


by LjL
(e-mail address removed)
 
Lorenzo said:
Depending on the library implementation, for complex numbers , Abs[z]
gives the modulus |z| .

No, there isn't such a function in FFTW.

FFTW is not a complex-number library. You can easily take the absolute
value of its complex number yourself by sqrt(re*re + im*im), or you can
use the standard C complex math library (or the C++ library via a
typecast).

I'd like to remain within plain C; and the complex math library is,
AFAIK, part of C99, so it might not be available on all compilers yet.
(Yeah, I know, I'm using // comments, but *those* are in every stupid
compiler ;-)

Currently I'm precisely doing the computation you say (well, I'm using
pow() actually), it's just that Bart says this is not a robust method
with "extreme" values. But it should be ok for now, in any case.
Neither. The real-to-real interface is primarily for transforms of
real-even or real-odd data (i.e. DCTs and DSTs), which can be expressed
via purely real outputs. They are also for transforms of real data
where the outputs are packed into a real array of the same length, but
the outputs in this case are still complex numbers (just stored in a
different format).

I see, thanks. It wasn't very clear reading the FFTW manual, for someone
who's meeting Fourier transforms for the first time in his life.


by LjL
(e-mail address removed)
 
SNIP
These two, cygwin1.dll and cygfftw3-3.dll, are sufficient.

SNIP

I'll give the "slantededge.exe" a try. I'm just trying to get it to
recognize my options, but no results are saved (only some statistics
are reported on screen). For example "--csv-esf testedge.ppm" is an
"unrecognized" option.

SNIP
Should these 10% and 90% positions fixed as if the image were
normalized?

Yes, between the 10% and 90% response of the normalized ESF data
(assuming linearized image gamma 1.0, I would assume since all data
should be linearized).

Bart
 
Bart said:
SNIP
These two, cygwin1.dll and cygfftw3-3.dll, are sufficient.

SNIP



I'll give the "slantededge.exe" a try. I'm just trying to get it to
recognize my options, but no results are saved (only some statistics are
reported on screen). For example "--csv-esf testedge.ppm" is an
"unrecognized" option.

Wait a moment, but you must specify a filename to save the ESF to.

Try with this command line:

slantededge.exe --verbose --csv-esf esf.txt --csv-lsf lsf.txt --csv-mtf
mtf.txt testedge.ppm

It works for me.
SNIP


Yes, between the 10% and 90% response of the normalized ESF data
(assuming linearized image gamma 1.0, I would assume since all data
should be linearized).

Fine, thanks. 'll fix.

by LjL
(e-mail address removed)
 
Don't be so fixated with my 8 bits.

I'm not. It's simply a very important factor when considering the
context because it directly affects the result. So to ignore it would
lead to wrong conclusions.
Well, wait a minute: at any rate, I'll be able to use a *measured* --
instead of just *guessed* -- amount (and kind) of sharpening.

But that measurement will be so inaccurate as to be virtually
meaningless i.e. the margin of error will be so high that it will not
improve on the guessed amount. Indeed it's quite conceivable that in
significant number of cases it may actually produce worse results than
guessing.
Then I guess you'll be able to obtain the same results by using a "right
amount" of unsharp masking... but that's precisely what I want to avoid,
guessing values!

Please don't get me wrong. I hate guessing. But if the metrics are
inadequate then you may end up making matters worse. I mean you, can't
measure millimeters with a ruler that only has marks for centimeters.
I'm not an experienced photographer, quite the contrary, and I can't
really tell how much unsharp masking "looks right".

On a tangent, I personally don't use any sharpening at all. I compared
sharpened images to the originals (at large magnification) and didn't
really like what unsharp mask did. But, that's a matter of personal
taste...
That's another possibility to explore, sure. Imatest, SFRWin and my
program all give some measurement of color aberrations -- channel
misalignment, chiefly.

I was shocked when I discovered this on my film scanner. I expected
that the channel alignment would be much more accurate.
Certainly, those values could find some use; however, I don't have much
hope: in fact, unsurprisignly, my scanner seems to have very little
color misalignment in the CCD direction, but it does show quite a bit of
misalignment in the motor direction!

Yes, that's a very big problem with all flatbeds! The stepper motor is
also very irregular as the belts slip, etc.
But, I thought, that must be because the motor's steps are not very
regular and precise. If that's the cause, then it'll be impossible to
try and re-align the colors, as misalignment will change at every scan line.

Sort of like what you've found out with multi-pass scans alignment..

Here's a little test to try: Take a ruler and scan it twice at optical
resolution of your scanner: once horizontally, and once vertically.
Rotate one of them and compare! It makes a grown man cry! ;o)

Now, if that weren't bad enough, do several vertical scans (along the
stepper motor axis) and compare! And then really start to cry! ;o)

It sure made me pull my hair! I noticed this when I was scanning some
square images and was surprised that their vertical vs. horizontal
dimensions in Photoshop were not the same. I then rotated the photo,
scanned again, and now it was stretched in the other direction!
Aaaaarrrrggghhh!

That's when I invented "the ruler test". My scans on stepper motor
axis are about 1mm shorter than scans on CCD axis using a 10cm strip.
At this point, I think I have a better idea: let's *first* measure the
amount of misalignment, and then average the channels to luminance
*after* re-aligning them.

That's what I'm saying (individual channel measurements) only use a
straight average when you combine the results. Luminance will simply
introduce a large green bias at the expense of red, for the most part.

Luminance really has no part in this context because it only skews the
results by favoring the green channel results and neglecting the red.
Of course, I must first be sure the way I currently measure misalignment
is correct, as SFRWin gives different results.
But that's (by far) not the only thing that's currently wrong in my
program...

That's why we like programming! ;o) It's solving those problems!
I'm not sure. Yes, I have the real values, but... my program tries to
answer the question "how much resolution can my scanner get from the
original?". The answer itself depends on the observer's eye, as a person
might be able to see constrasts less than 10%, and another might only
see up to 15%, say.

No, the answer is not based on any one individual person. The answer
is quite clear if you read out the gray values. Whether one person can
see those grays and the other can't doesn't really matter in the
context of objective measurements.
So, since an average observer *must* be "invented" anyway for the
results to have any practical meaning, then it makes sense to also
adjust them so that the colors the average eye sees best count more, as
they *will* affect perceived resolution.

If you want to test human perception that's a completely different
test. However, that doesn't change the *objective* resolution of the
scanner.

I mean take number of colors on a monitor. You can objectively
determine how many colors your monitor can display. And then you can
also determine how many of those colors an average person can
distinguish. Those are two totally different test, using different
metrics.
And "perceived resolution" is the only viable metric: in fact, if I
wanted to measure "real" resolution, I would have to say that my scanner
really does resolve 2400 dpi (which it doesn't), as just before Nyquist,
there is (for example) a 0.00001 response.
Hey, that's still resolution, isn't it! But it's resolution that counts
nothing, as no observer will be able to see it, and sharpening won't
help because noise will overwhelm everything else.

In that case, it appears you're not really interested in your
scanner's actual resolution but your perception of that resolution.
And that's a different test.
Not should, is.

It's a figure of speech.

Don.
 
Don said:
On Thu, 29 Sep 2005 18:16:04 +0200, "Lorenzo J. Lucchini"

[snip]
Don't be so fixated with my 8 bits.

I'm not. It's simply a very important factor when considering the
context because it directly affects the result. So to ignore it would
lead to wrong conclusions.

But I'm not even ignoring it, since at the moment I haven't yet reached
the point of trying to apply my "slanted edge" measurements to a *real*
image.

What's the point of arguing that the "real" image should be 16-bit
instad of 8-bit, when I currently have no way to test a "real" image?
When my program will be able to do that, then we'll see if a 16-bit
image is needed.

Unless you mean...
But that measurement will be so inaccurate as to be virtually
meaningless i.e. the margin of error will be so high that it will not
improve on the guessed amount. Indeed it's quite conceivable that in
significant number of cases it may actually produce worse results than
guessing.

.... that I should *scan the slanted edge* at 16 bit -- as you say that
it's the *measurement* that's inaccurate.

But, you see, Imatest's manual doesn't particularly insist on scanning
the edge at 16-bit, and I think I can see the reason: the oversampling
that the slant allows compensates very well for the low bit-depth.

You see, even if I scan the edge at 8-bit, the final edge spread
function I obtain will have a *much higher* bit depth than 8-bit --
that's because I'm scanning the edge transition multiple times (200
times, if the scan is 200 pixels tall).

Wouldn't you think an image would get to have a much higher bit depth
than 8 bit if you multi-scan it 200 times, even if each of the scans is
made at 8-bit? :-)
Please don't get me wrong. I hate guessing. But if the metrics are
inadequate then you may end up making matters worse. I mean you, can't
measure millimeters with a ruler that only has marks for centimeters.

But, you see, the *metrics* are not inadequate (or at least, wouldn't be
if my program wasn't full of bugs).
At worst, it's the (8-bit) scanned *picture* that's inadequate, but in
that case, it can only be as inadequate for "guessing" as it is for
using measured values!

That is, at most you should be able to obtain, by guessing, the *same*
result I obtain with measurement, but no better.
Then, sure, using a 16-bit scan of the picture may well improve the
results of *both* guessing and using measurements.
On a tangent, I personally don't use any sharpening at all. I compared
sharpened images to the originals (at large magnification) and didn't
really like what unsharp mask did. But, that's a matter of personal
taste...

Isn't that because of the haloes perhaps?
Halos are precisely one of the things I wish to avoid with the PSF
method, which should be able to compute optimal sharpening that
*doesn't* cause haloes.

I think the main problem will (still) be noise, as it will be amplified
by the sharpening, and computing the PSF doesn't help much with that.

I think it's going to be a matter of compromise here: how much noise am
I prepared to accept versus how much (or, up to what frequency) do I
want to improve the MTF.
I was shocked when I discovered this on my film scanner. I expected
that the channel alignment would be much more accurate.

Well, looking at the MTF graphs, I see that while my scanner does about
1500dpi on the CCD axis, it does something like 1300dpi on the motor axis.

Now, this is the resolution, not the color aberration, but I'm afraid it
gives a measure of color aberration, too. Actually, I think color
aberrations increase *more* than resolution decreases.
[snip: the ruler test]

I'll try, just for laughs (or cries).
But even after measuring what's going on with a ruler, I'm still afraid
there is very little that can be done.

Possibly, one could scan a ruler next to the film, and use some program
to "reshape" every color channel based on the positions of the ruler
ticks... but, I dunno, I have a feeling this is only going to work in
theory.
That's what I'm saying (individual channel measurements) only use a
straight average when you combine the results. Luminance will simply
introduce a large green bias at the expense of red, for the most part.

More at the expense of blue, I think.
But, besides this, what you said before was that either average or
luminance will not be right when the channels are misaligned.

What I'm saying is, well, this will be no issue, as the channels will be
re-aligned *before* taking either average or luminance.
"Will", because this is not currently done in my program -- don't know
about Imatest.
[snip]
I'm not sure. Yes, I have the real values, but... my program tries to
answer the question "how much resolution can my scanner get from the
original?". The answer itself depends on the observer's eye, as a person
might be able to see constrasts less than 10%, and another might only
see up to 15%, say.

No, the answer is not based on any one individual person. The answer
is quite clear if you read out the gray values. Whether one person can
see those grays and the other can't doesn't really matter in the
context of objective measurements.

But then why were 50% and (expecially) 10% chosen as standard?
Because of some physical reason? No, because they make perceptual sense:
10% is the boundary where the average human eye stops seeing contrast.

Sure, if you read the *whole* MTF instead of just MTF50 and MTF10, you
don't have to chose an observer-dependent frequency; but, like it or
not, MTF50 and MTF10 are standards. Sometimes it makes sense to follow
standards.
If you want to test human perception that's a completely different
test. However, that doesn't change the *objective* resolution of the
scanner.

I mean take number of colors on a monitor. You can objectively
determine how many colors your monitor can display. And then you can
also determine how many of those colors an average person can
distinguish. Those are two totally different test, using different
metrics.

But you can express the number of colors a monitor can display with
*one* number.

You can't express a scanner's "objective resolution" with one number;
you must print an MTF grpah.
But what if you want a measure in ppi (which many people want)? Then you
have to *choose a point* on the MTF, and the choice will be based on
human perception: "you scanner can do 1500ppi [at 10% contrast, because
that's what you will see at best]".
It follows that such a figure should be a *perceptually weighted*
average of the three channels' values.

On the other hand, I can see some merit with using a simple average when
presenting someone with the *whole* MTF graph.

But still, for the purpose of sharpening, Bart says color aberrations
will occur if average is used instead of sharpening. We'll see how that
works out (hopefully, if I can complete the program).
In that case, it appears you're not really interested in your
scanner's actual resolution but your perception of that resolution.
And that's a different test.

Maybe, but it seems that Imatest is interested in the same, and Imatest
doesn't look like it was written by idiots who didn't know what they
were testing.

Anyway, let's end it here: my program will default to luminance, but
will offer an option of using average, and it will always also show the
three channels separately anyway.

The beauty of choice!


by LjL
(e-mail address removed)
 
Unless you mean...

Yes, that's what I mean! ;o)
... that I should *scan the slanted edge* at 16 bit -- as you say that
it's the *measurement* that's inaccurate.
Bingo!

But, you see, Imatest's manual doesn't particularly insist on scanning
the edge at 16-bit, and I think I can see the reason: the oversampling
that the slant allows compensates very well for the low bit-depth.

I don't know what Imatest manual says, but I suspect being a generic
type of test they compensate in advance just in case people do use
less that optimal bit depths.

But that doesn't mean one should use lower bit depths if one has more.
Wouldn't you think an image would get to have a much higher bit depth
than 8 bit if you multi-scan it 200 times, even if each of the scans is
made at 8-bit? :-)

Not really, especially not for flatbeds because of the stepper motor
inaccuracies. You will just blur the image more. Not to mention it
will take "forever" to acquire all those 100s of samples. And all
along you have a ready and (compared to 200 * 8-bit scans) a quick
solution i.e. 16-bit!

The point I'm making is why try to "fix" 8-bit when there is 16-bit
readily available? Now, if your scanner did *not* have 16-bit then,
yes, trying to get 8-bit as accurate as possible makes sense.

But having said that, in my life I've done even sillier things (much,
*much*, sillier things!) simply because they were fun. And if that's
the goal, than just ignore everything I say and have fun! :o)
But, you see, the *metrics* are not inadequate (or at least, wouldn't be
if my program wasn't full of bugs).
At worst, it's the (8-bit) scanned *picture* that's inadequate, but in
that case, it can only be as inadequate for "guessing" as it is for
using measured values!

Yes, 8-bit image is inadequate which results in inadequate metrics.
That is, at most you should be able to obtain, by guessing, the *same*
result I obtain with measurement, but no better.
Then, sure, using a 16-bit scan of the picture may well improve the
results of *both* guessing and using measurements.

It will not improve guessing because we only have 8-bit eyes (some say
even only 6-bit) so you will not even be able to perceive or see the
extra color gradation available in 16-bit. But *mathematics* will!
Isn't that because of the haloes perhaps?

Halos is just one thing, but I don't like the concept behind it, that
edges are changed in such a drastic way.

The problem is the image is *not* made sharper but the contrast of
transition between dark and light is simply increased because humans
perceive high contrast as sharpness. It's an optical illusion, really.

That's what bothered me, conceptually. The image was degraded in order
to generate an optical illusion and that just doesn't make sense to
me. It's like anti-aliasing (which I *HATE*!) and which *pretends* to
"remove" jaggies by blurring everything!!! To me, that's madness! But
that's just me... ;o)
Halos are precisely one of the things I wish to avoid with the PSF
method, which should be able to compute optimal sharpening that
*doesn't* cause haloes.

By definition (because of increased contrast) it will cause haloes.
Whether you see them or not is another matter. If you zoom in and
compare to the original you will see them.
I think the main problem will (still) be noise, as it will be amplified
by the sharpening, and computing the PSF doesn't help much with that.

I think it's going to be a matter of compromise here: how much noise am
I prepared to accept versus how much (or, up to what frequency) do I
want to improve the MTF.

Yes, that's exactly what it boils down to! You have to balance one
against the other. Which means, back to "guessing" what looks better.
[snip: the ruler test]

I'll try, just for laughs (or cries).
But even after measuring what's going on with a ruler, I'm still afraid
there is very little that can be done.

Possibly, one could scan a ruler next to the film, and use some program
to "reshape" every color channel based on the positions of the ruler
ticks... but, I dunno, I have a feeling this is only going to work in
theory.

It will work in practice too if you have guides along both axis. The
trouble is that's very clumsy and time consuming.

If you do decided to do that I would create a movable frame so you
have guides on all 4 sides. That's because the whole assembly wiggles
as it travels so the distortion may not be the same at opposite edges.

Also, the misalignment is not uniform but changes because the stepper
motor sometimes goes faster and sometimes slower! So you will not be
able to just change the height/width of the image and have perfect
reproduction. You'll actually have to transform the image. Which means
superimposing a grid... Which means figuring out the size of that grid
i.e. determine the variance of stepper motor speed change... Argh!!

Of course, the key question is, is it worth it? In my case, in the
end, I decided it wasn't. But it still bugs me! ;o)
More at the expense of blue, I think.
But, besides this, what you said before was that either average or
luminance will not be right when the channels are misaligned.

What I'm saying is, well, this will be no issue, as the channels will be
re-aligned *before* taking either average or luminance.

I would *not* align them because that would change the values!!! And
those changes are bound to be much more than what you're measuring!

In principle, you should never do anything to the data coming from the
scanner if the goal is to perform measurements. That's why even gamma
is not applied but only linear data is used for calculations.

I really think the best way is to simply do each channel separately
and then see what the results are. In theory, they should be pretty
equal. If you want a single number I would then just average those
three results.
[snip]

No, the answer is not based on any one individual person. The answer
is quite clear if you read out the gray values. Whether one person can
see those grays and the other can't doesn't really matter in the
context of objective measurements.

But then why were 50% and (expecially) 10% chosen as standard?
Because of some physical reason? No, because they make perceptual sense:
10% is the boundary where the average human eye stops seeing contrast.

No, there is physical reason why those luminance percentages were
chosen. It's to do with how our eyes are built and the sensors for
individual colors.

I mean, if you're measuring how fast a car is going, are you going to
change the scale because of how you perceive speed or are you going to
ignore your subjective perception and just measure the speed?

This is the same thing. You measure the amounts of gray the scanner
can't resolve. How you perceive this gray is, is totally irrelevant to
the measurement.

Now, if you want to measure *your perception*, that's a different
thing altogether. But before you measure something as subjective as
individual perception, you still need objective measurements as a
starting point and a baseline.
But still, for the purpose of sharpening, Bart says color aberrations
will occur if average is used instead of sharpening. We'll see how that
works out (hopefully, if I can complete the program).

Bart has a tendency to be literal and just repeats what he reads
elsewhere without paying enough attention to context. Mind you, it's
good information with good links and I often save his messages because
of that, but it's really just repeating stuff seen somewhere else.

I mean, in this case Bart may very well be right, but I'd ask Kennedy
because Kennedy thinks laterally and actually analyzes what the
implications are in the full context.
Maybe, but it seems that Imatest is interested in the same, and Imatest
doesn't look like it was written by idiots who didn't know what they
were testing.

They may be testing a different thing, though. BTW, why don't you just
use Imatest?

Anyway, as I said on the outset. I'm just kibitzing here and threw in
that luminance note because it seemed contradictory to the task.

But instead of wasting time on replying carry on with programming! :o)

Don.
 
Don said:
On Fri, 30 Sep 2005 18:36:39 +0200, "Lorenzo J. Lucchini"

[snip]
Wouldn't you think an image would get to have a much higher bit depth
than 8 bit if you multi-scan it 200 times, even if each of the scans is
made at 8-bit? :-)

Not really, especially not for flatbeds because of the stepper motor
inaccuracies. You will just blur the image more. Not to mention it
will take "forever" to acquire all those 100s of samples. And all
along you have a ready and (compared to 200 * 8-bit scans) a quick
solution i.e. 16-bit!

Ok, you're probably right here for "real" images.
But this doesn't apply to the slanted edge: you aren't *really* taking
200 scans, it's just that every scan line "counts as a sampling pass" in
reconstructing the ESF.

The "16-bit quick solution" don't change much for scanning a slanted
edge, as you have to do the oversampling anyway.

It might be that scanning the edge at 16 bit still gives better results
than scanning it at 8 bit. Let's find out...

No, let's not find out: SFRWin doesn't accept 16 bit edges.
(Which might be a clue that they're not necessary, anyway)

Don't know about Imatest.

By the way, I see that the levels (or perhaps the gamma) are different
if I scan at 16-bit and if I scan at 8-bit, with otherwise the same
settings. Actually, the 16-bit scan clips. Wonderful, another bug in my
fine scanner driver!
The point I'm making is why try to "fix" 8-bit when there is 16-bit
readily available? Now, if your scanner did *not* have 16-bit then,
yes, trying to get 8-bit as accurate as possible makes sense.

But having said that, in my life I've done even sillier things (much,
*much*, sillier things!) simply because they were fun. And if that's
the goal, than just ignore everything I say and have fun! :o)

But, no, one goal is to make a program alternative to Imatest (its SFR
function, at least) and SFRWin, and the other goal is to reconstruct a
PSF to sharpen images.

The goal is not to get 16-bit from 8-bit... aren't you just getting
confused with other threads or parts of this thread?

Yes, currently I'm scanning things at 8-bit. Yes, I'm scanning my
slanted edges at 8-bit, too.
But my program works in floating point, it can load both 8-bit or 16-bit
edge images (though the code for loading 16-bit PPM isn't tested right
now); it's just that I'm using it with 8-bit images right now.

It's not functional enough to make a difference at the moment, in any case!
Yes, 8-bit image is inadequate which results in inadequate metrics.

Let's agree on terms. I took the "metrics" as meaning the slanted edge
test results, and the "image" is just the image, that is the picture to
be sharpened (or whatever).
It will not improve guessing because we only have 8-bit eyes (some say
even only 6-bit) so you will not even be able to perceive or see the
extra color gradation available in 16-bit. But *mathematics* will!

No, I was saying that *with an 8-bit image* your "guess" couldn't be
better than my measurements -- the best you can achieve is to make it
*as good as* the measurements. Visibile or not to the eye, there are
only 8 bpc in the image.

And then, if our eyes really have the equivalent of 6 bits, you wouldn't
be able to guess as well as you measure even with a poor 8-bit image!
[snip]
Halos are precisely one of the things I wish to avoid with the PSF
method, which should be able to compute optimal sharpening that
*doesn't* cause haloes.

By definition (because of increased contrast) it will cause haloes.
Whether you see them or not is another matter. If you zoom in and
compare to the original you will see them.

No wait -- my understanding is that, by definition, "optimal sharpening"
is the highest amount you can apply *without* causing haloes.
Perhaps unsharp mask in particular always causes them, I don't know, but
there isn't only unsharp mask around.

Haloes show quite clearly on the ESF graph, and I assure you that I
*can* apply some amount of sharpening that doesn't cause "hills" in the
ESF graph.
Yes, that's exactly what it boils down to! You have to balance one
against the other. Which means, back to "guessing" what looks better.

As far as noise is concerned, yes, this is mostly true.
But noise and haloes are two separate issues!

Anyway, what would seem a reasonable "balance" to me is this: apply the
best sharpening you can that does not cause noise to go higher than the
noise a non-staggered-CCD-array would have.

This is what I'd call the "right" sharpening for Epson scanners: make it
as sharp as the linear CCD scanners, making noise go no higher than a
linear CCD scanner's (since you know a linear CCD of the same size as my
staggered CCD has more noise in general, as the sensors are smaller).
[snip: the ruler test]

I'll try, just for laughs (or cries).
But even after measuring what's going on with a ruler, I'm still afraid
there is very little that can be done.

Possibly, one could scan a ruler next to the film, and use some program
to "reshape" every color channel based on the positions of the ruler
ticks... but, I dunno, I have a feeling this is only going to work in
theory.

It will work in practice too if you have guides along both axis. The
trouble is that's very clumsy and time consuming.

If you do decided to do that I would create a movable frame so you
have guides on all 4 sides. That's because the whole assembly wiggles
as it travels so the distortion may not be the same at opposite edges.

Also, the misalignment is not uniform but changes because the stepper
motor sometimes goes faster and sometimes slower! So you will not be
able to just change the height/width of the image and have perfect
reproduction. You'll actually have to transform the image. Which means
superimposing a grid... Which means figuring out the size of that grid
i.e. determine the variance of stepper motor speed change... Argh!!

Yes, this is precisely what I meant with "is only going to work in
theory". Remember also that I was talking in the context of color
aberrations, which means the process would have to be repeated *three
times* separately for each channel!

It'd take ages of processing times... and, also, what kind of
super-ruler should we get? Any common ruler just isn't going to be good
enough: the ticks will be to thick, non-uniformely spaced and unsharp;
and the transparent plastic the ruler is made of will, itself, cause
color aberrations.
Of course, the key question is, is it worth it? In my case, in the
end, I decided it wasn't. But it still bugs me! ;o)

I know. By the way, changing slightly the topic, what about two-pass
scanning and rotating the slide/film 90 degrees between the two passes?
I mean, we know the stepper motor axis has worse resolution than the CCD
axis. So, perhaps multi-pass scanning would work best if we let the CCD
axis get a horizontal *and* a vertical view of the image.

Of course, you'd still need to sub-pixel align and all that hassle, but
perhaps the results could be better than the "usual" multi-pass scanning.
Clearly, there is a disadvantage in that you'd have to physically rotate
your slides or film between passes...
I would *not* align them because that would change the values!!! And
those changes are bound to be much more than what you're measuring!

Hm? I don't follow you. When you have got the ESF, you just *have* your
values. You can then move them around at your heart's will, and you
won't lose anything. Which implies that you can easily move the three
ESFs so that they're all aligned (i.e. the "edge center" is found in the
same place), before taking any kind of average.
In principle, you should never do anything to the data coming from the
scanner if the goal is to perform measurements. That's why even gamma
is not applied but only linear data is used for calculations.

Yes, and I'm not doing anything to the data *coming from the scanner*;
just to the ESF, which is a high-precision, floating point function that
I've calculated *from* the scanner data.
It's not made of pixels: it's made for x's and y's, in double precision
floating point. I assure you that I'm already doing so much more
(necessary) evil to these functions, that shifting them around a bit
isn't going to lose anything.
I really think the best way is to simply do each channel separately
and then see what the results are. In theory, they should be pretty
equal. If you want a single number I would then just average those
three results.

Yes, in theory. In practice, my red channel has a visibly worse MTF than
the green channel, for one.
[snip]

No, the answer is not based on any one individual person. The answer
is quite clear if you read out the gray values. Whether one person can
see those grays and the other can't doesn't really matter in the
context of objective measurements.

But then why were 50% and (expecially) 10% chosen as standard?
Because of some physical reason? No, because they make perceptual sense:
10% is the boundary where the average human eye stops seeing contrast.

No, there is physical reason why those luminance percentages were
chosen. It's to do with how our eyes are built and the sensors for
individual colors.

Did you just say "with how our eyes are built"? Now that's perceptual!
Ok, not necessarily perceptual in the sense that it has to do with our
brain, but it has to do with the observer.

MTF10 is chosen *because the average observer can't see less than 10%
contrast* (because of how his eyes are built, or whatever; it's still
the observer, not the data).
I mean, if you're measuring how fast a car is going, are you going to
change the scale because of how you perceive speed or are you going to
ignore your subjective perception and just measure the speed?

Hmm, we definitely base units and scales of measurements on our
perception. We don't use light-years, we use kilometers; some weird
peoples even use "standardized" parts of their bodies (like my "average
observer", you see), such as feet, inches and funny stuff like that ;-P

Sure, we do use light-years now when we measure things that are
*outside* our normal perception.
This is the same thing. You measure the amounts of gray the scanner
can't resolve. How you perceive this gray is, is totally irrelevant to
the measurement.

But the problem is that there is *no* amount of gray the scanner can't
resolve! It can resolve everything up to half Nyquist. I mean *my*
scanner. It's just that it resolves frequencies near Nyquist with such a
low contrast that they're hardly distinguishable.

Where do you draw the line? Just how much uniformely gray your test
pattern must be before you say "ok, this is the point after which my
scanner has no useful resolution"?

I don't see a choice other than the perceptual choice. Which also has
the advantage of being a farily standard choice.
[snip]

They may be testing a different thing, though. BTW, why don't you just
use Imatest?

Because they're asking money for it :-) I've had my trial runs, finished
them up, and I'm now left with SFRWin and no intention to buy Imatest
(not that it's a bad program, it's just that I don't buy much of
anything in general).

I'm not sure I would call myself a "free software advocate", but I
definitely do like free software. And certainly the fact that my program
might be useful to other people gives me more motivation to write it,
than if it were only useful to myself.
Not necessarily altruism, mind you, just seeing a lot of downloads of a
program I've written would probably make me feel a star :-) hey, we're
human.
Anyway, as I said on the outset. I'm just kibitzing here and threw in
that luminance note because it seemed contradictory to the task.

But instead of wasting time on replying carry on with programming! :o)

I can't keep programming all day anyway! -- well, I've done that
yesterday, and the result was one of those headaches you don't quickly
forget.

Anyway, have you tried out ALE yet? I don't think it can re-align
*single* rows or columns in an image, but it does perform a lot of
geomtry transformation while trying to align images. And it works with
16 bit images and all, which you were looking for, weren't you? It's
just so terribly slow.


by LjL
(e-mail address removed)
 
Hi !

I did not saw this thread before I started my own.
But may I ask you: What sfr do you actually get from your
scanners ??

regards

john rehn
 
Back
Top