栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Python-opencv利用setMouseCallback实现美图秀秀磨皮魔法笔

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Python-opencv利用setMouseCallback实现美图秀秀磨皮魔法笔

Python-opencv实现美图秀秀磨皮魔法笔
  • 前言
  • 一、涉及技术
    • 1.Opencv鼠标响应setMouseCallback()
    • 2.双边滤波
  • 二、具体实现
    • 1.代码
    • 2.结果展示
    • 3.一些注释


前言

最近有时间写一写博客,突发奇想实现一个鼠标点击对面部磨皮效果的demo,写的比较简单仅供大家学习参考。


一、涉及技术 1.Opencv鼠标响应setMouseCallback()

OpenCV-Python中可以使用setMouseCallback来设置鼠标事件的回调函数

语法格式如下:

cv2.setMouseCallback(windowName,dc)

相关参数说明如下:

  • windowName:创建窗口的名字
  • dc:鼠标响应函数,回调函数

回调函数格式

dc(event,x,y,flags,param)

相关参数说明如下:

  • event 是鼠标事件,具体事件如下所示
  • x,y 是鼠标点击时图像的坐标
  • flags 是CV_EVENT_FLAG的组合
  • param 是自定义传递到setMouseCallback函数的参数

event 具体说明如下:

  • EVENT_MOUSEMOVE //滑动
  • EVENT_LBUTTonDOWN //左键点击
  • EVENT_RBUTTonDOWN //右键点击
  • EVENT_MBUTTonDOWN //中键点击
  • EVENT_LBUTTonUP //左键放开
  • EVENT_RBUTTonUP //右键放开
  • EVENT_MBUTTonUP //中键放开
  • EVENT_LBUTTonDBLCLK //左键双击
  • EVENT_RBUTTonDBLCLK //右键双击
  • EVENT_MBUTTonDBLCLK //中键双击
2.双边滤波

语法格式如下:

cv2.bilateralFilter(src, d, sigmaColor, sigmaSpace)

相关参数说明如下:

  • src:待处理图像
  • d:过滤时,每个像素邻域的直径范围
  • sigmaColor: 颜色空间过滤器的sigma值
  • sigmaSpace: 坐标空间中滤波器的sigma值

二、具体实现 1.代码
import cv2
import numpy as np

ix,iy=-1,-1
# 画笔半径
radius = 8

# 人脸磨皮
def face_dermabrasion(cut_image,mask,x,y):
    # 创建待处理图像
    pending_image = cv2.bitwise_and(cut_image, cut_image, mask=mask)
    # 双边滤波
    blur_img = cv2.bilateralFilter(pending_image, 15, 60, 60)
    # 图像融合
    fusion_img = cv2.addWeighted(pending_image, 0.3, blur_img, 0.7, 0)

    not_mask = 255 - mask
    back_img = cv2.bitwise_and(fusion_img, fusion_img, mask=mask)
    # cv2.imshow('back_img',back_img)
    front_img = cv2.bitwise_and(cut_image, cut_image, mask=not_mask)
    # cv2.imshow('front_img',front_img)
    result_img = cv2.add(back_img, front_img)
    # cv2.imshow('result_img',result_img)
    img[y-(2*radius):y+(2*radius),x-(2*radius):x+(2*radius)] = result_img


def dc(event,x,y,flags,param):
    global ix,iy
    mask = np.zeros([img.shape[0],img.shape[1]],dtype=np.uint8)
        # 鼠标左键点击
    if event==cv2.EVENT_LBUTTONDOWN:
        ix,iy=x,y
        # print(ix,iy)
        cv2.circle(mask, (ix, iy), radius, (255, 255, 255), -1)
        cut_image = img[iy-(2*radius):iy+(2*radius),ix-(2*radius):ix+(2*radius)]
        new_mask = mask[iy-(2*radius):iy+(2*radius),ix-(2*radius):ix+(2*radius)]
        face_dermabrasion(cut_image,new_mask,ix,iy)

if __name__ == '__main__':
    # 读取图像
    img = cv2.imread('g:/face.jpg')
    cv2.namedWindow('img')
    cv2.setMouseCallback('img',dc)
    while(1):
        cv2.imshow('img',img)
        cv2.waitKey(1)&0xFF

2.结果展示
左边为原图,大概用鼠标点了几个地方,没有全部处理,效果如右图所示。 3.一些注释
  • 运行时发现了一点小bug,选取边缘的时候没有设置图像边界,更改一下图像边界就可以了,在此不做修改了~
  • 画笔半径设置成了全局变量可以控制画笔半径的大小,后续可拓展成界面输入参数
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/588116.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号