GraphCut算法介绍

分割分为两种

1 全自动图像分割:一般采用聚类算法来最大化前景与背景的差。

2 用户互动式图像分割:用户提供前景和背景的种子,然后对前景背景建立概率分布模型。

而GraphCut和GrabCut就是属于第二类图像分割算法。首先来说GraphCut。

Graph Cut(图形切割)应用于计算机视觉领域用来有效的解决各种低级计算机视觉问题,例如图像平滑(image smoothing)、立体应对问题(stereo correspondence problem)、图像分割(image segmentation)。

GraphCut利用最小割最大流算法进行图像的分割,可以将图像分割为前景和背景。使用该算法时需要在前景和背景处各画几笔作为输入,算法将建立各个像素点与前景背景相似度的赋权图,并通过求解最小切割区分前景和背景。

如果背景比较复杂或者背景和目标相似度很大,那分割就不太好了;二是速度有点慢。

我们的目标是一种通用的交互式分割技术,将图像分为两部分:“对象”和“背景”。用户通过指示绝对必须是对象一部分的某些像素(种子)和必须是背景一部分的某些像素,对分割施加某些硬约束。直观地说,这些硬约束提供了用户打算分段的线索。

Grab Cut只需要提供背景区域的像素集就可以了。也就是说你只需要框选目标,那么在方框外的像素全部当成背景

以下代码是给背景中的书画框框

"""
 -*- coding: utf-8 -*-
 author: Hao Hu
 @date   2022/1/20 11:02 AM
"""
import cv2
import numpy as np
from matplotlib import pyplot as plt
import os.path as osp
WHITE = [255,255,255]
def grab_cut():
    img_ori = cv2.imread('./sample10.jpg')
    # 将img二值化
    retVal, image = cv2.threshold(img_ori, 50, 100, cv2.THRESH_BINARY)

    mask = np.zeros(image.shape[:2], np.uint8)
    bgdModel = np.zeros((1, 65), np.float64)
    fgdModel = np.zeros((1, 65), np.float64)
    ix = int(img_ori.shape[0] / 22)
    iy = int(img_ori.shape[1] / 20)
    w = iy * 20
    h = ix * 22
    rect = (ix, iy, int(w), int(h))
    # cv2.rectangle(img, (ix*2, iy*3), (int(w*0.9), int(h*0.9)), (0, 255, 0), 2)
    # 默认几个点作为物体和背景像素点
    # (ix*15,iy*26),(ix*21,iy*15),(ix*21,iy*10)为背景像素点
    cv2.circle(mask, (ix*15, iy*26), 15, [0,0,0], -1)
    cv2.grabCut(image, mask, rect, bgdModel, fgdModel, 5, cv2.GC_INIT_WITH_RECT)
    mask2 = np.where((mask == 2) | (mask == 0), 0, 1).astype('uint8')
    mask2[ix * 21, iy * 19] = 1
    #plt.imshow(mask2), plt.colorbar(), plt.show()
    img = image * mask2[:, :, np.newaxis]

    return img,mask2,img_ori

def get_three_RGB(mask):
    contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    contours = list(contours)
    contours.sort(key=lambda x: cv2.contourArea(x), reverse=True)
    cnt = cv2.approxPolyDP(contours[0], epsilon=100, closed=True)
    cnt = cv2.minAreaRect(cnt)
    box = np.int0(cv2.boxPoints(cnt))
    return mask, box


if __name__ == '__main__':
    img,mask,img_ori = grab_cut()
    _, box=get_three_RGB(mask)
    re = cv2.drawContours(img_ori.copy(), [box], 0, (0, 255, 0), 3)
    #cv2.imwrite(osp.join(save_p, osp.basename(im_p)), re)
    plt.imshow(re),  plt.show()

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值