zoukankan      html  css  js  c++  java
  • 用python实现你的绘画梦想

    导语:

    ​ 你是否还在为当时年少时没有选择自己的梦想而伤心,是否还在为自己的无法成为绘画名家而苦恼,这一切都不需要担心。python都能帮你实现,诶!python怎么能画画呢,一些简单的图案没问题,但是我要是想画素描那肯定没有办法了呀!

    需求分析:

    通过python代码脚本,实现绘制素描

    安装工具

    pip install pillow
    
    pip install numpy
    

    代码实现

    首先我们需要看一下我们需要的原图:

    这是一头大水牛,那我们要如何将它变成一幅素描画呢?

    来看我们第一种方案:

    # -*- coding: utf-8 -*-
    from PIL import Image
    from random import randint
    
    old = Image.open(r"da.jpg")
    new = Image.new('L', old.size, 255)
    w, d = old.size
    old = old.convert('L')
    PEN_SIZE = 3
    COLOR_DIFF = 7
    LINE_LEN = 2
    
    for i in range(PEN_SIZE + 1, w - PEN_SIZE - 1):
        for j in range(PEN_SIZE + 1, d - PEN_SIZE - 1):
            originalcolor = 255
            lcolor = sum([old.getpixel((i - r, j))
                          for r in range(PEN_SIZE)]) // PEN_SIZE
            rcolor = sum([old.getpixel((i + r, j))
                          for r in range(PEN_SIZE)]) // PEN_SIZE
            if abs(lcolor - rcolor) > COLOR_DIFF:
                originalcolor -= (255 - old.getpixel((i, j))) // 4
                for p in range(-LINE_LEN + randint(-1, 1), LINE_LEN + randint(-1, 1)):
                    new.putpixel((i, j + p), originalcolor)
    
            ucolor = sum([old.getpixel((i, j - r))
                          for r in range(PEN_SIZE)]) // PEN_SIZE
            dcolor = sum([old.getpixel((i, j + r))
                          for r in range(PEN_SIZE)]) // PEN_SIZE
            if abs(ucolor - dcolor) > COLOR_DIFF:
                originalcolor -= (255 - old.getpixel((i, j))) // 4
                for p in range(-LINE_LEN + randint(-1, 1), LINE_LEN + randint(-1, 1)):
                    new.putpixel((i + p, j), originalcolor)
    
            lucolor = sum([old.getpixel((i - r, j - r))
                           for r in range(PEN_SIZE)]) // PEN_SIZE
            rdcolor = sum([old.getpixel((i + r, j + r))
                           for r in range(PEN_SIZE)]) // PEN_SIZE
            if abs(lucolor - rdcolor) > COLOR_DIFF:
                originalcolor -= (255 - old.getpixel((i, j))) // 4
                for p in range(-LINE_LEN + randint(-1, 1), LINE_LEN + randint(-1, 1)):
                    new.putpixel((i - p, j + p), originalcolor)
    
            rucolor = sum([old.getpixel((i + r, j - r))
                           for r in range(PEN_SIZE)]) // PEN_SIZE
            ldcolor = sum([old.getpixel((i - r, j + r))
                           for r in range(PEN_SIZE)]) // PEN_SIZE
            if abs(rucolor - ldcolor) > COLOR_DIFF:
                originalcolor -= (255 - old.getpixel((i, j))) // 4
                for p in range(-LINE_LEN + randint(-1, 1), LINE_LEN + randint(-1, 1)):
                    new.putpixel((i + p, j + p), originalcolor)
    
    new.save(r"pencil_drawing.jpg")
    
    

    我们这第一份素描图案时以线条为单位进行素描的,而且还增加了随机函数,图案中线条的长度不确定,这样创作的素描看上去更加柔和,看起来更加接近真实的人类作画的风格。

    但是这个方法有一些弊端,

    • 一是代码量较多

    • 二是执行速度过慢

    你想通过这个方式实现一个素描图案,需要等待很长时间。

    那么有没有更好的方式呢?

    来,我们再来看,接下来我们要用一种更友好的方式来实现这个需求

    from PIL import Image
    import numpy as np
    
    a = np.asarray(Image.open('牛.jpg').convert('L')).astype('float')
    depth = 10.  # (0-100)
    grad = np.gradient(a)  # 取图像灰度的梯度值
    grad_x, grad_y = grad  # 分别取横纵图像梯度值
    grad_x = grad_x * depth / 100.
    grad_y = grad_y * depth / 100.
    A = np.sqrt(grad_x ** 2 + grad_y ** 2 + 1.)
    uni_x = grad_x / A
    uni_y = grad_y / A
    uni_z = 1. / A
    vec_el = np.pi / 2.2  # 光源的俯视角度,弧度值
    vec_az = np.pi / 4.  # 光源的方位角度,弧度值
    dx = np.cos(vec_el) * np.cos(vec_az)  # 光源对x 轴的影响
    dy = np.cos(vec_el) * np.sin(vec_az)  # 光源对y 轴的影响
    dz = np.sin(vec_el)  # 光源对z 轴的影响
    b = 255 * (dx * uni_x + dy * uni_y + dz * uni_z)  # 光源归一化
    b = b.clip(0, 255)
    im = Image.fromarray(b.astype('uint8'))  # 重构图像
    im.save('new.jpg')
    

    可能细心一点,大家可以看到我使用的是,数据分析,金融量化,机器学习,人工智能的必备工具包numpy,而且代码量缩短的二十几行了,效果相较于上面那种方式,还要更好一些,运行的速度也要快很多倍。

  • 相关阅读:
    常见寻找OEP脱壳的方法
    Windows内核原理系列01
    HDU 1025 Constructing Roads In JGShining's Kingdom
    HDU 1024 Max Sum Plus Plus
    HDU 1003 Max Sum
    HDU 1019 Least Common Multiple
    HDU 1018 Big Number
    HDU 1014 Uniform Generator
    HDU 1012 u Calculate e
    HDU 1005 Number Sequence
  • 原文地址:https://www.cnblogs.com/Yang-Sen/p/11841070.html
Copyright © 2011-2022 走看看