26.OpenCV的交互式前景提取——示例2(使用鼠标进行框选和标注)
前言
首先,使用鼠标进行框选前景范围;然后利用鼠标左键标注背景,鼠标右键标注前景;最后直接得到分割后的图像。相较于之前的示例方法,此方法不用确定要提取的前景图像的坐标(rect参数),也不用提前复制图像后进行标注。
此示例可直接在原图上进行上述功能。
一、使用鼠标进行框选和标注的前景提前结果
程序运行结果如图所示:
(1) 在原图上用鼠标框选前景所在的位置,矩形(绿色)内部为前景图像,外部为背景
(2) 前景提取时使用掩膜全为0(等同于未使用掩模图像),只根据上一步设置的矩形区域提取前景
(3) 为了获得更好的结果,在原图上使用鼠标左键标注背景(黑色),鼠标右键标注前景(白色)
(4) 将上一步完成的标注图像保存为掩膜图像
(5) 利用掩膜图像进行第二次前景提取
二、使用鼠标进行框选和标注的前景提前程序
import cv2
import numpy as np
from os.path import exists
def on_mouse(event, x, y, flag, param):
global rect
global leftButtonDowm
global leftButtonUp
if event == cv2.EVENT_LBUTTONDOWN:
rect[0] = x
rect[2] = x
rect[1] = y
rect[3] = y
leftButtonDowm = True
leftButtonUp = False
if event == cv2.EVENT_MOUSEMOVE:
if leftButtonDowm and not leftButtonUp:
rect[2] = x
rect[3] = y
if event == cv2.EVENT_LBUTTONUP:
if leftButtonDowm and not leftButtonUp:
x_min = min(rect[0], rect[2])
y_min = min(rect[1], rect[3])
x_max = max(rect[0], rect[2])
y_max = max(rect[1], rect[3])
rect[0] = x_min
rect[1] = y_min
rect[2] = x_max
rect[3] = y_max
leftButtonDowm = False
leftButtonUp = True
img = cv2.imread("test.jpg")
imgmask=cv2.imread("test.jpg")
drawing = False
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]
leftButtonDowm = False
leftButtonUp = True
cv2.namedWindow('img')
cv2.setMouseCallback('img',on_mouse)
cv2.imshow('img',img)
while cv2.waitKey(2) == -1:
global img
if leftButtonDowm and not leftButtonUp:
img_copy = img.copy()
cv2.rectangle(img_copy,(rect[0],rect[1]),(rect[2],rect[3]),(0,255,0),2)
cv2.namedWindow('img', cv2.WINDOW_NORMAL)
cv2.imshow('img',img_copy)
elif not leftButtonDowm and leftButtonUp and rect[2] - rect[0] != 0 and rect[3] - rect[1] != 0:
# 转换为宽度高度
rect[2] = rect[2] - rect[0]
rect[3] = rect[3] - rect[1]
rect_copy = tuple(rect.copy())
rect = [0,0,0,0]
cv2.grabCut(img,mask,rect_copy,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_RECT)
mask2 = np.where((mask==2)|(mask==0),0,1).astype('uint8')
img_show = img * mask2[:,:,np.newaxis]
cv2.imshow('grabCut1',img_show)
def draw_2(event,x,y,flag,param):
global img,imgmask,drawing_bg,drawing_fg
if event == cv2.EVENT_LBUTTONDOWN:
drawing_bg = True
elif event == cv2.EVENT_MOUSEMOVE:
if drawing_bg == True:
cv2.circle(imgmask,(x,y),3,(0,0,0),-1)
elif event == cv2.EVENT_LBUTTONUP:
drawing_bg = False
if event == cv2.EVENT_RBUTTONDOWN:
drawing_fg = True
elif event == cv2.EVENT_MOUSEMOVE:
if drawing_fg == True:
cv2.circle(imgmask,(x,y),3,(255,255,255),-1)
elif event == cv2.EVENT_RBUTTONUP:
drawing_fg = False
elif event==cv2.EVENT_RBUTTONDBLCLK:
cv2.imwrite("test_imgmask.png",imgmask)
imgmask_BF = cv2.imread("test_imgmask.png")
cv2.imshow('mask image',imgmask_BF)
mask3 = cv2.cvtColor(imgmask_BF, cv2.COLOR_BGR2GRAY, dstCn=1)
mask[mask3 == 0] = 0
mask[mask3 == 255] = 1
cv2.grabCut(img, mask ,None, bgdModel, fgdModel, 5, cv2.GC_INIT_WITH_MASK)
mask3 = np.where((mask==2)|(mask==0),0,1).astype('uint8')
img = img*mask3[:,:,np.newaxis]
cv2.imshow('grabCut2', img)
cv2.imshow('drawing_BFG',imgmask)
cv2.namedWindow('drawing_BFG')
cv2.setMouseCallback('drawing_BFG',draw_2)
cv2.imshow('drawing_BFG',imgmask)
cv2.waitKey(0)
cv2.destroyAllWindows()
三、OpenCV-Python资源下载
OpenCV-Python测试用图片、中文官方文档、opencv-4.5.4源码
总结
以上内容介绍了OpenCV-Python的交互式前景提取的相关示例,有关Python、数据科学、人工智能等文章后续会不定期发布,请大家多多关注,一键三连哟(●’◡’●)。