金字塔分割算法由cvPrySegmentation所实现,该函数的使用很简单;需要注意的是图像的尺寸以及金字塔的层数,图像的宽度和高度必须能被2整除,能够被2整除的次数决定了金字塔的最大层数。
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(c1,c2)=|c1-c2|. 如果输入图像有单个通道(红、绿、兰),那么p(c1,c2)=0,3·(c1r-c2r)+0,59·(c1g-c2g)+0,11·(c1b-c2b) . 每一个簇可以有多个连接部件。图像 src 和 dst 应该是 8-比特、单通道 或 3-通道图像,且大小一样 。 |
//学习OpenCV中的介绍:
图像分割需要先建立一个图像金字塔,然后在Gi的像素和Gi+1的像素直接依照对应关系,建立起"父-子"关系,通过这种方式,快速初始分割可以先在金字塔高层的低分辨率图像上完成,然后逐层对分割加以优化;
在程序写好后,VS总是编译不通过,提示cvPyrSegmentation是未标示的函数。在网上找了好久,才找到解决办法。问题是缺少了legacy这个库文件。只要将这个库放进来即可。
具体是 项目属性-——VC++ Directories——Include Directories——加入编辑的路径(D:\OPENCV\opencv\build\include\opencv2\legacy),这是相对于本人的安装路径,主要是有\opencv\build\include\opencv2\legacy。加入后,即可正常使用函数了。
附:
在Ubuntu 10.04上安装openCV很方便:
#apt-get install opencv-doc libcv4 libhighgui4 libcvaux4 libcv-dev libcvaux-dev libhighgui-dev
同时最好顺便把ffmpeg的开发文件也装上。
然后编译《Learning OpenCV》一书的例子试一把,理论上把Makefile.txt改为Makefile然后make就行,但在我机子上有错误:
1. 'cvPyrSegmentation' undeclared identifier
定义在 /usr/local/include/opencv2/legacy/legacy.hpp中,默认没include进来,把该头文件包含进来即可。
2. 'cvCalcOpticalFlowHS' undeclared identifier
原因同上,也在legacy.hpp中。
3. cvRand,cvRandInit,cvRandSetRange等函数undeclred identifier
这些函数在 legacy/compat.hpp中,包含进来即可,然后链接时还要链接libopencv_legacy.so(-lopencv_legacy)。
4. 'CvDTreeParams::CvDTreeParams(...)' undefined reference
链接时加-lopencv_ml去链接libopencv_ml库。
void CdialogCVDlg::OnBnClickedBtnpyrsegment()
{
// TODO: Add your control notification handler code here
cvNamedWindow("src",CV_WINDOW_AUTOSIZE);
cvNamedWindow("dst",CV_WINDOW_AUTOSIZE);
img=cvLoadImage("D:\KK.jpg",-1);
cvShowImage("src",img);
img1=cvCreateImage(cvGetSize(img),img->depth,img->nChannels);
CvMemStorage * stoage = cvCreateMemStorage(0) ;
CvSeq* comp=NULL;
int level = 2 ; //进行n层采样
double threshold1 = 150 ;
double threshold2 = 30 ;
cvPyrSegmentation(img,img1,stoage,&comp,level,threshold1,threshold2);
cvShowImage("dst",img1);
}