python-OpenCV 使用GrabCut来实现图片的前景与后景的分割
先上一个效果图:

使用Python3.7+OpenCV 3.x.
需要引入 numpy库。
在图上用鼠标左键和右键标记前景和后景即可.
如果需要重新标记图像,关闭程序重新运行.
以下是具体实现代码。
# -*- coding:utf-8 -*- '''
Python: 3.5.7
opencv 3.x 在图上用鼠标左键和右键标记前景和后景即可.
如果需要重新标记图像,关闭程序重新运行.
By Ynxf http://www.zhouws.com
''' import cv2
import numpy as np
import time img_src = '../test_images/3.jpg' drawing = False
mode = False class GrabCut:
def __init__(self, t_img):
self.img = t_img
self.img_raw = img.copy()
self.img_width = img.shape[0]
self.img_height = img.shape[1]
self.scale_size = 640 * self.img_width // self.img_height
if self.img_width > 640:
self.img = cv2.resize(self.img, (640, self.scale_size), interpolation=cv2.INTER_AREA)
self.img_show = self.img.copy()
self.img_gc = self.img.copy()
self.img_gc = cv2.GaussianBlur(self.img_gc, (3, 3), 0)
self.lb_up = False
self.rb_up = False
self.lb_down = False
self.rb_down = False
self.mask = np.full(self.img.shape[:2], 2, dtype=np.uint8)
self.firt_choose = True # 鼠标的回调函数
def mouse_event2(event, x, y, flags, param):
global drawing, last_point, start_point
# 左键按下:开始画图
if event == cv2.EVENT_LBUTTONDOWN:
drawing = True
last_point = (x, y)
start_point = last_point
param.lb_down = True
print('mouse lb down')
elif event == cv2.EVENT_RBUTTONDOWN:
drawing = True
last_point = (x, y)
start_point = last_point
param.rb_down = True
print('mouse rb down')
# 鼠标移动,画图
elif event == cv2.EVENT_MOUSEMOVE:
if drawing:
if param.lb_down:
cv2.line(param.img_show, last_point, (x,y), (0, 0, 255), 2, -1)
cv2.rectangle(param.mask, last_point, (x, y), 1, -1, 4)
else:
cv2.line(param.img_show, last_point, (x, y), (255, 0, 0), 2, -1)
cv2.rectangle(param.mask, last_point, (x, y), 0, -1, 4)
last_point = (x, y)
# 左键释放:结束画图
elif event == cv2.EVENT_LBUTTONUP:
drawing = False
param.lb_up = True
param.lb_down = False
cv2.line(param.img_show, last_point, (x,y), (0, 0, 255), 2, -1)
if param.firt_choose:
param.firt_choose = False
cv2.rectangle(param.mask, last_point, (x,y), 1, -1, 4)
print('mouse lb up')
elif event == cv2.EVENT_RBUTTONUP:
drawing = False
param.rb_up = True
param.rb_down = False
cv2.line(param.img_show, last_point, (x,y), (255, 0, 0), 2, -1)
if param.firt_choose:
param.firt_choose = False
param.mask = np.full(param.img.shape[:2], 3, dtype=np.uint8)
cv2.rectangle(param.mask, last_point, (x,y), 0, -1, 4)
print('mouse rb up') if __name__ == '__main__':
img = cv2.imread(img_src)
if img is None:
print('error: 图像为空')
g_img = GrabCut(img) cv2.namedWindow('image')
# 定义鼠标的回调函数
cv2.setMouseCallback('image', mouse_event2, g_img)
while (True):
cv2.imshow('image', g_img.img_show)
if g_img.lb_up or g_img.rb_up:
g_img.lb_up = False
g_img.rb_up = False
start = time.process_time()
bgdModel = np.zeros((1, 65), np.float64)
fgdModel = np.zeros((1, 65), np.float64) rect = (1, 1, g_img.img.shape[1], g_img.img.shape[0])
print(g_img.mask)
mask = g_img.mask
g_img.img_gc = g_img.img.copy()
cv2.grabCut(g_img.img_gc, mask, rect, bgdModel, fgdModel, 5, cv2.GC_INIT_WITH_MASK)
elapsed = (time.process_time() - start)
mask2 = np.where((mask == 2) | (mask == 0), 0, 1).astype('uint8') # 0和2做背景
g_img.img_gc = g_img.img_gc * mask2[:, :, np.newaxis] # 使用蒙板来获取前景区域
cv2.imshow('result', g_img.img_gc) print("Time used:", elapsed) # 按下ESC键退出
if cv2.waitKey(20) == 27:
break
来源: https://blog.zhouws.com/index/article/detial/id/35.html
python-OpenCV 使用GrabCut来实现图片的前景与后景的分割的更多相关文章
- Python opencv提取视频中的图片
作者:R语言和Python学堂链接:https://www.jianshu.com/p/e3c04d4fb5f3 这个函数就是本文要介绍的video2frames()函数,功能就是从视频中提取图片,名 ...
- python opencv图像识别(相同大小图片)
简介 由于项目需要对比两张相同图片的相似度,因此采用opencv将图片转为灰阶数组,然后对比相应的数组来取相似度,此方法只适用于大小相同的图片,较为局限 # -*- coding: utf-8 -*- ...
- python opencv show图片,debug技巧
debug的时候可以直接把图片画出来debug. imshow函数就是python opencv的展示图片的函数,第一个是你要起的图片名,第二个是图片本身.waitKey函数是用来展示图片多久的,默认 ...
- Python + opencv 实现图片文字的分割
实现步骤: 1.通过水平投影对图形进行水平分割,获取每一行的图像: 2.通过垂直投影对分割的每一行图像进行垂直分割,最终确定每一个字符的坐标位置,分割出每一个字符: 先简单介绍一下投影法:分别在水平和 ...
- Python OpenCV图片转视频 工具贴(三)
Python OpenCV图片转视频 粘贴即用,注意使用时最好把自己的文件按照数字顺序命名.按照引导输入操作. # 一键傻瓜式引导图片串成视频 # 注意使用前最好把文件命名为数字顺序格式 import ...
- RPi 2B python opencv camera demo example
/************************************************************************************** * RPi 2B pyt ...
- Python+OpenCV图像处理(一)
Python+OpenCV图像处理(一): 读取,写入和展示图片 调用摄像头拍照 调用摄像头录制视频 1. 读取.写入和展示图片 图像读入:cv2.imread() 使用函数cv2.imread() ...
- Python+OpenCV图像处理(一)——读取显示一张图片
先在此处先声明,后面学习python+opencv图像处理时均参考这位博主的博文https://blog.csdn.net/u011321546/article/category/7495016/2? ...
- python - opencv 的一些小技巧备忘
python - opencv 的一些小技巧备忘 使用python-opencv来处理图像时,可以像matlab一样,将一幅图像看成一个矩阵,进行矢量操作,以加快代码运行速度. 下面记录几个常用的操作 ...
随机推荐
- 03_Service的绑定
Start Service启动的Service,Application退出,Service也不会退出: Bind Service启动的Service,Application退出,Service就会退出 ...
- ④SpringCloud 实战:引入Hystrix组件,分布式系统容错
这是SpringCloud实战系列中第4篇文章,了解前面第两篇文章更有助于更好理解本文内容: ①SpringCloud 实战:引入Eureka组件,完善服务治理 ②SpringCloud 实战:引入F ...
- JZOJ2020年8月11日提高组T3 页
JZOJ2020年8月11日提高组T3 页 题目 Description 战神阿瑞斯听说2008年在中华大地上,将举行一届规模盛大的奥林匹克运动会,心中顿觉异常兴奋,他想让天马在广阔的天空上,举行一场 ...
- JZOJ2020年9月5日提高组反思
JZOJ2020年9月5日提高组反思 T1 考试的时候没有头绪,就打了个暴力,愉快的拿到了10分的\(impossible\) 正解是\(DP\),设\(f[i][j][k]\)表示地\(i\)种币值 ...
- PyQt(Python+Qt)学习随笔:树型部件QTreeWidget中的项编辑方法editTriggers、editItem和openPersistentEditor作用及对比分析
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 在树型部件QTreeWidget中,有三种方法触发进行项数据的编辑:editTriggers触发编辑 ...
- 爬虫模块-requests
title: python爬虫01 date: 2020-03-08 22:56:12 tags: 1.requests模块 requests模块的底层是urllib,但是比urllib更强大也更加简 ...
- Kubernetes-21:Apiserver等证书修改使用年限
Kubernetes证书使用年限修改方法 Kubernetes的apiservice.crt证书默认只有一年的使用期限,查看方法: cd /etc/kubernetes/pki [root@Cen ...
- python中的多线程和多进程
一.简单理解一下线程和进程 一个进程中可有多个线程,线程之间可共享内存,进程间却是相互独立的.打比方就是,进程是火车,线程是火车厢,车厢内人员可以流动(数据共享) 二.python中的多线程和多进程 ...
- 手把手教你写DI_1_DI框架有什么?
DI框架有什么? 在上一节:手把手教你写DI_0_DI是什么? 我们已经理解DI是什么 接下来我们就徒手撸一撸,玩个支持构造函数注入的DI出来 首先我们回顾一下 构造函数注入 的代码形式, 大概长这模 ...
- CRT, lucas及其扩展形式
CRT, lucas及其扩展形式 exgcd int exgcd(int a, int b, int &x, int &y) { if (b == 0) return a, x = 1 ...