OpenCV入门(十一)-- 图像金字塔

图像金字塔

图像金字塔是一个图像的集合,集合中所有的图像源于同一个原始图像,而且是通过对原始图像连续采样获得,直到达到某个终止条件才停止采样。

图像金字塔有两种,高斯金字塔和拉普拉斯金字塔

高斯金子塔用来向下采样图像,拉普拉斯金字塔用来从金字塔底层图像中向上采样重建一个图像

PyrDown

图像的下采样

void cvPyrDown( const CvArr* src, CvArr* dst, int filter=CV_GAUSSIAN_5x5 );
src
输入图像.
dst
输出图像, 宽度和高度应是输入图像的一半 ,传入前必须已经完成初始化
filter
卷积滤波器的类型,目前仅支持 CV_GAUSSIAN_5x5

函数 cvPyrDown 使用 Gaussian 金字塔分解对输入图像向下采样。首先它对输入图像用指定滤波器进行卷积,然后通过拒绝偶数的行与列来下采样图像。


PyrUp

图像的上采样

void cvPyrUp( const CvArr* src, CvArr* dst, int filter=CV_GAUSSIAN_5x5 );
src
输入图像.
dst
输出图像, 宽度和高度应是输入图像的2倍
filter
卷积滤波器的类型,目前仅支持 CV_GAUSSIAN_5x5

函数 cvPyrUp 使用Gaussian 金字塔分解对输入图像向上采样。首先通过在图像中插入 0 偶数行和偶数列,然后对得到的图像用指定的滤波器进行高斯卷积,其中滤波器乘以4做插值。所以输出图像是输入图像的 4 倍大小。(hunnish: 原理不清楚,尚待探讨)


应用程序:

/*
* 图像金字塔
*/

#include "highgui.h"
#include "cv.h"

void doPyr(IplImage* img)
{
	IplImage* pyrd = cvCreateImage(
		cvSize(img->width/2, img->height/2),
		img->depth,
		img->nChannels
		);
	IplImage* pyru = cvCreateImage(
		cvSize(img->width*2, img->height*2),
		img->depth,
		img->nChannels
		);
	//图像金字塔
	cvPyrDown(img,pyrd,CV_GAUSSIAN_5x5);
	cvPyrUp(img,pyru,CV_GAUSSIAN_5x5);

	cvNamedWindow("PyrDown");
	cvNamedWindow("PyrUp");
	cvShowImage("PyrDown",pyrd);
	cvShowImage("PyrUp",pyru);

	cvReleaseImage(&pyrd);
	cvReleaseImage(&pyru);
	cvWaitKey(0);
	cvDestroyWindow("PyrDown");
	cvDestroyWindow("PyrUp");
}

输出结果:

原图




图像分割

图像金子塔的一个重要的应用就是图像分割

PyrSegmentation

用金字塔实现图像分割

void cvPyrSegmentation( IplImage* src, IplImage* dst,
                        CvMemStorage* storage, CvSeq** comp,
                        int level, double threshold1, double threshold2 );
src
输入图像.
dst
输出图像.
storage
Storage: 存储连通部件的序列结果
comp
分割部件的输出序列指针 components.
level
建立金字塔的最大层数
threshold1
建立连接的错误阈值
threshold2
分割簇的错误阈值

函数 cvPyrSegmentation 实现了金字塔方法的图像分割。金字塔建立到 level 指定的最大层数。如果 p(c(a),c(b))<threshold1,则在层 i 的象素点 a 和它的相邻层的父亲象素 b 之间的连接被建立起来,

定义好连接部件后,它们被加入到某些簇中。如果p(c(A),c(B))<threshold2,则任何两个分割 A 和 B 属于同一簇。

如果输入图像只有一个通道,那么

p(c¹,c²)=|c¹-c²|. 

如果输入图像有单个通道(红、绿、兰),那幺

p(c¹,c²)=0,3·(c¹r-c²r)+0,59·(c¹g-c²g)+0,11·(c¹b-c²b) . 

每一个簇可以有多个连接部件。 图像 src 和 dst 应该是 8-比特、单通道 或 3-通道图像,且大小一样



CvConnectedComp

连接部件

typedef struct CvConnectedComp
{
    double area; /* 连通域的面积 */
    float value; /* 分割域的灰度缩放值 */
    CvRect rect; /* 分割域的 ROI */
} CvConnectedComp;

程序代码:

/*
* 图像分割
*/

#include "highgui.h"
#include "cv.h"
#include<cxcore.h>
#include<opencv2/legacy/legacy.hpp>
#pragma comment(lib,"opencv_legacy249.lib")

void f(IplImage* img, IplImage* dst);

void doSegment(IplImage *img)
{
	IplImage* dst = cvCreateImage(
		cvGetSize(img),
		img->depth,
		img->nChannels
		);
	f(img, dst);
	cvNamedWindow("dst");
	cvShowImage("dst",dst);
	cvReleaseImage(&dst);
	cvWaitKey(0);
	cvDestroyWindow("dst");
}

void f(IplImage* img, IplImage* dst)
{
	CvMemStorage* storage = cvCreateMemStorage(0);
	CvSeq* comp = NULL;
	cvPyrSegmentation(img,dst,storage, &comp, 4, 200, 50);
	int n_comp = comp->total;
	for(int i = 1; i < n_comp; i++)
	{
		CvConnectedComp* cc = (CvConnectedComp*) cvGetSeqElem(comp,i);
	}
	cvReleaseMemStorage(&storage);
}

结果:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值