Python OpenCV 交互式前景提取 自动抠图

这是需要抠图的原图像,文件名为 “messi5.jpg”

 使用矩形方式处理:

# -*- coding: utf-8 -*-

import numpy as np
import cv2
from matplotlib import pyplot as plt
img = cv2.imread('messi5.jpg')
# 返回一个和图片等尺寸、且全为0的矩阵
mask = np.zeros(img.shape[:2],np.uint8)

# 返回1*65、且全为0的矩阵
# grabCut 算法用到,无需关心
bgdModel = np.zeros((1,65),np.float64)
fgdModel = np.zeros((1,65),np.float64)

# 前景在矩形框以内
rect = (64,67,467,355)
# 函数的返回值是更新的 mask, bgdModel, fgdModel
# https://blog.csdn.net/github_39611196/article/details/81143026
# mask 掩码图像,用于确定哪些可能是前景/背景
# rect 前景矩形,格式为 (x1,y1,x2,y2)
# 5 算法迭代次数
# cv2.GC_INIT_WITH_?? 前景提取模式是矩形形式还是掩码的形式
cv2.grabCut(img,mask,rect,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_RECT)

# 根据是否条件满足,返回元素为0/1的数组
mask2 = np.where((mask==2)|(mask==0),0,1).astype('uint8')
# np.newaxis 增加一个维度,
# 将二维2*3的矩阵 [[0 0 0] [0 0 0]] 变成
# 三维2*3*1的矩阵 [ [ [0] [0] [0] ] [ [0] [0] [0] ] ]
# print(mask2)
# print('\nwaxis\n',mask2[:,:,np.newaxis].shape)
# 数组相乘,得到每个元素的乘积
img = img*mask2[:,:,np.newaxis]

plt.imshow(img),plt.colorbar(),plt.show()

使用矩形模式 图像处理结果:

使用掩模方式处理:

打开网址 :https://www.tuyitu.com/photoshop/

将原图像上传,新建图层,绘制前景-背景掩模图像:

绘制方式为:一定是前景-白色;一定是背景-黑色;可能是背景-灰色(144色值)

保存掩模图层,命名为 “newmask.png” 

 执行下列程序:

 

# -*- coding: utf-8 -*-

import numpy as np
import cv2
from matplotlib import pyplot as plt
img = cv2.imread('messi5.jpg')
# 返回一个和图片等尺寸、且全为0的矩阵
mask = np.zeros(img.shape[:2],np.uint8)

# 返回1*65、且全为0的矩阵

bgdModel = np.zeros((1,65),np.float64)
fgdModel = np.zeros((1,65),np.float64)
rect = (64,67,467,355)
# newmask is the mask image I manually labelled
newmask = cv2.imread('newmask.png',0)
# whereever it is marked white (sure foreground), change mask=1
# whereever it is marked black (sure background), change mask=0
# 黑色一定是背景
mask[newmask == 0] = 0
# 白色一定是前景
mask[newmask == 255] = 1
# 灰色可能是背景
mask[newmask == 145] = 2

# 打印看看灰色色值
print(newmask[:,100])

# 注意 newmask 一定是按要求的图层保存,否则函数会错误
# 建议使用Photoshop或在线PS工具:https://www.tuyitu.com/photoshop/
# 函数的返回值是更新的 mask, bgdModel, fgdModel
# mask 掩码图像,用于确定哪些可能是前景/背景
# None 前景矩形,未用到
# 5 算法迭代次数
# GC_INIT_WITH_MASK 掩码的形式提取
mask, bgdModel, fgdModel = cv2.grabCut(img,mask,None,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_MASK)
mask = np.where((mask==2)|(mask==0),0,1).astype('uint8')
img = img*mask[:,:,np.newaxis]
plt.imshow(img),plt.colorbar(),plt.show()

处理图像结果:

直接使用掩模方式,只需在图像中画上几笔,就可以将前景人物完美提取出来,可见 grabCut 函数非常强大。

参考资料:OpenCV官方教程中文版(For Python).pdf

 

 

 

 

 

 

 

 

 

 

 

 

  • 6
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Python中的OpenCV库是一个广泛使用的计算机视觉库,提供了许多图像处理和分析的功能。其中包括轮廓提取抠图的功能。 在OpenCV中,可以使用函数`findContours()`来提取图像中的轮廓。该函数接受一个二值化图像作为输入,并返回一个包含所有轮廓点的列表。具体步骤如下: 1. 将图像进行二值化处理,使得背景为黑色(像素值为0),感兴趣的对象为白色(像素值为255)。 2. 使用`findContours()`函数提取轮廓。该函数会修改输入图像,所以需要首先对输入图像进行备份。 3. `findContours()`函数返回两个值:轮廓点的列表和层级信息。我们只需要轮廓点的列表,可以使用索引0来获取。 4. 可以通过绘制轮廓来查看或显示轮廓,使用`drawContours()`函数可以实现该功能。 抠图是将感兴趣的对象从图像中分离出来形成一个新的图像。可以使用OpenCV中的函数`bitwise_and()`来实现抠图。具体步骤如下: 1. 选择一个感兴趣的对象,并使用函数`findContours()`提取其轮廓。 2. 创建一个与原图像尺寸相同的空白图像(全黑)作为抠图结果。 3. 使用函数`drawContours()`将感兴趣的对象轮廓绘制到空白图像上。 4. 使用`bitwise_and()`函数将原图像和抠图结果进行按位与操作,将背景部分变为黑色。可以使用反色操作将背景变为白色。 5. 得到的结果即为抠图后的图像。 总而言之,Python中的OpenCV库提供了丰富的图像处理功能,使用其提供的函数可以轻松实现图像的轮廓提取抠图操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值