0

I'm attempting to improve performance of the OpenCV lanczos interpolation algorithm for applying homography transformations to astronomical images, as it is prone to ringing artefacts around stars in some images. My approach is to apply homography twice, once using lanczos and once using bilinear filtering which is not susceptible to ringing, but doesn't perform as well at preserving detail. I then use the bilinear-interpolated output as a guide image, and clamp the lanczos-interpolated output to the guide if it undershoots the guide by more than a given percentage. I have working code (below) but have 2 questions:

  1. It doesn't seem optimal to iterate across elements in the Mat. Is there a better way of doing the compare and replace loop using OpenCV Mat methods?

  2. My overall approach is computationally expensive - I'm applying homography to the entire Mat twice. Is there an overall better approach to preventing deringing of lanczos interpolation? (Rewriting the entire algorithm plus all the various optimisations that OpenCV makes available is not an option for me.)

    warpPerspective(in, out, H, Size(target_rx, target_ry), interpolation, BORDER_TRANSPARENT);
    if (interpolation == OPENCV_LANCZOS4) {
        int count = 0;
        // factor sets how big an undershoot can be tolerated
        double factor = 0.75;
        // Create guide image
        warpPerspective(in, guide, H, Size(target_rx, target_ry), OPENCV_LINEAR, BORDER_TRANSPARENT);
        // Compare the two, replace out pixels with guide pixels if too far out
        for (int i = 0 ; i < out.rows ; i++) {
            const double* outi = out.ptr<double>(i);
            const double* guidei = guide.ptr<double>(i);
            for (int j = 0; j < out.cols ; j++) {
                if (outi[j] < guidei[j] * factor) {
                    out.at<double>(i, j) = guidei[j];
                    count++;
                }
            }
        }
    }
Markus
  • 5,976
  • 5
  • 6
  • 21
Adrian K-B.
  • 99
  • 1
  • 8
  • use comparison on entire matrices, work with masks. use official documentation, read the contained tutorials. -- crosspost: https://forum.opencv.org/t/deringing-lanczos4-interpolation/10419 – Christoph Rackwitz Oct 04 '22 at 11:13

1 Answers1

0

With a steer from Christoph Rackwitz, the answer was surprisingly simple:

        compare(out, (guide * factor), mask, CMP_LT);
        guide.copyTo(out, mask);

Thanks :)

Adrian K-B.
  • 99
  • 1
  • 8