在OpenCV中,实现了grabcut分割算法,该算法可以方便的分割出前景图像,操作简单,而且分割的效果很好。算法的原理参见papaer:“GrabCut” — Interactive Foreground Extraction using Iterated Graph Cuts

比如下面的一副图,我们只要选定一个四边形框,把框中的图像作为grabcut的一个输入参数,表示该框中的像素可能属于前景,但框外的部分一定属于背景。

然后调用grabcut函数,就可以分割出城堡来。具体代码如下:

// 打开另一幅图像cv::Mat image= cv::imread("../tower.jpg");if (!image.data)    {    cout<<"不能打开图像!"<<endl;return 0;     }

// 矩形外的像素是背景 cv::Rect rectangle(50,70,image.cols-150,image.rows-180);

cv::Mat result;//两个临时矩阵变量,作为算法的中间变量使用,不用carecv::Mat bgModel,fgModel; double tt = cv::getTickCount();// GrabCut 分段cv::grabCut(image,    //输入图像    result,   //分段结果    rectangle,// 包含前景的矩形     bgModel,fgModel, // 前景、背景    1,        // 迭代次数    cv::GC_INIT_WITH_RECT); // 用矩形tt = cv::getTickCount() - tt;printf("算法执行执行时间:%g ms\n", tt/cv::getTickFrequency()*1000);// 得到可能是前景的像素//比较函数保留值为GC_PR_FGD的像素cv::compare(result,cv::GC_PR_FGD,result,cv::CMP_EQ);// 产生输出图像cv::Mat foreground(image.size(),CV_8UC3,cv::Scalar(255,255,255));//背景值为 GC_BGD=0,作为掩码image.copyTo(foreground,result); 

grabCut函数的第一个参数为我们要处理的图像,本程序中就是image,图像的类型必须为:CV_8UC3

第二个参数是mask图像,它的大小和image一样,但是它的格式为CV_8UC1,只能是单通道的,grabcut算法的结果就保存在该图像中。

前面的代码中,我们并没有对mask图像(result)进行初始化设置,因为第6个参数为cv::GC_INIT_WITH_RECT,它表示算法会根据rectangle的范围,来生成一个初始化的mask图像。

cv::grabCut(image,    //输入图像
    result,   //分段结果
    rectangle, // 包含前景的矩形
    bgModel,fgModel, // 前景、背景
    1,        // 迭代次数
    cv::GC_INIT_WITH_RECT); // 用矩形

mask图像的值只能为下面下面4个值(PR,probably表示可能的):

GC_BGD    = 0,  //背景

GC_FGD    = 1,  //前景
GC_PR_BGD = 2,  //可能背景

GC_PR_FGD = 3   //可能前景

根据rectangle生成的mask图像规则为:四边形外面的部分一定是背景,所以在mask图中对应的像素值为GC_BGD,而四边形内部的的值可能为前景,所以对应的像素值为GC_PR_FGD。所以我们程序中使用mask图像应该如下图所示。

如果第7个参数为GC_INIT_WITH_MASK,这时第三个参数rectangle没有使用,我们必须在调用grabcut函数之前,手工设置mask图像(变量result),如果我们把result设置成上图所示的灰度图。那个调用函数

cv::grabCut(image1,    //输入图像
    result1,   //分段结果
    rectangle, // 包含前景的矩形
    bgModel,fgModel, // 前景、背景
    1,        // 迭代次数
    cv::GC_INIT_WITH_MASK); // 用矩形

可以得到同样的结果。
可以参考下面的代码:

cv::Mat result1= cv::Mat(image1.rows, image1.cols,CV_8UC1, cv::Scalar(cv::GC_BGD));//注意给子矩阵赋值的方法cv::Mat roi(result1, cv::Rect(50,70,result1.cols-150,result.rows-180));roi = cv::Scalar(cv::GC_PR_FGD);tt = cv::getTickCount();// GrabCut 分段cv::grabCut(image1,    //输入图像    result1,   //分段结果    rectangle,// 包含前景的矩形     bgModel,fgModel, // 前景、背景    1,        // 迭代次数    cv::GC_INIT_WITH_MASK); // 用矩形tt = cv::getTickCount() - tt;printf("算法执行执行时间:%g ms\n", tt/cv::getTickFrequency()*1000);

// 得到可能是前景的像素//比较函数保留值为GC_PR_FGD的像素cv::compare(result1,cv::GC_PR_FGD,result,cv::CMP_EQ);// 产生输出图像cv::Mat foreground1(image1.size(),CV_8UC3,cv::Scalar(255,255,255));//背景值为 GC_BGD=0,作为掩码image.copyTo(foreground1,result1); 

第3个参数是rectangle的大小位置,如果第7个参数为GC_INIT_WITH_MASK,则该参数没有作用。

第4,5个参数是两个算法在执行过程中使用临时矩阵变量,不用care它们的内容。

第6个参数是迭代次数,迭代越多,效果越好,但划时间也越长。

第7个参数是操作模式,通常情况下为GC_INIT_WITH_RECT和GC_INIT_WITH_MASK。

