【OpenCV】Meanshift图像分割

OpenCV中自带有基于meanshift的分割方法pyrMeanShiftFiltering()。由函数名pyrMeanShiftFiltering可知,这里是将meanshift算法和图像金字塔相结合用来分割的。

void PyrMeanShiftFiltering( const CvArr* srcarr,//输入图像 CvArr* dstarr,//输出图像 doublesp,//颜色域半径 double sr,//空间域半径 int max_level,//金字塔最大层数 CvTermCriteria termcrit )//迭代终止条件

/******************************** image输入三通道8bit彩色图像,同时作为输出。 mask是掩模图像,它的大小是输入图像的长宽左右各加1个像素, mask一方面作为输入的掩模图像,另一方面也会在填充的过程中不断被更新。 floodFill漫水填充的过程并不会填充mask上灰度值不为0的像素点, 所以可以使用一个图像边缘检测的输出作为mask, 这样填充就不会填充或越过边缘轮廓。 mask在填充的过程中被更新的过程是这样的: 每当一个原始图上一个点位(x,y)被填充之后, 该点位置对应的mask上的点(x+1,y+1)的灰度值随机被设置为1(原本该点的灰度值为0), 代表该点已经被填充处理过。 seedPoint是漫水填充的起始种子点。 newVal被充填的色彩值。 rect可选的参数,用于设置floodFill函数将要重绘区域的最小矩形区域; loDiff upDiff用于定义跟种子点相比色彩的下限值和上限值, 介于种子点减去loDiff和种子点加上upDiff的 值会被填充为跟种子点同样的颜色。 第八个参数,定义漫水填充的模式,用于连通性、扩展方向等的定义。 */ int cv::floodFill(InputOutputArrayimage, InputOutputArraymask, PointseedPoint, ScalarnewVal, Rect *rect = 0, ScalarloDiff = Scalar(), ScalarupDiff = Scalar(), intflags = 4 )

效果图:
原图
【OpenCV】Meanshift图像分割
文章图片

meanshift分割
【OpenCV】Meanshift图像分割
文章图片

漫水填充后
【OpenCV】Meanshift图像分割
文章图片


步骤:
(1) 读入图像并显示
【【OpenCV】Meanshift图像分割】【OpenCV】Meanshift图像分割
文章图片

(2) 设置参数并进行分割
【OpenCV】Meanshift图像分割
文章图片

(3) 设置掩模进行漫水填充
【OpenCV】Meanshift图像分割
文章图片

程序:
//meanshift程序 #include "opencv2/highgui/highgui.hpp" #include "opencv2/core/core.hpp" #include "opencv2/imgproc/imgproc.hpp"using namespace cv; using namespace std; int main(int argc, char** argv) { Mat src_img = imread("2.jpg"); //读入图像,RGB三通道 imshow("src 1210", src_img); Mat dst_img; //分割后图像 int spatialRad = 50; //空间窗口大小 int colorRad = 50; //色彩窗口大小 int maxPyrLevel = 2; //金字塔层数 pyrMeanShiftFiltering(src_img, dst_img, spatialRad, colorRad, maxPyrLevel); //色彩聚类平滑滤波 imshow("dst 1210", dst_img); RNG rng = theRNG(); Mat mask(dst_img.rows + 2, dst_img.cols + 2, CV_8UC1, Scalar::all(0)); //掩模 for (int y = 0; y < dst_img.rows; y++) { for (int x = 0; x < dst_img.cols; x++) { if (mask.at(y + 1, x + 1) == 0)//非0处即为1,表示已经经过填充,不再处理 { Scalar newVal(rng(256), rng(256), rng(256)); floodFill(dst_img, mask, Point(x, y), newVal, 0, Scalar::all(5), Scalar::all(5)); //执行漫水填充 } } } imshow("漫水填充", dst_img); waitKey(); return 0; }

    推荐阅读