zoukankan      html  css  js  c++  java
  • 磨皮,美白,搞笑图片处理

     
     (1)PIL库自我学习总结

    Hello!今天我们来学习一下这个神奇的图片处理的第三方函数库——PIL库

    (本blog部分图片及代码来自网络)

    这是一个支持图像存储、显示和处理的函数库,它能够处理几乎所有图像格式,可以完成对图像的缩放、裁剪、叠加以及图像添加条纹,文字等信息等的操作。

    首先是利用pip下载一个:

    它有许多子库,例如:Image、ImageChops、ImageDraw等等,他们各有神通,发挥着自己的作用,

    首先我们当然学习的是经典的Image子库;

    方法 描述
    Image.open(filename) 根据参数加载图像文件
    Image.new(mode,size,color) 根据给定参数创建一个新的图像
    Image.open(StringIO.StringIO(buffer)) 从字符串中获取图像
    Image.frombytes(mode,size,data) 根据像素点data创建图像
    Image.verify() 对图像文件完整性进行检查,返回异常

    常用函数

    读取一张图片

    im=Image.open(‘test.jpg’)

    显示一张图片

    im.show()

    保存图片

    im.save(“save.gif”,“GIF”) #保存图像为gif格式

    查看图像信息

    im.format, im.size, im.mode

    图片裁剪:
    box=(100,100,500,500)

    #设置要裁剪的区域

    region=im.crop(box) #此时,region是一个新的图像对象。

    改变图像的大小

    out=img.resize((128,128))#resize成128*128像素大小

    旋转图像

    out=img.rotate(45) #逆时针旋转45度

    图像类型转换

    im=im.convert(“RGBA”)

    (2)缩略图的学习,我们有时候为了节约储存空间,会将原来的图片进行压缩,通过等比例压缩之后会变成缩略图,那么如何用Image库来实现呢??

    代码如下:

    from PIL import Image
    im=Image.open("test1.png")
    im.thumbnail((128,128))
    im.save("nest","png")
    im.show("nest")

    原图与缩略图如下:

                    

    (3)改变图片颜色
    代码如下:

    from PIL import Image
    im=Image.open("test1.png")
    r,g,b=im.split()
    newr=g.point(lambda i:i*0.9)
    newg=g.point(lambda i:i<100)
    om=Image.merge(im.mode,(newr,newg,b))
    om.save("nest.png")
    om.show("nest")

    原图:

    改变颜色后的图片:
    (4)浮雕艺术在世界各地都可以见到,中国古代在唐朝以来就有许多浮雕效果的东西,很多的大型纪念性建筑都有这种作为装饰,常见的有花窗,龙柱等。

    简单的来说,浮雕就是把所要呈现的图像突起于石头表面,根据凹凸的程度不同从而形成三维的立体感。

    用Python画一张浮雕画,那就进行类似的原理,通过勾画图像的轮廓,并且降低周围的像素值,那就可以产生一张具有立体感的浮雕效果图片。我们可以采用相邻像素相减的方法来得到轮廓与平面的差,类似边缘的特征,从而获得这种立体感,为了增强图片的主观感受,我们还可以给这个差加上一个固定值。

    那具体怎么实现呢?首先先把图片读入内存,转化为灰度图像,使用当前像素值 = 相邻像素值之差来得到图像的边缘特征,在加上固定数值150就可以得到浮雕效果了。

    import cv2
    import numpy as np
    img = cv2.imread('E:pythoneeLearnOpenCV\test222.jpg',1)
    imgInfo = img.shape
    height = imgInfo[0]
    width = imgInfo[1]
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    dstImg = np.zeros((height,width,1),np.uint8)
    # 算法:newPixel = grayCurrentPixel - grayNextPixel + 150
    for i in range(0,height):
        for j in range(0,width-1):
            grayCurrentPixel = int(gray[i,j])
            grayNextPixel = int(gray[i,j+1])
            newPixel = grayCurrentPixel - grayNextPixel + 150
            if newPixel > 255:
                newPixel = 255
            if newPixel < 0:
                newPixel = 0
            dstImg[i,j] = newPixel
    cv2.imshow('dstImg',dstImg)
    cv2.waitKey(0)
    

    注意在这里图像像素是用0-255的范围表示的,所以当像素值大于255时,需要将他变为255


     



    (5)提取图片的轮廓的代码如下:

    from PIL import Image
    from PIL import ImageFilter
    im=Image.open("test1.png")
    om=im.filter(ImageFilter.CONTOUR)
    om.show("nest")

    原图与提取轮廓图的对比如下

    (6)美白磨皮实现原理

    大神提供的算法:
    Dest =(Src * (100 - Opacity) + (Src + 2 * GuassBlur(EPFFilter(Src) - Src + 128) - 256) * Opacity) /100 ;
    大神本神传送门,该算法其实是对 PS 的一种磨皮方案的脚本实现。

    Python + OpenCV 实现

    网上看到的一个基于上述公式的 python 实现方案beauty_face,但是他再线性光叠加时出错,修正后如beauty_face2(由于对Python矩阵运算不熟悉使用了比较笨的方法实现), 具体见代码:

    #!/bin/python
    # 祛痘美白 
    
    import numpy as np
    import cv2
    
    def beauty_face(img):
        '''
        Dest =(Src * (100 - Opacity) + (Src + 2 * GuassBlur(EPFFilter(Src) - Src + 128) - 256) * Opacity) /100 ;
        https://my.oschina.net/wujux/blog/1563461
        '''
    
        dst = np.zeros_like(img)
        #int value1 = 3, value2 = 1; 磨皮程度与细节程度的确定
        v1 = 3
        v2 = 1
        dx = v1 * 5 # 双边滤波参数之一 
        fc = v1 * 12.5 # 双边滤波参数之一 
        p = 0.1
       
        temp4 = np.zeros_like(img)
        
        temp1 = cv2.bilateralFilter(img,dx,fc,fc)
        temp2 = cv2.subtract(temp1,img)
        temp2 = cv2.add(temp2,(10,10,10,128))
        temp3 = cv2.GaussianBlur(temp2,(2*v2 - 1,2*v2-1),0)
        temp4 = cv2.add(img,temp3)
        dst = cv2.addWeighted(img,p,temp4,1-p,0.0)
        dst = cv2.add(dst,(10, 10, 10,255))
        return dst
    
    def beauty_face2(src):
        '''
        Dest =(Src * (100 - Opacity) + (Src + 2 * GuassBlur(EPFFilter(Src) - Src + 128) - 256) * Opacity) /100 ;
        '''
    
        dst = np.zeros_like(src)
        #int value1 = 3, value2 = 1; 磨皮程度与细节程度的确定
        v1 = 3
        v2 = 1
        dx = v1 * 5 # 双边滤波参数之一 
        fc = v1 * 12.5 # 双边滤波参数之一 
        p = 0.1
       
        temp4 = np.zeros_like(src)
        
        temp1 = cv2.bilateralFilter(src,dx,fc,fc)
        temp2 = cv2.subtract(temp1,src)
        temp2 = cv2.add(temp2, (10,10,10,128))
        temp3 = cv2.GaussianBlur(temp2,(2*v2 - 1,2*v2-1),0)
        temp4 = cv2.subtract(cv2.add(cv2.add(temp3, temp3), src), (10, 10, 10, 255))
        
        dst = cv2.addWeighted(src,p,temp4,1-p,0.0)
        dst = cv2.add(dst, (10, 10, 10,255))
        return dst
    
    
    def init():
        img = cv2.imread('testimg.jpg')
    
        # blur1 = cv2.GaussianBlur(img, (5,5),0)
        # blur2 = cv2.bilateralFilter(img, 9 , 75, 75)
        blur3 = beauty_face(img)
        blur4 = beauty_face2(img)
    
        cv2.imshow('image0', img)
        # cv2.imshow('image1', blur1)
        # cv2.imshow('image2', blur2)
        cv2.imshow('image3', blur3)
        cv2.imshow('image4', blur4)
    
        #cv2.namedWindow('image', cv2.WINDOW_NORMAL)
        #cv2.resizeWindow('image', 1000, 1000) #定义frame的大小
    
        cv2.waitKey(0)
        cv2.imwrite('result1.png', blur3)
        cv2.imwrite('result2.png', blur4)
        cv2.destroyAllWindows()
    
    if __name__ == "__main__":
        init()

    实验效果图

    原图:beauty_face 与 beauty_face2 对比如下:

     
    原图
    beauty_face2
    (5)转化为字符画

    小编找到了10几行的,好玩的动态表情包生成的代码。分享分享!

    这个程序怎么做呢?不要急,来听我给大家分析分析。

     
     

    工具:程序环境

    语言:Python 3.6

    编辑器:Pycharm


     
     

    程序步骤

    实现字符动态图转化只需要 3 步,合久必分,分久必合。

    把原动态图拆分成一帧一帧的图片。

    把拆分的每帧图片转化为字符画。

    把每帧字符画图片组合成动态图。

     
     

    导入编辑器

    把上面安装好的两个库在编辑器 Pycharm 的 settings/Interpreter 中安装好并在程序中导入,说明下,opencv-python 这个库这次只用到其中的 cv2 模块,所以只需导入这个模块。

    importimageioimportcv2

    拆分图片

    先定义好原始图片和处理后的图片的保存路径,这个大家运行程序前需要换成你自己需要转化的图片路径和转换后字符画图片的路径和名称。然后用 imageio 中的 mimread 方法读取原动态图,把动态图每帧都拆分成若干张图片。

     
     

    转化为字符画
    应用上面定义好的图片灰度与字符的映射,把上面的每帧图片都转化为字符画,并保存在一个列表中。
     
    image

    串联字符画为动态图
    最后把刚才处理好的每帧的字符画通过 imageio 库里的 mimsave 方法组合成动态图,变成字符动态图。
    imageio.mimsave(dealPic, A,'GIF', duration=0.1)# 把A列表里的字符画组合起来,变成动态图print('转化完成,请到你保存的路径下查看')
    通过这个程序,我们就可以把我们喜欢的图片变成字符画动态图。下面这个用本程序制


    作者:璃沫仙人
    链接:https://www.jianshu.com/p/3e45ab95d043
    来源:简书
    简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

    总结

    直接使用 PS 双曲线、中性灰、高低频等磨皮方案,能比自动化处理取得不错的效果,但自动化胜在傻瓜化。目前的方案是对全图做了平滑处理,并不只是对脸部,更高级方案可参考图像算法---磨皮算法研究汇总



  • 相关阅读:
    JSP语法学习笔记
    jsp 自定义标签
    java排序算法
    Linux系统rootpassword改动
    人生中第一次面试——北漂18年(1)
    msgsnd的一个小问题
    推荐系统中的矩阵分解演变方式
    FZU 2124 FOJ 2124 吃豆人【BFS】
    啦啦啦啦、新人学习中。。
    【Linux】线程并发拷贝程序
  • 原文地址:https://www.cnblogs.com/2987831760qq-com/p/10687110.html
Copyright © 2011-2022 走看看