- 1.GrabCut
通过交互的方式获得前景物体;
原理:
(1)用户指定前景的大体区域,剩下的为背景区域;
(2)用户也可以明确指定某些地方为前景或者背景;
(3)GrabCut采用分段迭代的方式分析前景物体形成模型树;
(4)通过权重决定某个像素是前景还是背景;
grabCut(img, mask, rect, bgdModel, fgdModel, iterCount, mode=None):
Img:输入的原始图像;
Mask:分割之后产生的掩码;
Rect:使用鼠标选取的区域大小;
bgdModel:np.float64 ;大小为1-65且为零的数组;
fgdModel:np.float64 ;大小为1-65且为零的数组;
Intercount:迭代的次数;
Mode:GC_INIT_WITH_RECT;GC_INIT_WITH_MASK;
输出的Mask对应的每个像素值:
BGD:背景-0;
FGD:前景-1;
PR_BGD:可能是背景-2;
PR_FGD:可能是前景-3;
import os import cv2 import numpy as np #定义结构类 class App: flag=False startX=0 startY=0 rect=(0,0,0,0) def onmouse(self,event,x,y,flags,param): if(event&cv2.EVENT_LBUTTONDOWN==cv2.EVENT_LBUTTONDOWN): self.flag=True self.startX=x self.startY=y print('按下左键') elif(event&cv2.EVENT_LBUTTONUP==cv2.EVENT_LBUTTONUP): self.flag=False cv2.rectangle(self.img,pt1=(self.startX,self.startX),pt2=(x,y),color=(0,255,0),thickness=3) #构造rect self.rect=(min(self.startX,x),min(self.startY,y),abs(self.startX-x),abs(self.startY-y)) print('弹起左键') elif(event&cv2.EVENT_MOUSEMOVE==cv2.EVENT_MOUSEMOVE): if self.flag==True: #每一次移动都是在最开始的图片中绘制 self.img=self.img2.copy() cv2.rectangle(self.img, pt1=(self.startX, self.startX), pt2=(x, y), color=(0, 255, 0), thickness=3) print('鼠标移动') def run(self): cv2.namedWindow(winname='input',flags=cv2.WINDOW_AUTOSIZE) cv2.setMouseCallback('input',self.onmouse) self.img=cv2.imread('images/hometomn1.jpg') self.img=cv2.resize(src=self.img,dsize=(450,450)) self.img2=self.img.copy() #构造mask self.mask=np.zeros(shape=(self.img.shape[0],self.img.shape[1]),dtype=np.uint8) self.output=np.zeros(shape=(self.img.shape[0],self.img.shape[1],self.img.shape[2]),dtype=np.uint8) while True: cv2.imshow('input',self.img) cv2.imshow('output',self.output) key=cv2.waitKey(100) if (key&0xFF==27): break if key==ord('s'): bgmodel=np.zeros((1,65),dtype=np.float64) cv2.grabCut(img=self.img2,mask=self.mask,rect=self.rect,bgdModel=bgmodel, fgdModel=bgmodel,iterCount=1,mode=cv2.GC_INIT_WITH_RECT) #当判断为前景时,为255,否则为0 mask2=np.where((self.mask==1)|(self.mask==3),255,0).astype('uint8') self.output=cv2.bitwise_and(src1=self.img2,src2=self.img2,mask=mask2) cv2.destroyAllWindows() if __name__ == '__main__': print('Pycharm') app=App() print(app.run())
演示