OpenCV——Grabcut算法
Grabcut 算法主要运用于计算机视觉中的前背景分割,立体视觉和抠图等。该算法利用了图像中的纹理(颜色)信息和边界(反差)信息,只要少量的用户交互操作即可得到比较好的分割结果.
1. Grabcut 的目标和背景的模型是RGB三通道的混合高斯模型GMM;
2. Grab Cut为一个不断进行分割估计和模型参数学习的交互迭代过程;
3. Grab Cut只需要提供背景区域的像素集就可以了。也就是说你只需要框选目标,那么在方框外的像素全部当成背景,这时候就可以对GMM进行建模和完成良好的分割了。即Grab Cut允许不完全的标注.
Grabcut 算法的基本步骤:
Grabcut的相关API:
void grabCut( InputArray img, //输入图像,必须是8位3通道图像,在处理过程中不会被修改InputOutputArray mask, //掩码图像,用来确定哪些区域是背景,前景,可能是背景, 可能是前景等//mask既可以作为输入也可以作为输出。作为输入时,mode要 选择GC_INIT_WITH_MASK (=1);
GCD_BGD (=0), 背景;GCD_FGD (=1),前景;GCD_PR_BGD (=2),可能是背景;GCD_PR_FGD(=3),可能是前景Rect rect, //包含前景的矩形,格式为(x, y, w, h)InputOutputArray bgdModel,//算法内部使用的数组,只需要创建大小为(1,65), 数据类型为np.float64的数组InputOutputArray fgdModel,//同上int iterCount, //算法迭代的次数int mode = GC_EVAL //用来指示grabCut函数进行什么操作// GC_INIT_WITH_RECT (=0),用矩形窗初始化GrabCut;// GC_INIT_WITH_MASK (=1),用掩码图像初始化GrabCut);
有关鼠标操作的两个函数:
void setMouseCallback( const string& winname, //图像视窗名称MouseCallback onMouse, //鼠标响应函数,监视到鼠标操作后调用并处理相 应动作void* userdata = 0 //鼠标响应处理函数的ID,识别号);
void OnMouseAction( int event, // 代表了鼠标的各种操作int x, // 代表鼠标位于窗口的(x,y)坐标位置,即Point(x,y)int y, int flags, // 代表鼠标的拖拽事件,以及键盘鼠标联合事件void *ustc // 标识了所响应的事件函数);
int event:#define CV_EVENT_MOUSEMOVE 0 //滑动
#define CV_EVENT_LBUTTONDOWN 1 //左键点击
#define CV_EVENT_RBUTTONDOWN 2 //右键点击
#define CV_EVENT_MBUTTONDOWN 3 //中键点击
#define CV_EVENT_LBUTTONUP 4 //左键放开
#define CV_EVENT_RBUTTONUP 5 //右键放开
#define CV_EVENT_MBUTTONUP 6 //中键放开
#define CV_EVENT_LBUTTONDBLCLK 7 //左键双击
#define CV_EVENT_RBUTTONDBLCLK 8 //右键双击
#define CV_EVENT_MBUTTONDBLCLK 9 //中键双击
int flags:#define CV_EVENT_FLAG_LBUTTON 1 //左鍵拖曳
#define CV_EVENT_FLAG_RBUTTON 2 //右鍵拖曳
#define CV_EVENT_FLAG_MBUTTON 4 //中鍵拖曳
#define CV_EVENT_FLAG_CTRLKEY 8 //(8~15)按Ctrl不放事件
#define CV_EVENT_FLAG_SHIFTKEY 16 //(16~31)按Shift不放事件
#define CV_EVENT_FLAG_ALTKEY 32 //(32~39)按Alt不放事件
Grabcut 算法的代码示例:
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\imgproc\imgproc.hpp>
#include<iostream>
#include <opencv2\opencv.hpp>
#include <math.h>
using namespace cv;
using namespace std;//grabcut算法
bool setMouse = false; //判断鼠标左键的状态(up / down)
bool init;
Point pt;
Rect rect;
Mat srcImg, mask, bgModel, fgModel;
int numRun = 0;
void onMouse(int, int, int, int, void*);
void runGrabCut();
void showImage();
int main()
{srcImg = imread("tahiti.jpg");if (srcImg.empty()){printf("could not load image...\n");return -1;}imshow("源图像", srcImg);mask.create(srcImg.size(), CV_8U);setMouseCallback("源图像", onMouse, 0);while (1){char c = (char)waitKey(0);if (c == ' ') {//选中矩形框后,按空格键执行grabcut分割runGrabCut();numRun++;showImage();printf("current iteative times : %d\n", numRun);}if ((int)c == 27) {break;}}return 0;
}void showImage()
{Mat result, binmask;binmask = mask & 1; //进一步掩膜if (init) //进一步抠出无效区域。鼠标按下,init变为false{srcImg.copyTo(result, binmask);}else{result = srcImg.clone();}rectangle(result, rect, Scalar(0, 0, 255), 2, 8);imshow("源图像", result);
}void onMouse(int events, int x, int y, int flag, void *)
{if (x < 0 || y < 0 || x > srcImg.cols || y > srcImg.rows) //无效区域return;if (events == EVENT_LBUTTONDOWN){setMouse = true;pt.x = x;pt.y = y;init = false;}else if (events == EVENT_MOUSEMOVE)//鼠标只要动,就执行一次{if (setMouse == true) //鼠标左键按住,滑动{Point pt1;pt1.x = x;pt1.y = y;rect = Rect(pt, pt1);//定义矩形区域showImage();mask.setTo(Scalar::all(GC_BGD));//背景mask(rect).setTo(Scalar(GC_PR_FGD));//前景 //对rect内部设置为可能的前景,外部设置为背景}}else if (events == EVENT_LBUTTONUP)setMouse = false; //鼠标左键抬起
}void runGrabCut()
{if (init)//鼠标按下,init变为falsegrabCut(srcImg, mask, rect, bgModel, fgModel, 1);//第二次迭代,用mask初始化grabcutelse{grabCut(srcImg, mask, rect, bgModel, fgModel, 1, GC_INIT_WITH_RECT);//用矩形窗初始化GrabCutinit = true;}
}
OpenCV——Grabcut算法相关推荐
- OpenCV GrabCut算法前景分割和提取
目录 一.OpenCv Grabcut算法:前景提取与分割(Foreground segmentation and extraction) (一)算法工作原理 (二)opencv函数cv2.grabC ...
- OpenCV GrabCut算法:前景分割和提取
目录 一.OpenCv Grabcut算法:前景提取与分割(Foreground segmentation and extraction) (一)算法工作原理 (二)opencv函数cv2.grabC ...
- OpenCV - GrabCut 算法抠图(Python实现)
原理 开始时用户需要用一个矩形将前景区域框住(前景区域应该完全被包括在矩形框内部).然后算法进行迭代式分割直达达到最好结果. 函数 mask, bgdModel, fgdModel = cv2.gra ...
- OpenCV使用 GrabCut 算法进行交互式前景提取
OpenCV使用 GrabCut 算法进行交互式前景提取 1. 效果图 2. 源码 参考 这篇博客将介绍如何使用Python,OpenCV中的GrabCut 算法来提取图像中的前景,并为此创建一个交互 ...
- OpenCV图像分割Grabcut算法
前言 1.OpenCV图像分割Grabcut算法主要功能是分割和抠图,就是把框着的目标抠出来,比如要分割出一个证件照的人的图像,只需要在目标外面画一个框,把目标框住,它就可以完成良好的分割. 2.算法 ...
- python opencv 利用 GrabCut 算法(opencv已经实现)从图像中分离出前景
# 利用GrabCut算法从图像中分离出前景 import numpy as np import cv2 as cv from matplotlib import pyplot as pltimg = ...
- 分水岭算法java,OpenCV 学习笔记 04 深度估计与分割——GrabCut算法与分水岭算法...
1 使用普通摄像头进行深度估计 1.1 深度估计原理 这里会用到几何学中的极几何(Epipolar Geometry),它属于立体视觉(stereo vision)几何学,立体视觉是计算机视觉的一个分 ...
- OpenCV实战——基于GrabCut算法的图像分割
OpenCV实战--基于GrabCut算法的图像分割 1. GrabCut 算法 2. 图像分割实战 3. 完整代码 相关链接 1. GrabCut 算法 在 OpenCV 策略设计模式一节中,我们已 ...
- OpenCV中的图像处理 —— 霍夫线 / 圈变换 + 图像分割(分水岭算法) + 交互式前景提取(GrabCut算法)
OpenCV中的图像处理 -- 霍夫线 / 圈变换 + 图像分割(分水岭算法) + 交互式前景提取(GrabCut算法)
最新文章
- ubuntu 在线安装mysql_Ubuntu下安装MySQL5.6
- struts.xml web.xml配置正常,访问action时出现404
- 腾讯员工:越来越多的新生都想要学计算机专业,好日子长不了
- 〖Linux〗多个JDK版本之间快速切换
- .Net定时弹出窗口(c#)
- Linux 知识点滴
- 一次系统调用开销到底有多大?
- anaconda tensorflow import PIL 报错的解决方法
- java 开源im_开源IM项目-InChat登录接口设计与实现(基于Netty)
- 综合计算机工时,计算机辅助工时定额制定与管理系统的研究与开发
- IsPostBack深入探讨
- html注册手机号验证,js正则表达式验证手机号码,用户名和邮箱
- 史上最全综述 | 3D目标检测算法汇总!(单目/双目/LiDAR/多模态/时序/半弱自监督)
- 中国汽车内饰皮革行业运行现状及经营战略建议报告2022年版
- 读取grib格式的小工具,在linux中的安装
- 电动车充电显示服务器无响应,纯电动汽车在充电时屏幕显示BMS无响应是怎么回事?...
- Vue 新手学习笔记:vue-element-admin 之按钮级权限管控
- Informatica元数据库解析
- 丑数(输出第n个丑数)
- 大话铁道部12306订票系统云架构
热门文章
- repost ACM生涯的感悟 个人建议 此文值得读三遍 可以少走很多弯路
- 写在最前面 - 每天5分钟玩转 OpenStack(1)
- JAVA_SE_Day05
- 算法实验一 递归与分治策略
- 软件测试招聘熟悉linux指,面试时候不知道 Linux 怎么回答?大师教给你46招!
- 【2021年度总结】长风破浪会有时,直挂云帆济沧海
- n9009+android+4.4.2,三星N9009电信双卡版刷机包 基于官方深度优化 精简冗余应用 极度纯净 操作流畅...
- druid分布式mysql_Druid 监控分布式解决方案
- [Win8]Windows8开发笔记(四):画刷介绍以及如何实现实现歌词动态变色显示
- Graphviz在python的用法(一):Graphviz安装和命令