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())
|