OpenCV4图像处理-图像交互式分割-GrabCut

本文将实现一个与人(鼠标)交互从而分割背景的程序。

GrabCut

  • 1.理论介绍
  • 2. 鼠标交互
  • 3. GrabCut

1.理论介绍

用户指定前景的大体区域,剩下为背景区域,还可以明确指出某些地方为前景或者背景,GrabCut算法采用分段迭代的方法分析前景物体形成模型树,最后根据权重决定某个像素是前景还是背景。

算法:GrabCut(img, mask, rect, bgdModel, fgdModel, 5, //iteratormode)
img:要分割的图像
mask:生称的掩码(以原图像大小为基准),该算法会把mask分为4部分,像素点的值为0,1,2,3四种值吗,其中每种值代表不同的意思。
rect:用户指定的矩形区域,元组的形式(起始坐标x, y , width,height)
bgdModel:1行65列的0矩阵,元素类型为float64。
fgdModel:1行65列的0矩阵,元素类型为float64。
5:迭代次数iterator
mode:第一次找用RECT,以后迭代用MASK

在这里插入图片描述

在这里插入图片描述

2. 鼠标交互

下面是一个鼠标交互的程序,可以通过点击鼠标滑动鼠标在图像上作图。

不太清楚的读者可以参考下面博客:Opencv(图像处理)-基于Python-绘图功能

代码如下:

import cv2
import numpy as np'''
该api可以在图上作图
点击并滑动鼠标可以在图上画出矩形框
'''# 定义一个类来封装该方法
class MouseStich:startX = 0startY = 0rect_flag = Falsedef onmouse(self, event, x, y, flags, param):# print("onmouse")if event == cv2.EVENT_LBUTTONDOWN:self.rect_flag = Trueself.startX = xself.startY = y# print("LBUTTONDOWN")elif event == cv2.EVENT_LBUTTONUP:# print("LBUTTONUP")self.rect_flag = Falsecv2.rectangle(self.img,(self.startX, self.startY),(x, y),(0, 0, 255),3)elif event == cv2.EVENT_MOUSEMOVE:# print("MOUSEMOVE")# 每次都在新的图像上画if self.rect_flag == True:self.img = self.img2.copy()cv2.rectangle(self.img,(self.startX, self.startY),(x, y),(0, 255, 0),3)def run(self):print("run....")# 绑定鼠标事件的窗口cv2.namedWindow('input')cv2.setMouseCallback('input', self.onmouse)# 暂存一个img2self.img = cv2.imread('./image/lena.jpg')self. img2 = self.img.copy()# 读取图片,在该窗口显示while(1):# 展示原图,被画的图cv2.imshow('input', self.img)k = cv2.waitKey(100) & 0xffif k == ord('q'):breakMouseStich().run()

3. GrabCut

将GrabCut需要的参数构造好后,传进去,获得mask掩模,然后我们用np.where把像素值是1,3的位置改成255,目的是用bitwise_and函数提取出前景区域。

import cv2
import numpy as np'''
该api可以在图上作图
点击并滑动鼠标可以在图上画出矩形框
'''# 定义一个类来封装该方法
class MouseStich:startX = 0startY = 0rect_flag = Falserect = (0, 0, 0, 0)def onmouse(self, event, x, y, flags, param):# print("onmouse")if event == cv2.EVENT_LBUTTONDOWN:self.rect_flag = Trueself.startX = xself.startY = y# print("LBUTTONDOWN")elif event == cv2.EVENT_LBUTTONUP:# print("LBUTTONUP")self.rect_flag = Falsecv2.rectangle(self.img,(self.startX, self.startY),(x, y),(0, 0, 255),3)elif event == cv2.EVENT_MOUSEMOVE:# print("MOUSEMOVE")# 每次都在新的图像上画if self.rect_flag == True:# 每次都在新的图像上画moveself.img = self.img2.copy()cv2.rectangle(self.img,(self.startX, self.startY),(x, y),(0, 255, 0),3)# 构造矩形的信息self.rect = (min(self.startX, x), min(self.startY, y),abs(self.startX - x), abs(self.startY - y))def run(self):print("run....")# 绑定鼠标事件的窗口cv2.namedWindow('input')cv2.setMouseCallback('input', self.onmouse)self.img = cv2.imread('./image/lena.jpg')self. img2 = self.img.copy()# 定义一个与图片相同大小的掩码self.mask = np.zeros(self.img.shape[:2], dtype=np.uint8)self.output = np.zeros(self.img.shape, dtype=np.uint8)# 读取图片,在该窗口显示while(1):# 展示原图,被画的图cv2.imshow('input', self.img)cv2.imshow('output', self.output)k = cv2.waitKey(100) & 0xffif k == ord('q'):breakif k == ord('g'):bgdmodel = np.zeros((1, 65), np.float64)fgdmodel = np.zeros((1, 65), np.float64)cv2.grabCut(self.img2, self.mask, self.rect,bgdmodel, fgdmodel,1,cv2.GC_INIT_WITH_RECT)# 构造提取前景的淹没mask2 = np.where((self.mask==1)|(self.mask==3), 255, 0).astype('uint8')self.output = cv2.bitwise_and(self.img2, self.img2, mask=mask2)MouseStich().run()

展示效果:先使用鼠标画出区域,然后按’g’分割图片。

在这里插入图片描述

以上是关于GrabCut算法的实战内容,如有问题欢迎在评论区讨论。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/5695.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL主从复制与读写分离

文章目录 一.前言二.主从复制原理1.MySQL的复制类型2.MySQL主从复制的工作过程2.1 MysQL主从复制延迟原因2.2问题解决方法2.3 MySQL 有几种同步方式2.3.1 异步复制2.3.2 同步复制2.3.3 半同步复制2.3.4 增强半同步复制(lossless Semi-Sync Replication、无损复制&am…

消息队列 CKafka 跨洋数据同步性能优化

导语 本文主要介绍了 CKafka 在跨洋场景中遇到的一个地域间数据同步延时大的问题,跨地域延时问题比较典型,所以详细记录下来做个总结。 一. 背景 为了满足客户跨地域容灾、冷备的诉求,消息队列 CKafka 通过连接器功能,提供了跨…

进程控制学习笔记

文章目录 进程退出孤儿进程僵尸进程进程回收waitpid()函数 进程退出 子进程的退出需要父进程对其资源的释放,子进程只能对用户区的数据进行释放,无法完成对内核区的释放。 可以获取到。 两个退出的区别: 系统调用不会刷新缓冲区&#xff…

Kubernetes对象深入学习之四:对象属性编码实战

欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本文是《Kubernetes对象深入学习》系列的第四篇,前面咱们读源码和文档,从理论上学习了kubernetes的对象相关的知识&#xff…

python识别极验4滑块验证码实战

闲得无聊,趁着休息研究了一下极验4滑块验证码的安全性,是否有机器识别、自动化拖拽的可能性。首先看一下效果 如何识别验证码 1、下载图片 下载图片可以参考博客《采集极验4滑块验证码图片数据》 2、标记图片 3、标记滑动距离 实现代码 __author__ &…

【C++】C++11

文章目录 C111. 统一的列表初始化1.1 {}初始化 2. 声明2.1 auto2.2 decltype2.3 nullptr 3. 右值引用和移动语义3.1 左值引用和右值引用3.2 左值引用与右值引用比较3.3 右值引用使用的场景和意义3.4 完美转发 4. 可变参数模板5. lambda表达式5.1 函数对象与lambda表达式 6. 线程…

STM32入门之创建工程模板

1.STM32固件库的结构图如下。从图中可以看出,我们在配置STM32的固件库时需要配置用户层、CMSIS层的文件。配置库文件即正确的配置这些函数的文件。CMSIS(Cortex Microcontroller Software Interface Standard)是ARM公司提供的微控制器软件接口标准,所有使…

macos M1安装多个版本jdk

1、安装jdk 8 到 oracle 官网 https://www.oracle.com/java/technologies/javase/javase8u211-later-archive-downloads.html 找到 macOS x64 DMG Installer 后面的下载链接下载安装包 java的jdk 都安装在以下目录 ls /Library/Java/JavaVirtualMachines/jdk-1.8.jdk jdk-1…

Data Structure, Algorithm,and Applications in C++

在学习这本书进阶内容之前,我们可以跟着它的第一章部分再巩固和复习。本书由Sartaj Sahni撰写,由王立柱和刘志红翻译。全书通俗易懂,内容丰富,是巩固C内容的不二选择。希望本文对各位有所帮助。 目录 1.函数与参数 1.1.传值参数…

C++初探

目录 经典开头 — C的历史 作用域运算符 using的用法 命名空间 - namespace 命名空间的基本使用 特殊的命名空间 - 无名命名空间 全部展开和部分展开 std — C所有的标准库都在std命名空间内 省缺值 - 默认参数 占位参数 内联函数 - inline 函数重载 函数重载的用…

【Unity2D】相机移动以及设置相机边界

添加相机 添加相机时,首先需要在unity中添加 Cinemachine 包 第一次使用这个包时,需要在Package Manager中搜索并安装 安装Camera Mechine包后,添加2D Camera 设置跟随对象为Ruby (从Hierarchy中将Ruby拖动到Follow中&#xff0…

kafka 2.1.1 java的消费者客户端如何获取数据源码

KafkaConsumer 一、kakfa消费者暴露给业务系统获取数据的方法1 首先从缓冲区队列取数,没有数据则请求服务端来获取数据1.1循环从队列中取数,给到空或者已被提取的nextInLineRecords(1)当nextInLineRecords的数据被提取时,就把nextInLineRecor…

c函数学习

函数的概念 函数是c语言的功能单位,实现一个功能可以封装一个函数来实现。定义函数的时候一切以功能为目的,根据功能去定义函数的参数和返回值 函数的分类 从定义角度分类:库函数(c库实现的),自定义函数&…

一、大数据技术之Flume(简介)

第1章 Flume概述 1.1 Flume定义 Flume是Cloudera提供的一个高可用的,高可靠的,分布式的海量日志采集、聚合和传输的系统。Flume基于流式架构,灵活简单。 1.2 Flume基础架构 Flume组成架构如下图所示。 1.2.1 Agent Agent是一个JVM进程&…

微信小程序23__flex布局 相关的3种居中: 水平居中_垂直居中_水平垂直居中

3 种居中方式, 在页面布局中经常用到, 现作一记录。 第一种 水平居中 类似这样写法 display: flex; flex-direction: column; //垂直布局 align-items: center; // 水平居中 justify-content: space-a…

NLP实战8:图解 Transformer笔记

目录 1.Transformer宏观结构 2.Transformer结构细节 2.1输入 2.2编码部分 2.3解码部分 2.4多头注意力机制 2.5线性层和softmax 2.6 损失函数 3.参考代码 🍨 本文为[🔗365天深度学习训练营]内部限免文章(版权归 *K同学啊* 所有&#…

vue 路由守卫

全局路由守卫 beforeEach 路由跳转前触发to 代表 到那个页面去from 代表从哪个页面来next 表示放行 beforeResolve 表示 组件解析后触发的钩子 afterEach 表示路由跳转完成之后i触发的钩子 全局路由钩子执行顺序 beforeEach > beforeResolve>afterEach 局部路由…

在外远程NAS群晖Drive - 群晖Drive挂载电脑磁盘同步备份【无需公网IP】

文章目录 前言1.群晖Synology Drive套件的安装1.1 安装Synology Drive套件1.2 设置Synology Drive套件1.3 局域网内电脑测试和使用 2.使用cpolar远程访问内网Synology Drive2.1 Cpolar云端设置2.2 Cpolar本地设置2.3 测试和使用 3. 结语 前言 群晖作为专业的数据存储中心&…

【Hadoop 01】简介

目录 1 Hadoop 简介 2 下载并配置Hadoop 2.1 修改/etc/profile 2.2 修改hadoop-env.sh 2.3 修改core-site.xml 2.4 修改hdfs-site.xml 2.5 修改mapred-site.xml 2.6 修改yarn-site.xml 2.7 修改workers 2.8 修改start-dfs.sh、stop-dfs.sh 2.9 修改start-yarn.sh、s…

Elemui表单合并

原代码形式 <template><el-table:data"tableData"borderstyle"width: 100%"><el-table-columnprop"date"label"日期"width"180"></el-table-column><el-table-columnprop"name"label…