pyrMeanShiftFiltering函数

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));
src
输入的8-比特,3-信道图象.
dst
和源图象相同大小,相同格式的输出图象.
sp
The spatial window radius.
空间窗的半径
sr
The color window radius.
色彩窗的半径
max_level
Maximum level of the pyramid for the segmentation.
我们先借助Mean Shift算法的分割特性将灰度值相近的元素进行聚类,然后,在此基础上应用阈值分割算法,

达到将图像与背景分离的目的。 简单来说,基于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;
}



你可能感兴趣的:(pyrMeanShiftFiltering函数)