一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

彩色圖片轉(zhuǎn)手繪線稿的原理簡(jiǎn)述與Python實(shí)現(xiàn)

 小小明代碼實(shí)體 2021-11-30

大家好,我是小小明,在學(xué)習(xí) 好友葉庭云 介紹的一門中國(guó)大學(xué)MOOC的課程中,學(xué)到手繪圖像,下面我測(cè)試并總結(jié)一下。

課程鏈接是:https://www.icourse163.org/course/BIT-1001870002?from=searchPage

下面使用Python Imaging Library ( PIL ) 進(jìn)行圖像處理,安裝方式:

pip install pillow

彩色圖片轉(zhuǎn)手繪線稿的原理簡(jiǎn)述

對(duì)于一張手繪圖,其特征主要是邊界線條較重、相同或相近色彩趨于白色、略有光源效果。

將彩色圖片轉(zhuǎn)換為手繪線稿,首先需要將圖片轉(zhuǎn)換為灰度圖片。

灰度值實(shí)際代表了圖像明暗的變化,而梯度代表了灰度的變化率。

調(diào)整像素的梯度值可以間接改變圖像的明暗程度。

下面以如下圖片為例進(jìn)行測(cè)試:

from PIL import Image
import numpy as np

im = Image.open('001.jpg')
im

image-20210724221521756

轉(zhuǎn)換為灰度模式:

im = im.convert("L")
im

png

獲取灰度圖片像素點(diǎn)數(shù)據(jù)的numpy數(shù)組:

data = np.array(im)
data.shape, data.dtype
((300, 300), dtype('uint8'))

調(diào)整像素的梯度值

調(diào)整像素的梯度值間接改變圖像的明暗程度

首先提取出x和y方向的梯度:

grad_x, grad_y = np.gradient(data)
print(grad_x.shape, grad_y.shape)
(300, 300) (300, 300)

深度值的取值范圍為0-100,決定了梯度的縮放比例,現(xiàn)在預(yù)設(shè)深度值為10:

depth = 10
grad_x /= 100/depth
grad_y /= 100/depth

光源效果

根據(jù)灰度變化來模擬人類視覺的遠(yuǎn)近程度

  • 設(shè)計(jì)一個(gè)位于圖像斜上方的虛擬光源
  • 光源相對(duì)于圖像的俯視角為 eLevation,方位角為 Azimuth
  • 建立光源對(duì)個(gè)點(diǎn)梯度值的影響函數(shù)
  • 運(yùn)算出各點(diǎn)的新像素值

]

假設(shè)俯視角eLevation= π 2.2 \frac \pi {2.2} 2.2π?,方位角Azimuth= π 4 \frac \pi {4} 4π?

eLevation = np.pi / 2.2
azimuth = np.pi / 4
# 光源對(duì)x/y/z軸三個(gè)方向的影響程度
dx = np.cos(eLevation) * np.cos(azimuth)
dy = np.cos(eLevation) * np.sin(azimuth)
dz = np.sin(eLevation)

梯度歸一化

構(gòu)造x和y軸梯度的三維歸一化單位坐標(biāo)系:

A = np.sqrt(grad_x ** 2 + grad_y ** 2 + 1.)
uni_x = grad_x / A
uni_y = grad_y / A
uni_z = 1. / A

梯度與光源相互作用,將梯度轉(zhuǎn)化為灰度:

b = 255 * (dx * uni_x + dy * uni_y + dz * uni_z)

最終看看轉(zhuǎn)換效果:

Image.fromarray(b.clip(0, 255).astype('uint8'))

代碼封裝

from PIL import Image
import numpy as np
from PIL.ImageFile import ImageFile
from typing import Union


def img2sketch(img: Union[str, ImageFile], depth=10, eLevation=np.pi / 2.2, azimuth=np.pi / 4):
    assert isinstance(img, str) or isinstance(img, ImageFile)
    assert 0 < depth <= 100
    if isinstance(img, str):
        im = Image.open(img)
    else:
        im = img
    data = np.array(im.convert("L"))
    grad_x, grad_y = np.gradient(data)

    # 根據(jù)深度縮放梯度
    grad_x /= 100/depth
    grad_y /= 100/depth

    # 光源對(duì)x/y/z軸三個(gè)方向的影響程度
    dx = np.cos(eLevation) * np.cos(azimuth)
    dy = np.cos(eLevation) * np.sin(azimuth)
    dz = np.sin(eLevation)

    # 構(gòu)造x和y軸梯度的三維歸一化單位坐標(biāo)系
    A = np.sqrt(grad_x ** 2 + grad_y ** 2 + 1.)
    uni_x = grad_x / A
    uni_y = grad_y / A
    uni_z = 1. / A

    # 梯度與光源相互作用,將梯度轉(zhuǎn)化為灰度
    b = 255 * (dx * uni_x + dy * uni_y + dz * uni_z)

    return Image.fromarray(b.clip(0, 255).astype('uint8'))

調(diào)整一下深度和光源方向測(cè)試一下:

img2sketch('001.jpg', 5, azimuth=-5/4*np.pi)

圖像處理中的三個(gè)基本操作

反相:

對(duì)于三通道的RGB圖片:

t = [255, 255, 255] - data    # 計(jì)算RGB三個(gè)通道的補(bǔ)值
Image.fromarray(t.astype('uint8')) 

對(duì)于單通道的灰度圖片:

t = 255 - data
Image.fromarray(t.astype('uint8')) 

區(qū)間變換(灰度圖像):

t = (100 / 255) * data + 150   # 區(qū)間變換
Image.fromarray(t.astype('uint8'))

像素取平方(灰度圖像):

t = 255 * (data / 255) ** 2    # 像素平方
Image.fromarray(e.astype('uint8'))

    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    中文字幕精品少妇人妻| 欧美字幕一区二区三区| 国产一区二区三区四区中文| 国内精品美女福利av在线| 日韩成人动作片在线观看| 偷拍洗澡一区二区三区| 色综合久久中文综合网| 久久精品蜜桃一区二区av| 美女黄色三级深夜福利| 欧洲一区二区三区自拍天堂| 人妻一区二区三区多毛女| 日韩一区二区三区观看| 国产三级不卡在线观看视频| 国内精品一区二区欧美| 四季精品人妻av一区二区三区| 日本高清二区视频久二区| 国产精品免费视频专区| 加勒比日本欧美在线观看| 女人精品内射国产99| 精品一区二区三区人妻视频| 国产精品偷拍视频一区| 国产人妻熟女高跟丝袜| 日本女人亚洲国产性高潮视频| 97精品人妻一区二区三区麻豆| 视频在线播放你懂的一区| 黄片在线观看一区二区三区| 高清一区二区三区大伊香蕉| 91天堂免费在线观看| 免费亚洲黄色在线观看| 日韩成人动作片在线观看| 午夜精品久久久99热连载| 国产欧美一区二区三区精品视| 日韩免费av一区二区三区| 久久99一本色道亚洲精品| 日本不卡在线视频你懂的| 又黄又爽禁片视频在线观看| 国产精品成人免费精品自在线观看| 国产毛片不卡视频在线| 91欧美日韩精品在线| 粉嫩国产美女国产av| 免费特黄欧美亚洲黄片|