opencv用金字塔cvPyrSegmentation实现图像分割

PyrSegmentation:用金字塔实现图像分割,图像分割需要先建立一个图像金字塔,然后在Gi的像素和Gi+1的像素直接依照对应关系,建立起"父-子"关系,通过这种方式,快速初始分割可以先在金字塔高层的低分辨率图像上完成,然后逐层对分割加以优化。

要从金字塔第i层生成第i+1层(我们表示第i+1层为G+i),我们先要要高斯核对Gi进行卷积,然后删除所有偶数行和偶数列。当然,新得到的图像面积会变为源图像的四分之一。按上述过程对输入图像G0循环执行操作就可产生整个金字塔。


void cvPyrSegmentation( IplImage* src, IplImage* dst,
CvMemStorage* storage, CvSeq** comp,
int level, double threshold1, double threshold2 );


参数解析:

src :输入图像. 

dst :输出图像. 

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(c1,c2)=|c1-c2|. 
如果输入图像有单个通道(红、绿、兰),那幺 
p(c1,c2)=0,3·(c1r-c2r)+0,59·(c1g-c2g)+0,11·(c1b-c2b) . 

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


代码:

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

void  doPyrSegmentation( IplImage * src ,IplImage * dst)
{
//这里要注意:输入的图像必须是偶数行和列,否则输入不成功!!!
assert(src->width%2 == 0 && src->height%2 == 0);

CvMemStorage * stoage = cvCreateMemStorage(0);
CvSeq* comp=NULL;

int level = 2 ;   //进行n层采样
double threshold1 = 150 ;
double threshold2 = 30 ;
cvPyrSegmentation(src,dst, stoage,&comp,level, threshold1,threshold2) ;
};

int main(int argc,char ** argv)
{
IplImage * src = cvLoadImage("Li4.jpg");
IplImage * dst=cvCreateImage(cvGetSize(src), src->depth,src->nChannels);


doPyrSegmentation(src,dst);
cvNamedWindow("src") ;
cvNamedWindow("dst") ;
cvShowImage("src",src);
cvShowImage("dst",dst);
cvSaveImage("src.jpg",src);
cvSaveImage("dst.jpg",dst);
cvWaitKey(0) ;
cvDestroyAllWindows();
return 0;
}

效果:

opencv用金字塔cvPyrSegmentation实现图像分割_第1张图片     opencv用金字塔cvPyrSegmentation实现图像分割_第2张图片

以上照片仅仅是出于个人对偶像的敬仰。不经允许,不得用作商业用途。





你可能感兴趣的:(opencv,图像处理,模式识别)