【OpenCV-Python】26.OpenCV的交互式前景提取——示例2(使用鼠标进行框选和标注)

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、数据科学、人工智能等文章后续会不定期发布,请大家多多关注,一键三连哟(●’◡’●)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

机器视觉小学徒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值