051-OpenCV GrabCut图像分割算法

话不多说,上代码,看结果。

import cv2           # 导入库
import numpy as np

'''  
    cv2.imread(filename,flags)
# filename为文件名,图片与.py文件在一个文件夹时输入文件名即可
# 不在一个文件夹时输入图片的路径和名字
# flags为图片的颜色类型,默认为1,灰度图像为0
'''
img = cv2.imread('89.jpg')

mask = np.zeros(img.shape[:2], np.uint8)

bgdModel = np.zeros((1, 65), np.float64)

fgdModel = np.zeros((1, 65), np.float64)

rect = (160, 160, 376, 498)

'''
    cv2.grabCut(img, mask, rect, bgdModel, fgdModel, iterCount, mode)
# img: 待分割原图像, 需为8位三通道彩色图像
# mask: 8位单通道掩码图像, 如果使用掩码进行初始化, 那么mask保存掩码信息, 
# 在执行分割的时候, 也可以将用户交互所设定的前景与背景保存到mask中,然后再传入grabCut函数, 
# 在处理结束之后,mask中会保存结果。Mask只能取4种可能的值:
# GC_BGD: 0 表示明确属于背景的像素  GC_FGD: 1 表示明确属于前景的像素
# GC_PR_BGD: 2 表示可能属于背景的像素   GC_PR_FGD: 3 表示可能属于前景的像素
# 如果没有手动标记GC_BGD或者GC_FGD, 那么结果只会有GC_PR_BGD或 GC_PR_FGD
# rect: 包含分割对象的矩形ROI, 矩形外部的像素为背景, 矩形内部的像素为前景,当参数mode=GC_INIT_WITH_RECT使用
# bgdModel: 背景模型(内部使用), 大小为 (1,65),数据类型为 np.float64 的数组
# fgdModel: 前景模型(内部使用 ), 大小为 (1,65),数据类型为 np.float64 的数组
# iterCount: 迭代次数, 必须大于0
# mode: 用于指示grabCut函数进行什么操作, 可选的值有:
# GC_INIT_WITH_RECT: 用矩形框初始化GrabCut
# GC_INIT_WITH_MASK: 用掩码图像初始化GrabCut
# GC_EVAL: 执行分割
'''
cv2.grabCut(img, mask, rect, bgdModel, fgdModel, 9, cv2.GC_INIT_WITH_RECT)


# mask2 = np.where((mask == 1) | (mask == 3), 1, 0).astype('uint8')  # 提取前景
mask2 = np.where((mask == 0) | (mask == 2), 1, 0).astype('uint8')  # 提取背景
img = img * mask2[:, :, np.newaxis]  # 改变数组维度与原图保持一致
'''
   cv2.imshow(winname,mat)
# winname为显示的窗口
# mat 需要显示的图像
'''
cv2.imshow('result', img)

'''
cv2.waitKey(delay)
#  delay为正数时,延时delay毫秒结束
#  想要用按下某个键时退出可用以下方法:
#  if(cv2.waitKey(0)  == ord('q')):
        exit(0)
#别的方法也行,不唯一
'''
if cv2.waitKey(0) & 0xFF == 27:
    exit(0)
'''
cv2.destroyWindow(winname)
#结束窗口,winname为窗口名
cv2.destroyAllWindows() 
#结束所有窗口
'''
cv2.destroyAllWindows()

结果如下图。
在这里插入图片描述

cv2.GC_INIT_WITH_MASK用法:

import cv2           # 导入库
import numpy as np

'''  
    cv2.imread(filename,flags)
# filename为文件名,图片与.py文件在一个文件夹时输入文件名即可
# 不在一个文件夹时输入图片的路径和名字
# flags为图片的颜色类型,默认为1,灰度图像为0
'''
img = cv2.imread('89.jpg')

mask = np.zeros(img.shape[:2], np.uint8)

bgdModel = np.zeros((1, 65), np.float64)

fgdModel = np.zeros((1, 65), np.float64)

rect = (0, 0, 0, 0)  # 次数rect参数对结果无影响

'''
    cv2.rectangle(img,pt1,pt2,color,thickness,lineType,shift)
# 画矩形
# img,被画矩形的图像  pt1、pt2矩形的左上角、右下角坐标
# color,直线的颜色,BGR颜色  thickness,线的宽度,-1的时候表示填充矩形
# lineType,有三种cv2.LINE_AA、cv2.LINE_4、cv2.LINE_8
# cv2.LINE_AA抗锯齿,这种类型的线看起来平滑点
# shift,坐标精确到小数点后第几位
'''
cv2.rectangle(mask, (160, 160), (376, 498), (3, 3, 3), -1, cv2.LINE_AA)  # cv2.GC_PR_FGD

'''
    cv2.grabCut(img, mask, rect, bgdModel, fgdModel, iterCount, mode)
# img: 待分割原图像, 需为8位三通道彩色图像
# mask: 8位单通道掩码图像, 如果使用掩码进行初始化, 那么mask保存掩码信息, 
# 在执行分割的时候, 也可以将用户交互所设定的前景与背景保存到mask中,然后再传入grabCut函数, 
# 在处理结束之后,mask中会保存结果。Mask只能取4种可能的值:
# GC_BGD: 0 表示明确属于背景的像素  GC_FGD: 1 表示明确属于前景的像素
# GC_PR_BGD: 2 表示可能属于背景的像素   GC_PR_FGD: 3 表示可能属于前景的像素
# 如果没有手动标记GC_BGD或者GC_FGD, 那么结果只会有GC_PR_BGD或 GC_PR_FGD
# rect: 包含分割对象的矩形ROI, 矩形外部的像素为背景, 矩形内部的像素为前景,当参数mode=GC_INIT_WITH_RECT使用
# bgdModel: 背景模型(内部使用), 大小为 (1,65),数据类型为 np.float64 的数组
# fgdModel: 前景模型(内部使用 ), 大小为 (1,65),数据类型为 np.float64 的数组
# iterCount: 迭代次数, 必须大于0
# mode: 用于指示grabCut函数进行什么操作, 可选的值有:
# GC_INIT_WITH_RECT: 用矩形框初始化GrabCut
# GC_INIT_WITH_MASK: 用掩码图像初始化GrabCut
# GC_EVAL: 执行分割
'''
cv2.grabCut(img, mask, rect, bgdModel, fgdModel, 9, cv2.GC_INIT_WITH_MASK)

cv2.imshow('mask', mask)

# mask2 = np.where((mask == 1) | (mask == 3), 1, 0).astype('uint8') # 提取前景
mask2 = np.where((mask == 0) | (mask == 2), 1, 0).astype('uint8')   # 提取背景
# if(condition成立)数组位置取前值否则取后值
img = img * mask2[:, :, np.newaxis]  # 改变数组维度与原图保持一致

cv2.imshow('result', img)

'''
cv2.waitKey(delay)
#  delay为正数时,延时delay毫秒结束
#  想要用按下某个键时退出可用以下方法:
#  if(cv2.waitKey(0)  == ord('q')):
        exit(0)
#别的方法也行,不唯一
'''
if cv2.waitKey(0) & 0xFF == 27:
    exit(0)
'''
cv2.destroyWindow(winname)
#结束窗口,winname为窗口名
cv2.destroyAllWindows() 
#结束所有窗口
'''
cv2.destroyAllWindows()

结果如下图。
在这里插入图片描述
就先这样,遇到别的再补充。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值