赞
踩
目录
6.1.4 算法实现
Github代码地址:GitHub - Qinong/OpenCV
Opencv提供了一种常用的图像分割算法Grabcut。Grabcut算法比较复杂,计算量也很大,但有很高的精确度。
cv::grabCut函数的用法非常简单,只需要在输入图像做上 “属于背景”或“属于前最” 的标记即可。根据这个局部标记,算法将计算出整幅图像的前景/背景分割线。
可以通过定义矩形指定输人图像局部前景/背景标签的。
- // 定义一个带边框的矩形
- // 矩形外部的像素会被标记为背景
- cv::Rect rectangle(100,120,650,350);
GrabCut算法的工作原理是:参考文章
接受输入图像与任一(1)的边界框,我们想段或(2)所涉及的图像中指定的对象的位置掩模即近似分割
反复执行以下步骤:
步骤1:通过高斯混合模型(GMM)估算前景和背景的颜色分布
步骤2:在像素标签上构造一个马尔可夫随机场(即,前景与背景)
步骤3:应用图割优化以进行最终细分
GrabCut是Graph Cut的改进版,是迭代的Graph Cut。OpenCV中的GrabCut算法是依据《"GrabCut" - Interactive Foreground Extraction using Iterated Graph Cuts》这篇文章来实现的。该算法利用了图像中的纹理(颜色)信息和边界(反差)信息,只要少量的用户交互操作即可得到比较好的分割结果。与Graph cut指定两个顶点不同,grabcut只需指定一个粗略的能将目标框住的边框就可以完成良好的分割。
虽然神经网络的分割已经占据了主流,但是再很多情况下并不需要如此大力气的训练,所以GrabCut也是可选项之一。
- void grabCut( InputArray img,
- InputOutputArray mask,
- Rect rect,
- InputOutputArray bgdModel,
- InputOutputArray fgdModel,
- int iterCount,
- int mode = GC_EVAL );
cv::GC_BGD == 0//表示是背景
cv::GC_FGD == 1//表示是前景
cv::GC_PR_BGD == 2//表示可能是背景
cv::GC_PR_FGD == 3//表示可能是前景
cv::GC_INIT_WITH_RECT//用矩阵初始化grabCut
cv::GC_INIT_WITH_MASK//用掩码初始化grabCut
cv::GC_EVAL//执行分割
cv::compare()主要用于两个图像之间进行逐像素的比较,并输出比较的结果。具体用法如下:
- bool cv::compare(cv::InputArray src1, // 输入数组1
- cv::InputArray src2, // 输入数组2
- cv::OutputArray dst, // 输出数组
- int cmpop // 比较操作子,见注释
cv::CMP_EQ src==src1
cv::CMP_GT src>src1
cv::CMP_GE src>=src1
cv::CMP_LT src<src1
cv::CMP_LE src<=src1
cv::CMP_NE src!=src1
- int main()
- {
- cv::Mat image= cv::imread("Ferrar_F8.png");
- if (!image.data)
- return 0;
- cv::namedWindow("Image");
- cv::imshow("Image",image);
-
- // 定义边框矩形
- cv::Rect rectangle(100,120,650,350);
- // 定义前景、背景和分割结果
- cv::Mat bgModel,fgModel,result;
-
- // GrabCut分割
- cv::grabCut(image,
- result,
- rectangle,
- bgModel,
- fgModel,
- 5,
- cv::GC_INIT_WITH_RECT); // use rectangle
-
- // 标记可能属于前景的区域
- cv::compare(result,cv::GC_PR_FGD,result,cv::CMP_EQ);
- // or:
- // result= result&1;
-
- // 创建前景图像
- cv::Mat foreground(image.size(), CV_8UC3, cv::Scalar(255, 255, 255));
- image.copyTo(foreground,result); // 复制前景图像
-
- // 在原图像绘制矩形区域
- cv::rectangle(image, rectangle, cv::Scalar(200,0,200),4);
- cv::namedWindow("Rectangle");
- cv::imshow("Rectangle",image);
- cv::namedWindow("Foreground");
- cv::imshow("Foreground",foreground);
-
- cv::waitKey();
- return 0;
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。