pyrMeanShiftFiltering函数
对图像进行:均值偏移滤波
调用格式:
void cvPyrMeanShiftFiltering( const CvArr* src, CvArr* dst, double sp, double sr, int max_level=1, CvTermCriteria termcrit=cvTermCriteria(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS,5,1));
达到将图像与背景分离的目的。 简单来说,基于Mean Shift的图像分割过程就是首先利用Mean Shift算法对图像中的像素进行聚类,
即把收敛到同一点的起始点归为一类,然后把这一类的标号赋给这些起始点,同时把包含像素点太少的类去掉。
然后,采用阈值化分割的方法对图像进行二值化处理 基于Mean Shift的图像分割算法将图像中灰度值相近的像素点聚类为一个灰度级,
因此,经过Mean Shift算法分割后的图像中的灰度级较该算法处理之前有所减少。
opencv代码:
// meanshift_segmentation.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <iostream> using namespace cv; using namespace std; Mat src,dst; int spatialRad=10,colorRad=10,maxPryLevel=1; //const Scalar& colorDiff=Scalar::all(1); void meanshift_seg(int,void *) { //调用meanshift图像金字塔进行分割 pyrMeanShiftFiltering(src,dst,spatialRad,colorRad,maxPryLevel); RNG rng=theRNG(); Mat mask(dst.rows+2,dst.cols+2,CV_8UC1,Scalar::all(0)); for(int i=0;i<dst.rows;i++) //opencv图像等矩阵也是基于0索引的 for(int j=0;j<dst.cols;j++) if(mask.at<uchar>(i+1,j+1)==0) { Scalar newcolor(rng(256),rng(256),rng(256)); floodFill(dst,mask,Point(i,j),newcolor,0,Scalar::all(1),Scalar::all(1)); // floodFill(dst,mask,Point(i,j),newcolor,0,colorDiff,colorDiff); } imshow("dst",dst); } int main(int argc, uchar* argv[]) { namedWindow("src",WINDOW_AUTOSIZE); namedWindow("dst",WINDOW_AUTOSIZE); src=imread("stuff.jpg"); CV_Assert(!src.empty()); spatialRad=10; colorRad=10; maxPryLevel=1; //虽然createTrackbar函数的参数onChange函数要求其2个参数形式为onChange(int,void*) //但是这里是系统响应函数,在使用createTrackbar函数时,其调用的函数可以不用写参数,甚至 //括号都不用写,但是其调用函数的实现过程中还是需要满足(int,void*)2个参数类型 createTrackbar("spatialRad","dst",&spatialRad,80,meanshift_seg); createTrackbar("colorRad","dst",&colorRad,60,meanshift_seg); createTrackbar("maxPryLevel","dst",&maxPryLevel,5,meanshift_seg); // meanshift_seg(0,0); imshow("src",src); /*char c=(char)waitKey(); if(27==c) return 0;*/ imshow("dst",src); waitKey();//无限等待用户交互响应 // while(1);//这里不能用while(1)的原因是需要等待用户的交互,而while(1)没有该功能。虽然2者都有无限等待的作用。 return 0; }