首页 > 编程语言 >Python工具箱系列(五十六)

Python工具箱系列(五十六)

时间:2024-10-30 15:20:55浏览次数:1  
标签:last img point Python self cv2 param 五十六 工具箱

抠图

抠图是基本需求,最常见的应用场景就是证件照,每次去拍照,都要用个纯色的幕布,而且要求衣服不能太浅。其实背后是有原因的:为了管理部门更准确识别出人像。许多科幻电影也是要求演员在绿幕前表演,后期抠图合成逼真的电影。抠图工具非常多,例如PhotoShop就是抠图利器,可以很神奇地把图片里的元素单独提取出来,和其他的背景合并。事实上,ps的这些能力背后也是基于图像处理的算法。抠图的基本原理,就是找出目标物的边界范围,然后把其他地方变透明。常见做法有3种:

根据像素色彩范围,识别出背景。适合纯背景色场景,如证件照。

如果背景色彩复杂,就分块识别,在某小块中色彩相对集中。但需要单独设计切分算法。

机器学习算法,训练出识别物的特征模型。训练过程非常耗资源,但有了模型就可以快速应用,目前不少大平台也开放出了自己的训练模型,如百度的paddlehub项目。

以下是背景杂乱的原图。

import paddlehub as hub
import cv2 as cv

def cutperson(inputfile):
    """
    AI抠图

    Args:
        inputfile (string): 要处理的图片文件名
    """
    image = cv.imread(inputfile)
    humanseg = hub.Module(name='deeplabv3p_xception65_humanseg')
    
    filelist = [inputfile]
    res = humanseg.segmentation(data = {'image':filelist},visualization=True,output_dir='.output')    

cutperson("/mnt/d/test/cut2.bmp")

下图是输出图片,可以看出效果还不错。

import cv2
import numpy as np
 
#绘制前景/背景标识线标志
drawing = False
 
# 定义GrabCut类,作用是设置一些参数
class GrabCut:
    def __init__(self, t_img):
        self.img = t_img
        self.img_raw = img.copy()
        self.img_width = img.shape[0]
        self.img_height = img.shape[1]
        self.img_show = self.img.copy()
        self.img_gc = self.img.copy()
        self.img_gc = cv2.GaussianBlur(self.img_gc, (3, 3), 0)
        self.lb_up = False
        self.rb_up = False
        self.lb_down = False
        self.rb_down = False
        self.mask = np.full(self.img.shape[:2], 2, dtype=np.uint8)
        self.firt_choose = True

# 鼠标操作的的回调函数
def mouse_event(event, x, y, flags, param):
    global drawing, last_point, start_point
    # 左键按下,开始标识前景
    if event == cv2.EVENT_LBUTTONDOWN:
        drawing = True
        # 设置鼠标按下的起始点
        last_point = (x, y)
        start_point = last_point
        param.lb_down = True

    # 右键按下,开始标识背景
    elif event == cv2.EVENT_RBUTTONDOWN:
        # 读者请先标识前景,否则无法分割
        if param.firt_choose:
            print("Please select foreground first!")
            return
        drawing = True
        last_point = (x, y)
        start_point = last_point
        param.rb_down = True

   # 鼠标移动,绘制标识前景和背景的线
    elif event == cv2.EVENT_MOUSEMOVE:
        if drawing:
            # 鼠标左键按下的绘制
            if param.lb_down:
                cv2.line(param.img_show, last_point, (x,y), (0, 0, 255), 2, -1)
                cv2.rectangle(param.mask, last_point, (x, y), 1, -1, 4)
            # 鼠标右键按下的绘制
            if param.rb_down:
                cv2.line(param.img_show, last_point, (x, y), (255, 0, 0), 2, -1)
                cv2.rectangle(param.mask, last_point, (x, y), 0, -1, 4)
            last_point = (x, y)

    # 左键释放,结束标识前景
    elif event == cv2.EVENT_LBUTTONUP:
        drawing = False
        param.lb_up = True
        param.lb_down = False
        cv2.line(param.img_show, last_point, (x,y), (0, 0, 255), 2, -1)
        # 如果第一次标识,切换状态
        if param.firt_choose:
            param.firt_choose = False
        cv2.rectangle(param.mask, last_point, (x,y), 1, -1, 4)

    # 右键释放,结束标识背景
    elif event == cv2.EVENT_RBUTTONUP:
        # 如果首先标识背景则不做处理
        if param.firt_choose:
            return
        drawing = False
        param.rb_up = True
        param.rb_down = False
        cv2.line(param.img_show, last_point, (x,y), (255, 0, 0), 2, -1)
        cv2.rectangle(param.mask, last_point, (x,y), 0, -1, 4)

