OpenCV图像处理篇之采样金字塔

转载请注明出处:http://xiahouzuoxin.github.io/notes


图像金字塔

图像金字塔是通过将原始图像经过平滑、下采样所生成一系列具有不同分辨率的图像的集合。金字塔结构(Pyramid)适于多分辨率处理的一种图像存储数据结构。

最常用的生成图像金字塔的方法是采用高斯函数平滑图像,每次将分辨率降低为原来的一半,由此得到一个图像序列{ML,ML-1,……,M0},图像金字塔的存储量为N^2*(1+1/4+1/16+...)=(4*N^2)/3

如上图:最右边为原始图像,从右到左依次为使用高斯平滑1次、2次和3次后的图像,这些图像共同组成了图像金字塔。

图像金字塔这种结构在图像处理中有广泛的用途。最著名的特征匹配算子SIFT就是通过构造图像金字塔来完成的。有关图像金字塔在SIFT特征提取算法中的应用可参见Rachel Zhang的博文"SIFT特征提取分析"

程序分析

/*
 * FileName : pyramids.cpp
 * Author   : xiahouzuoxin @163.com
 * Version  : v1.0
 * Date     : Sat 20 Sep 2014 07:04:29 PM CST
 * Brief    :
 *
 * Copyright (C) MICL,USTB
 */
#include <iostream>
#include "cv.h"
#include "highgui.h"
#include "opencv2/imgproc/imgproc.hpp"

using namespace std;
using namespace cv;

const char *wn = "Pyramids Demo";

int main(int argc, char *argv[])
{
    if (argc < 2) {
        cout<<"Usage: ./pyramids [file name]"<<endl;
        return -1;
    }

    Mat src = imread(argv[1]);
    if (!src.data) {
        cout<<"Error: read image error."<<endl;
        return -1;
    }

    /* Size of input image must be 2^n */
    if ( src.cols & (src.cols-1) ) {  // src.cols > 0 first
        cout<<"Error: input image‘s column must be 2^n"<<endl;
        return -1;
    }
    if ( src.rows & (src.rows-1) ) {  // src.cols > 0 first
        cout<<"Error: input image‘s row must be 2^n"<<endl;
        return -1;
    }

    cout<<"User Guide:"<<endl;
    cout<<"---------------------"<<endl;
    cout<<"u   -> Zoom out"<<endl;
    cout<<"d   -> Zoom in"<<endl;
    cout<<"ESC -> Exit program"<<endl;

    namedWindow(wn, WINDOW_AUTOSIZE);
    imshow(wn, src);

    Mat cur = src;
    Mat dst = cur;

    int end_while = 0;
    while(!end_while) {
        char c;

        c = waitKey(10);
        switch (c) {
        case 27:   /* ESC */
            end_while = 1;
            break;
        case ‘u‘:
            pyrUp(cur, dst, Size(cur.cols*2, cur.rows*2));
            imshow(wn, dst);
            cur = dst;
            break;
        case ‘d‘:
            pyrDown(cur, dst, Size(cur.cols/2, cur.rows/2));
            imshow(wn, dst);
            cur = dst;
            break;
        default:
            break;
        }

    }
}
  1. 使用高斯图像金字塔进行降采样和插值的函数分别是pyrDownpyrUp,参数依次为原图像、采样结果图像、采样后的图像尺寸。
  2. 上述程序中的降采样操作因为都是按2为倍数进行的,因此要求输入图像的长宽都必须是2^n。if ( src.cols & (src.cols-1) )是用来判断原图像的列是否为2^n的语句。请仔细体会这种判断某个数是否是2^n的方法——x*(x-1)返回0表示x是2^n,否则不是。

结果显示

下面一系列图片展现的是先将原图像通过图像金字塔降采样(会存在数据丢失),再通过金字塔插值恢复图像过程中图像的变化过程。由于降采样过程中存在数据丢失,所以可以看到恢复到原图像大小后的图像比原图像模糊。

图注 原图像

图注 1次降采样后的图像

图注 2次降采样后的图像

图注 2次降采样后,再经过1次图像金字塔插值操作后的图像,大小与1次降采样后图像相同,但变得模糊

图注 2次降采样后,再经过2次图像金字塔插值操作后的图像,大小与原图相同,但变得模糊

时间: 2024-10-05 00:36:15

OpenCV图像处理篇之采样金字塔的相关文章

OpenCV图像处理篇之腐蚀与膨胀

转载请注明出处:http://xiahouzuoxin.github.io/notes 腐蚀与膨胀 腐蚀和膨胀是图像的形态学处理中最基本的操作,之后遇见的开操作和闭操作都是腐蚀和膨胀操作的结合运算.腐蚀和膨胀的应用非常广泛,而且效果还很好: 腐蚀可以分割(isolate)独立的图像元素,膨胀用于连接(join)相邻的元素,这也是腐蚀和膨胀后图像最直观的展现 去噪:通过低尺寸结构元素的腐蚀操作很容易去掉分散的椒盐噪声点 图像轮廓提取:腐蚀操作 图像分割 等等...(在文后给出一则简单实用膨胀操作提

OpenCV图像处理篇之图像平滑

