Lanczos resampling

Lanczos resampling - Detailed Pedia | 全部文件(25KB)

Lanczos resampling is often used also for multivariate interpolation, for example to resize or rotate a digital image. It has been considered the "best compromise" among several simple filters for this purpose. The filter is named after its inventor, Cornelius Lanczos (匈牙利人).

Multivariate means involving multiple dependent variables resulting in one outcome.

In engineering and science one often has a number of data points, as obtained by sampling or some experiment, and tries to construct a function which closely fits those data points. This is called curve fitting. Interpolation is a specific case of curve fitting, in which the function must go exactly through the data points.

1.cpp:

#include "bmp24.h"
// https://github.com/avaneev/avir
#include "lancir.h" // 仅头文件即可,支持SIMD和NEON
int main() {
  BMP24 in; in.load("in.bmp");
  int w = in.width, h = in.height, w2 = 286, h2 = 201;
  BMP24 out; out.create(w2, h2);
  avir::CLancIR lir;
  /* void resizeImage( const Tin* const SrcBuf, const int SrcWidth,
    const int SrcHeight, const int SrcSSize, Tout* const NewBuf,
    const int NewWidth, const int NewHeight, const int NewSSize,
    const int ElCount); */
  lir.resizeImage(in.bits, w, h, in.stride, out.bits, w2, h2, out.stride, 3);
  out.save("lir.bmp");
  return 0;
}

2.cpp:

#include <math.h>
#include "bmp24.h"

typedef float real;
#define fabs  fabsf
#define sin   sinf
const real pi = 3.1415926535897932, pipi = pi * pi;
// The parameter a is a positive integer, typically 2 or 3, which determines the size of the kernel.
const real a = 3; // 应该是int哈。光顾着L()里不用int转double,忘了main()里还俩for循环呢
real L(real x) {
  if (fabs(x) < 1e-9) return 1.0;
  if (x >= -a && x < a) return a * sin(pi*x) * sin(pi*x/a) / (pipi * x*x);
  return 0.0;
}

int main() {
  BMP24 in; in.load("in.bmp");
  int w = in.width, h = in.height, w2 = 286, h2 = 201;
  const real ratio = 3.14;
  BMP24 out; out.create(w2, h2);
  uint8_t* row2 = out;
  for (int y2 = 0; y2 < h2; y2++) {
    uint8_t* p2 = row2;
    for (int x2 = 0; x2 < w2; x2++) {
      real yr = y2 / ratio, xr = x2 / ratio;
      // 为in[1.23][3.45]这样的点估RGB
      int yf = int(yr), xf = int(xr); // f(loor)
      real bgr[3] = { 0 };
      for (int y = yf - a + 1; y <= yf + a; y++) {
        for (int x = xf - a + 1; x <= xf + a; x++) {
            if (y < 8 || y >= h - 8 || x < 8 || x >= w - 8) {
              uint8_t* p = in + yf * in.stride + xf * 3;
              *bgr = *p; bgr[1] = p[1]; bgr[2] = p[2];
              goto done;
            }
            const uint8_t* p = in + y * in.stride + x * 3;
            const real t = L(xr - x) * L(yr - y);
            *bgr += *p * t; bgr[1] += p[1] * t; bgr[2] += p[2] * t;
        }
      }
      done:
      for (int i = 0; i < 3; i++) {
        real  t = bgr[i];
        #if 0
        if (t < 0) t = 0;
        if (t > 255) t = 255;
        #endif
        p2[i] = int(t + 0.5);
      }
      p2 += 3;
    }
    row2 += out.stride;
  }
  out.save("simple.bmp");
  return 0;
}
posted @ 2023-01-09 20:46  Fun_with_Words  阅读(89)  评论(0编辑  收藏  举报









 张牌。