#执行操作
def process(img):
    if img is None:
        print('Can not read image correct!')
        return
    g_img = GrabCut(img)
 
    cv2.namedWindow('image')
    # 定义鼠标的回调函数
    cv2.setMouseCallback('image', mouse_event, g_img)
    while (True):
        cv2.imshow('image', g_img.img_show)
        # 鼠标左键或者右键抬起时,按照标识执行Grabcut算法
        if g_img.lb_up or g_img.rb_up:
            g_img.lb_up = False
            g_img.rb_up = False
            # 背景model
            bgdModel = np.zeros((1, 65), np.float64)
            # 前景model
            fgdModel = np.zeros((1, 65), np.float64)
 
            rect = (1, 1, g_img.img.shape[1], g_img.img.shape[0])
            mask = g_img.mask
            g_img.img_gc = g_img.img.copy()
            #执行Grabcut算法
            cv2.grabCut(g_img.img_gc, mask, rect, bgdModel, fgdModel, 5, cv2.GC_INIT_WITH_MASK)
            # 0和2做背景
            mask2 = np.where((mask == 2) | (mask == 0), 0, 1).astype('uint8')
            # 使用蒙板来获取前景区域
            g_img.img_gc = g_img.img_gc * mask2[:, :, np.newaxis]
            cv2.imshow('Grabcut_result', g_img.img_gc)
 
        # 按下ESC键退出
        if cv2.waitKey(20) == 27:
            break
 
if __name__ == '__main__':
    img = cv2.imread("/mnt/d/test/cut2.bmp")
    process(img)

利用opencv的交互能力,人工简单的勾勒要抠图的主要部分,随后就会生成当前的抠图效果。勾勒的效果如下图所示。

勾勒时不需要太精确。算法就会自动生成当前的抠图如下所示。

 

从上图可以看出,交互式抠图的效果不错,不过还是直接使用paddlehub来的方便。

标签:last,img,point,Python,self,cv2,param,五十六,工具箱
From: https://www.cnblogs.com/shanxihualu/p/18515897

相关文章

  • Python工具箱系列(五十七)
    图像分割与人脸识别众所周知图像是由若干有意义的像素组成的,图像分割作为计算机视觉的基础,对具有现有目标和较精确边界的图像进行分割,实现在图像像素级别上的分类任务。图像分割可分为语义分割和实例分割两类,区别如下:语义分割:将图像中每个像素赋予一个类别标签,用不同的颜色来表......
  • python调用grpc请求
    gRPC是一款高性能、开源的RPC框架,支持多种编程语言。Protobuf是gRPC使用的默认序化协议,可以将结构化数据序列化为二进制格式,提高数据传输效率。在Python中使用gRPC调用服务时,通常需要先定义协议缓冲区(ProtocolBuffers)消息类型,这些类型是从.proto文件生成的。当你准备调用一个gRP......
  • 【EI复现】基于深度强化学习的微能源网能量管理与优化策略研究(Python代码实现)
    ......
  • 【EI复现】基于深度强化学习的微能源网能量管理与优化策略研究(Python代码实现)
    ......
  • python毕业设计django基于协同过滤算法的养老新闻推荐网站
    文章目录前言一、项目介绍三、功能介绍四、核心代码五、效果图前言Django基于协同过滤算法的养老新闻推荐网站是一个结合了Django框架和协同过滤推荐算法的养老领域信息服务系统。该系统旨在通过个性化推荐算法,向用户推荐符合其兴趣偏好的养老新闻,以提高用户体验和......
  • Python毕业设计基于Python+Django的人事管理系统
    文章目录项目介绍技术介绍功能介绍核心代码数据库参考系统效果图文章目录项目介绍  人事管理系统的目的是让使用者可以更方便的将人、设备和场景更立体的连接在一起。能让用户以更科幻的方式使用产品,体验高科技时代带给人们的方便,同时也能让用户体会到与以往常规......
  • Python基础16_数据结构:队列&树
    一、队列队列(Queue),它是一种运算受限的线性表,先进先出(FIFOFirstInFirstOut)-队列是一种受限的线性结构-受限之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作Python标准库中的queue模块提供了多种队列实现,包括普通队列、双端队列、......
  • python之Requests模块
    python中文官方文档:https://docs.python.org/zh-cn/3/Requests中文官方文档地址:https://requests.readthedocs.io/projects/cn/zh_CN/latest/1.Requests模块快速入门requests库的基本使用详解1.Requests模块作用:发送http请求,获取响应数据2.Requests模块是第三方模块,需要......
  • Python表格格式转换模块:tablib
    文章目录安装创建表格导出数据读写安装Tablib是Python的表格转换插件,支持不同格式表格之间的转换,其推荐的安装方式为pipinstall"tablib[all]"其中,all等同于html,pandas,ods,xls,xlsx,yaml,表示在安装tablib的基础上,同时对这些不同的文件格式提供支持。如果......
  • 【一分钟配置Python环境变量
    配置Python环境变量可以帮助系统找到Python解释器和相关工具。下面是如何在不同操作系统上配置Python环境变量的步骤:Windows 1.安装Python:在官方网站下载并安装Python,安装过程中选择“AddPythontoPATH”选项。手动配置环境变量:右击“此电脑”或“计算机”,选择“属性......