jsvascript图像处理—(计算机视觉应用)图像金字塔

图像金字塔是一种由同一图像的多个分辨率构成的数据结构。每一层的大小是前一层的一半,高频信息(细节)被过滤,低频信息(谐波)被保留。

JavaScript图像处理-图像金字塔

简介

图像金字塔是一种由同一图像的多个分辨率构成的数据结构。每一层的大小是前一层的一半,高频信息(细节)被过滤,低频信息(谐波)被保留。

图像金字塔的主要应用包括:

  • 缩放图片
  • 图像分割
  • 特征提取
  • 增强图像

处理流程

对于每一层的金字塔图像,可以通过下采样(up-sampling)和高斯卷积(Gauss blur)来实现金字塔层数的构建。

下采样

下采样是将原图像变更为该级别的大小的方法。这涉及到两个步骤:滤波和采样。

下采样过程中可以采用多种滤波器,通常使用Box或Gaussian来实现。Box滤波器的处理方式比Gaussian更快更简单,但是Gaussian滤波器产生的输出比较好。所以,在使用Box滤波器之前,应该尽可能使用Gaussian来近似。

下采样达到的效果是保留图像中某些区域的平均值。每次下采样通常导致图像边缘的失真,可以通过越来越增大的滤波器来逐渐缓解失真的程度。

高斯卷积

高斯模糊是常用的图像模糊技术之一,它可以模糊图像从而去除图像噪声,同时也可以作为图像锐化的前置步骤。

电脑中由于所有图像都被处理成了离散的像素,所以无法真正意义上的实现高斯函数。可是可以采用中心极限定理,计算机实现从而来实现高斯模糊。

高斯函数的处理通常采用的是快速四次平方滤波器(Fourier Low-Pass/High-Pass Filter)

示例

示例1:下采样

下面的代码演示了一个简单的下采样函数的实现。downsample 函数接受一个图像的像素数组和宽高,返回一个下采样后的图像,宽高为原来的一半。

function downsample(src, srcWidth, srcHeight) {
  const dstWidth = srcWidth / 2;
  const dstHeight = srcHeight / 2;
  const dst = new Array(dstWidth * dstHeight * 3);

  for (let j = 0; j < dstHeight; j++) {
    for (let i = 0; i < dstWidth; i++) {
      const idx = (j * dstWidth + i) * 3;
      const x = i * 2;
      const y = j * 2;
      const srcIdx = (y * srcWidth + x) * 3;
      dst[idx + 0] = (src[srcIdx + 0] + src[srcIdx + 3] + src[srcIdx + srcWidth * 3] + src[srcIdx + srcWidth * 3 + 3]) / 4;
      dst[idx + 1] = (src[srcIdx + 1] + src[srcIdx + 4] + src[srcIdx + srcWidth * 3 + 1] + src[srcIdx + srcWidth * 3 + 4]) / 4;
      dst[idx + 2] = (src[srcIdx + 2] + src[srcIdx + 5] + src[srcIdx + srcWidth * 3 + 2] + src[srcIdx + srcWidth * 3 + 5]) / 4;
    }
  }

  return {
    data: new Uint8ClampedArray(dst),
    width: dstWidth,
    height: dstHeight
  };
}

示例2:高斯卷积

下面的代码演示了一个简单的高斯卷积函数的实现。将一个3x3的高斯核卷积输入图像,可以得到输出图像。

function applyGaussianKernel(src, width, height) {
  const kernel = [
    0.0625,
    0.125,
    0.0625,
    0.125,
    0.25,
    0.125,
    0.0625,
    0.125,
    0.0625
  ];
  const dst = new Uint8ClampedArray(width * height * 3);

  // Loop over pixels in the input image.
  for (let u = 0; u < width; u++) {
    for (let v = 0; v < height; v++) {
      // Loop over the kernel.
      let r = 0, g = 0, b = 0, i = 0;
      for (let m = -1; m <= 1; m++) {
        for (let n = -1; n <= 1; n++) {
          const x = clamp(u + m, 0, width - 1);
          const y = clamp(v + n, 0, height - 1);
          const idx = (y * width + x) * 3;
          r += src[idx] * kernel[i];
          g += src[idx + 1] * kernel[i];
          b += src[idx + 2] * kernel[i];
          i++;
        }
      }
      const dstIdx = (v * width + u) * 3;
      dst[dstIdx] = r;
      dst[dstIdx + 1] = g;
      dst[dstIdx + 2] = b;
    }
  }

  return {
    data: dst,
    width: width,
    height: height
  };
}

总结

使用图像金字塔可以进行多种图像处理操作,比如图像缩放、特征提取、边缘检测等。理解图像金字塔,可以有助于大幅度提高图像应用的性能和效果。

参考资料

  • https://en.wikipedia.org/wiki/Pyramid_representation
  • 金字塔

本文标题为:jsvascript图像处理—(计算机视觉应用)图像金字塔

基础教程推荐