Opencv3笔记14——图像金字塔

6 图像金字塔与图像尺寸缩放

opencv提供尺寸缩放的方法

  • resize函数
  • pyrUp(),pyrDOwn()函数,对图像进行向上采样和向下采样

6.1 关于图像金字塔

图像金字塔主要用于图像分割

  • 高斯金字塔:向下采样,主要的图像金字塔
  • 拉普拉斯金字塔:用来从金字塔底层图像重建上层未采样的图像
  • 区别:高斯金字塔用来向下采样图像,拉普拉斯金字塔用来从底层图像向上采样,重建一个图像。

向上就是图像尺寸加倍,向下就是图像尺寸减半

6.2 高斯金字塔

6.2.1 对图像的向下取样

为了获取层级未 G i + 1 的金字塔图像
(1):对图像 G i 进行高斯内核卷积
(2):将所有偶数行和列去除
结果图像减少为原来图像的四分之一

6.2.2 对图像的向上取样

(1):将图像在每个方向上扩大为原来的两倍,新增的行和列以0填充
(2):使用先前同样的内核(乘以4)与放大的图像卷积,获取新增像素的近似值

6.3 拉普拉斯金字塔

数学定义

L i = G i U P ( G i + 1 ) g 5 × 5

6.4 尺寸调整:resize()函数

此函数将源图像精确地转换为指定尺寸的目标函数图像,函数原型

void resize(InputArray src, OutputArray dst,Size dsize, double fx = 0, double fy = 0, int interpolation = INTER_LINEAR)
  • 第三个参数:Size类型的dsize,输出图像的大小,如果等于零,由公式决定

    d s i z e = S i z e ( r o u n d ( f x × s r c . c o l s ) , r o u n d ( f y × s r c . r o w s ) )

  • 第四个参数:fx表示沿水平轴的缩放系数,默认值为0,当等于0的时候

    ( d o u b l e ) d s i z e . w i d t h / s r c . c o l s

  • 第五个参数:fy表示,沿垂直轴的缩放系数,默认值为0, ( d o u b l e ) d s i z e . h e i g h t / s r c . r o w s
  • 第六个参数,int类型的interpolation,用于指定插值的方式。
    • INTER_NEAREST最近邻插值
    • INTER_LINEAR线性插值
    • INTER_AREA区域插值
    • INTER_CUBIC三次样条插值
    • INTER_LANCZOS4 lanczos插值

6.5 图像金字塔API函数

6.5.1向上采样:pyrUp()函数

void pyrUp(InputArray src, OutputArray dst,const Size & dstsize = Size(),int borderType = BODER_DEFAULT)
  • 第三个参数 默认值为Size(src.cols*2,src.rows*2)
    | d s t s i z e . w i d t h s r c . c o l s × 2 | ( d s t s i z e . w i d t h mod 2 ) | d s t s i z e . h e i g t h s r c . r o w s × 2 | ( d s t s i z e . h e i g h t mod 2 )

6.5.2 pyrDown()函数

void pyrDown(InputArray src, OutputArray dst,const Size & dstsize=Size(),int borderType = BORDER_DEFAULT)
  • 第三个参数:Size (src.cols/2,src,rows/2)满足的条件
    | d s t s i z e . w i d t h × 2 s r c . c o l s | 2 | d s t s i z e . h e i g h t × 2 s r c . r o w s | 2

6.6 综合示例

//头文件和命名空间

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace std;
using namespace cv;

//宏定义
#define WINDOW_NAME "【程序窗口】"

//全局变量

Mat g_srcImage, g_dstImage, g_tmpImage;

//main函数

int main()
{
    //载入图像
    g_srcImage = imread("1.jpg");
    if (!g_srcImage.data)
    {
        printf("读取srcImage错误~!\n");
        return false;
    }
    namedWindow(WINDOW_NAME, WINDOW_AUTOSIZE);
    imshow(WINDOW_NAME, g_srcImage);
    g_tmpImage = g_srcImage;
    g_dstImage = g_tmpImage;
    int key = 0;

    //轮询消息
    while (1)
    {
        key = waitKey(9); //读取键值到key变量中

        switch (key)
        {
        case 27: //按键ESC
            return 0;
            break;
        case 'q':
            return 0;
            break;
        //图像放大的相关方法
        case 'a':
            pyrUp(g_tmpImage, g_dstImage, Size(g_tmpImage.cols * 2, g_tmpImage.rows * 2));
            printf(">检测到按键[A]被按下,开始进行基于[pyrUp]函数的图像放大:图片尺寸×2\n");
            break;
        case 'w':
            resize(g_tmpImage, g_dstImage, Size(g_tmpImage.cols * 2, g_tmpImage.rows * 2));
            printf(">检测到按键[w]被按下,开始进行基于[resize]函数的图像放大:图片尺寸×2\n");
        case '1':
            resize(g_tmpImage, g_dstImage, Size(g_tmpImage.cols * 2, g_tmpImage.rows * 2));
            printf(">检测到按键[1]被按下,开始进行基于[resize]函数的图像放大:图片尺寸×2\n");
            break;
        case '3':
            pyrUp(g_tmpImage, g_dstImage, Size(g_tmpImage.cols * 2, g_tmpImage.rows * 2));
            printf(">检测到按键[3]被按下,开始进行基于[pyrUp]函数的图像放大:图片尺寸×2\n");
            break;
        //缩小操作
        case 'd':
            pyrDown(g_tmpImage, g_dstImage, Size(g_tmpImage.cols / 2, g_tmpImage.rows / 2));
            printf(">检测到按键[d]被按下,开始进行基于[pyrDown]函数的图像缩小:图片尺寸/2\n");
            break;
        case 's':
            resize(g_tmpImage, g_dstImage, Size(g_tmpImage.cols / 2, g_tmpImage.rows / 2));
            printf(">检测到按键[s]被按下,开始进行基于[resize]函数的图像缩小:图片尺寸/2\n");
            break;
        case '2':
            resize(g_tmpImage, g_dstImage, Size(g_tmpImage.cols / 2, g_tmpImage.rows / 2));
            printf(">检测到按键[2]被按下,开始进行基于[resize]函数的图像缩小:图片尺寸/2\n");
            break;
        case '4':
            pyrDown(g_tmpImage, g_dstImage, Size(g_tmpImage.cols / 2, g_tmpImage.rows / 2));
            printf(">检测到按键[4]被按下,开始进行基于[pyrDown]函数的图像缩小:图片尺寸/2\n");
            break;
        default:
            break;
        }
        //操作后显示图像
        imshow(WINDOW_NAME, g_dstImage);
        g_tmpImage = g_dstImage;
    }
    return 0;
}

QQ截图20180806165750.png

猜你喜欢

转载自blog.csdn.net/huayunhualuo/article/details/81501632