从上面的图中,我们可以看到,grabcut算法的效果很好,但是花的时间也很长,上面图像在我的笔记本上需要4.4秒。

程序源代码:工程FirstOpenCV13

OpenCV学习(20) grabcut分割算法相关推荐

  1. 基于深度学习的场景分割算法研究综述

    基于深度学习的场景分割算法研究综述 人工智能技术与咨询 来自<计算机研究与发展> ,作者张 蕊等 摘 要 场景分割的目标是判断场景图像中每个像素的类别.场景分割是计算机视觉领域重要的基本问 ...

  2. 基于FCN,U-Net的深度学习医学影像分割算法(细胞分割算法)以及传统算法分析

    本博文主要分析了基于传统计算机视觉的细胞分割算法和基于深度学习的细胞分割算法.主要针对医学影像分割算法.包括了FCN全卷积网络的细胞分割效果,U-Net细胞分割效果.查阅了采用深度学习分割医学影像的几 ...

  3. 基于迁移学习的语义分割算法分享与代码复现

    摘要:语义分割的数据集是比较大的,因此训练的时候需要非常强大的硬件支持. 本文分享自华为云社区<[云驻共创]基于迁移学习的语义分割算法分享>,原文作者:启明. 此篇文章是分享两篇基于迁移学 ...

  4. OpenCV学习(21) Grabcut算法详解

    grab cut算法是graph cut算法的改进.在理解grab cut算之前,应该学习一下graph cut算法的概念及实现方式. 我搜集了一些graph cut资料:http://yunpan. ...

  5. 【毕业设计】深度学习图像语义分割算法研究与实现 - python 机器视觉

    文章目录 0 前言 2 概念介绍 2.1 什么是图像语义分割 3 条件随机场的深度学习模型 3. 1 多尺度特征融合 4 语义分割开发过程 4.1 建立 4.2 下载CamVid数据集 4.3 加载C ...

  6. 【毕业设计】基于深度学习实现语义分割算法系统 - 机器视觉

    文章目录 0 前言 2 概念介绍 2.1 什么是图像语义分割 3 条件随机场的深度学习模型 3. 1 多尺度特征融合 4 语义分割开发过程 4.1 建立 4.2 下载CamVid数据集 4.3 加载C ...

  7. OpenCV4学习笔记(57)——基于GrabCut图像分割算法实现背景替换与背景虚化效果

    在上一篇笔记<OpenCV4学习笔记(56)>中,整理了关于在OpenCV中使用GrabCut图像分割算法的相关内容,那么本次笔记就以GrabCut算法为基础来实现对图像的背景替换和背景虚 ...

  8. opencv学习笔记—— opencv3 源码文件夹内容

    OpenCV 3 的源代码文件夹: 3rdparty/: 包含第三方库,如用视频解码用的 ffmpeg.jpg.png.tiff 等图片的解码库. apps/: 包含进行 Haar 分类器训练的工具, ...

  9. 无人驾驶 静态环境感知与分割算法(三)

    无人驾驶感知 一. 感知 1.感知外界: 目的:感知外界环境 静态环境:车道线.交通标识等 动态物体:运动物体的运动状态 传感器:单目(图片)/双目(深度图.稠密点云)/激光雷达(稀疏点云)/毫米波雷 ...

最新文章

  1. NumericUpDown
  2. 百度正在摆脱广告营收依赖!AI云增长64%成最大推动力
  3. java学习之文件基本操作
  4. Linux Centos6.5在哪里输入命令
  5. OPENCV图像轮廓检测
  6. java多态和泛型_Java面向对象(二) 接口、多态和泛型
  7. JS获取移动端系统信息(操作系统、操作系统版本、横竖屏状态、设备类型、网络状态、生成浏览器指纹)...
  8. 处理2D图像和纹理——创建2D菜单界面
  9. 新能源汽车累计补贴审核情况出炉:比亚迪、吉利两家独大
  10. Study Struts Commons Validator
  11. maven [INFO] No proxies configured [INFO] No proxy was configured, downloading directly
  12. 上位机控制PWM占空比
  13. Google账号登录后直接跳转百度首页,登陆不上
  14. 为找房方便,将sohu房产的rss 转成全文的!
  15. 逆向webpack打包,还原出原始文件。
  16. Joplin 软件转换中文
  17. docker中各ID之间的关系和计算(二)-layerID-diffID-chainID-cacheID的计算
  18. 天黑请闭眼 杀人游戏 规则 02
  19. Python新手-记一次股权穿透层级打分(森林实现)
  20. 增强低频和高频 matlab,实验名称高斯低频滤波及高频增强滤波.doc

热门文章

  1. linux进程下的线程数,Linux下查看进程线程数的方法
  2. c语言动态迁移mysql,flask-migrate动态迁移数据库
  3. 【sql】实现分页查询
  4. java中的基本用法
  5. Android-room的学习
  6. iOS 13 如何删除SceneDelegate
  7. iOS 高德导航按返回后报错 解决
  8. ScratchCardView:刮刮卡视图组件
  9. Linux (CentOS 7 )下搭建局域网SVN服务器+SVN权限配置
  10. consul安装配置使用