Menu

Rejected edge should produce worse quality than a contaminated edge

dima
2026-05-21
5 days ago
  • dima

    dima - 2026-05-21

    Hi. Thanks for handling the bug reports. I've a few more small things and a bigger thing. This is a small thing: primarily a documentation request.

    Esf_model::estimate_esf_clipping() and Esf_model_...::build_esf() return an int which means:

    • -1: Failure. No results returned. Edge rejected because of shifted peak slope
    • 0: success! Results returned
    • 1: Warning. Results returned. Probably contamination. tagging edge as dodgy

    This logic doesn't appear in any comments, and is highly confusing. Can we define an enum for these 3 cases, and return that enum?

    And it looks like we don't handle the output completely correctly. In Mtf_core::compute_mtf() we call build_esf(). If -1, we return immediately with quality = poor_quality. Otherwise do all the computation. And then if compute_mtf() returned +1, we return very_poor_quality. Probably those should be reversed, right? -1 -> very_poor_quality and +1 -> poor_quality.

    Oh, and in that same chunk of code we have

        if (fabs(quad - 26.565051) < 1) {
            quality = medium_quality;
        }
    

    What's special about 26.565051? Being within 1deg of this angle is known to produce poor results?

    Thanks.

     
    • Frans van den Bergh

      Hi!

      The magic angle, 26.565051 degrees is just atan(0.5), meaning an edge with a slope of 1/2. If the slanted edge is at exactly this angle you do not get sufficient oversampling for the slanted-edge method to avoid aliasing. In the early days of MTF Mapper development I did not have such a good grasp of this phenomenon, but later I added explicit measurement of the effective oversampling rate, e.g., the Snr.oversampling() method.

      There are some more rule-of-thumb magic numbers here: strictly speaking you want oversampling() to be 8, but I generally find that enforcing oversampling() >= 6.0 is good enough to select all the high-quality measurements. This will automatically reject the slope = 1/2 case (which would have oversampling() = 4.0). And the values scale as you would expect: a 45 degree edge will yield oversampling() = 2.0, and a 0-degree edge would yield oversampling() = 1.0.

      So a more comprehensive overhaul would remove all the edge-orientation decisions and focus only on that single oversampling() metric.

      Regards,
      Frans

       
  • dima

    dima - 5 days ago

    That's great to know. Let me use these oversampling metrics for the quality in my scripts. Will respond to the wide-angle post. Thanks

     

Log in to post a comment.