图像平滑算法 图像平滑与图像模糊是同一概念,主要用于图像的去噪.平滑要使用滤波器,为不改变图像的相位信息,一般使用线性滤波器,其统一形式如下: 其中h称为滤波器的核函数,说白了就是权值.不同的核函数代表不同的滤波器,有不同的用途. 在图像处理中,常见的滤波器包括: 归一化滤波器(Homogeneous blur) 也是均值滤波器,用输出像素点核窗口内的像素均值代替输出点像素值. 高斯滤波器(Guassian blur) 是实际中最常用的滤波器,高斯滤波是将输入数组的每一个像素点与 高斯内核 卷积

OpenCV图像处理篇之Hough变换

图像空间到参数空间的转换 对于图像中共线的点集{(x0,y0), (x1,y1), ...}都经过直线y=kx+b,先在我们换一个说法,"斜率为k,截距为b的直线y=kx+b包含了所有在该直线上的点".一种强调的是图像中的点集,另一种强调的是直线的参数k和b,通过直线的点集去描述这条直线明显没有直接通过k,b两个参数去描述那样直接方便.而Hough变换就是将我们"点共线"的思维转化到参数空间{k,b}进行描述,图像空间中所有经过y=kx+b的点经过Hough变换后在

OpenCV图像处理篇之边缘检测算子

3种边缘检测算子 灰度或结构等信息的突变位置是图像的边缘,图像的边缘有幅度和方向属性,沿边缘方向像素变化缓慢,垂直边缘方向像素变化剧烈.因此,边缘上的变化能通过梯度计算出来. 一阶导数的梯度算子 对于二维的图像,梯度定义为一个向量, Gx对于x方向的梯度,Gy对应y方向的梯度,向量的幅值本来是 mag(f)?=?(Gx2?+?Gy2)1/2,为简化计算,一般用mag(f)=|Gx|+|Gy|近似,幅值同时包含了x而后y方向的梯度信息.梯度的方向为 α?=?arctan(Gx/Gy) . 由于图像

OpenCV图像处理篇之阈值操作函数

阈值操作类型 这5种阈值操作类型保留opencv tutorials中的英文名称,依次为: Threshold Binary:即二值化,将大于阈值的灰度值设为最大灰度值,小于阈值的值设为0. Threshold Binary, Inverted:将大于阈值的灰度值设为0,大于阈值的值设为最大灰度值. Truncate:将大于阈值的灰度值设为阈值,小于阈值的值保持不变. Threshold to Zero:将小于阈值的灰度值设为0,大于阈值的值保持不变. Threshold to Zero, In

OpenCV图像处理篇之边缘检測算子

3种边缘检測算子 灰度或结构等信息的突变位置是图像的边缘,图像的边缘有幅度和方向属性.沿边缘方向像素变化缓慢,垂直边缘方向像素变化剧烈.因此,边缘上的变化能通过梯度计算出来. 一阶导数的梯度算子 对于二维的图像.梯度定义为一个向量. Gx对于x方向的梯度,Gy相应y方向的梯度,向量的幅值本来是 mag(f)?=?(Gx2?+?Gy2)1/2,为简化计算,一般用mag(f)=|Gx|+|Gy|近似,幅值同一时候包括了x而后y方向的梯度信息.梯度的方向为 α?=?arctan(Gx/Gy) . 因为

《OpenCV图像处理编程实例》 目录

当当网购买地址:http://product.dangdang.com/23956649.html京东网购买地址:http://item.jd.com/11929148.html 内容简介 本书以 OpenCV 开源库为基础实现图像处理领域的很多通用算法,并结合当今图像处理领域前沿技术,对多个典型工程实例进行讲解及实现.全书内容覆盖面广,由基础到进阶,各个技术点均提供详细的代码实现,以帮助读者快速上手和深入学习.本书内容共三个部分,其中 1-2 章为基础篇, 3-6 章为进阶篇, 7-9 章为高

OpenCV &mdash;&mdash; 图像处理

使用图像结构中所定义的高层处理方法(图形和视觉范畴)来完成特定任务 平滑处理   cvSmooth 处理后图像与输入图像的大小相同(不用考虑边缘) 中值滤波  CV_MEDIAN 不支持 in place 操作 , 高斯滤波 CV_GAUSSIAN 支持 in place 操作(可以设置高斯核不对称,双边滤波--高斯平滑,水彩画处理,可用于图像分割) 图像形态学 膨胀 -- 把二值图像各像素连接成分的边界扩大一层,填充边缘或像素内部的孔:使灰度图像高亮区域逐渐增长 腐蚀 -- 把二值图像各像素连

OPENCV第一篇

了解过之前老版本OpenCV的童鞋们都应该清楚,对于OpenCV1.0时代的基于 C 语言接口而建的图像存储格式IplImage*,如果在退出前忘记release掉的话,就会照成内存泄露.而且用起来超级麻烦,我们往往在debug的时候,很大一部分时间在纠结手动释放内存的问题.虽然对于小型的程序来说手动管理内存不是问题,但一旦我们写的代码变得越来越庞大,我们便会开始越来越多地纠缠于内存管理的问题,而不是着力解决你的开发目标. 这,就有些舍本逐末的感觉了. 而浅墨在这篇文章开头想说,自从OpenCV