Opencv图像处理---图像金字塔

理论

图像金字塔

  • 图像金字塔是图像的集合 - 全部来自单个原始图像 - 它们被连续地下采样直到达到某个期望的停止点。
  • 有两种常见的图像金字塔:
  1. 高斯金字塔:用于下采样图像
  2. 拉普拉斯金字塔:用于从金字塔下方的图像重建上采样图像(分辨率较低)

高斯金字塔

  • 想象金字塔是一组图层,图层越高,尺寸越小。
  • 每个层从下到上编号,因此层(i + 1)(表示为(Gi + 1)小于层i(Gi))。
  • 要在高斯金字塔中生成层(i + 1),我们执行以下操作:
  1. 使用高斯内核卷积Gi:
  2. 删除每个偶数行和列。
  • 您可以很容易地注意到,生成的图像将是其前一个区域的四分之一。 在输入图像G0(原始图像)上迭代此过程会产生整个金字塔。
  • 上述过程对于下采样图像很有用。 如果我们想让它变得更大怎么办?:用零填充列。
  1. 首先,将图像的尺寸增大到每个尺寸的原始尺寸的两倍,即新的偶数行和
  2. 使用上面显示的相同内核执行卷积(乘以4)以近似“缺失像素”的值
  • 这两个过程(如上所述的下采样和上采样)由OpenCV函数cv :: pyrUp和cv :: pyrDown实现。

代码

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
using namespace cv;
Mat src, dst, tmp;
const char* window_name = "Pyramids Demo";
int main( void )
{
  printf( "\n Zoom In-Out demo  \n " );
  printf( "------------------ \n" );
  printf( " * [u] -> Zoom in  \n" );
  printf( " * [d] -> Zoom out \n" );
  printf( " * [ESC] -> Close program \n \n" );
  src = imread( "../data/chicky_512.png" );
  if( src.empty() )
    { printf(" No data! -- Exiting the program \n");
      return -1; }
  tmp = src;
  dst = tmp;
  namedWindow( window_name, WINDOW_AUTOSIZE );
  imshow( window_name, dst );
  for(;;)
  {
    int c;
    c = waitKey(10);
    if( (char)c == 27 )
      { break; }
    if( (char)c == 'u' )
      { pyrUp( tmp, dst, Size( tmp.cols*2, tmp.rows*2 ) );
        printf( "** Zoom In: Image x 2 \n" );
      }
    else if( (char)c == 'd' )
      { pyrDown( tmp, dst, Size( tmp.cols/2, tmp.rows/2 ) );
        printf( "** Zoom Out: Image / 2 \n" );
      }
    imshow( window_name, dst );
    tmp = dst;
   }
   return 0;
}

解释

  • 加载图像
  • 创建一个Mat对象来存储操作的结果(dst),另一个用于保存时间结果(tmp)。
  • 创建一个窗口以显示结果
  • 执行无限循环等待用户输入。
  • 进行上采样(按'u'后):
  • 执行下采样(按'd'后):
  • 请注意,输入图像可以按两倍(两个维度)进行划分非常重要。 否则,将显示错误。
  • 最后,我们用显示的当前图像更新输入图像tmp,以便对其执行后续操作。

效果

原始图像如下所示:

向下采样的效果图

向上采样的效果图

猜你喜欢

转载自blog.csdn.net/LYKymy/article/details/83153927