<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          用不到20行代碼制作一個(gè) “手繪風(fēng)” 視頻

          共 6329字,需瀏覽 13分鐘

           ·

          2021-04-24 02:22



          ??【當(dāng)當(dāng)書香節(jié)優(yōu)惠碼】??

          200-30 優(yōu)惠碼: NR9EZR 

          300-60 優(yōu)惠碼:HNZVTA 

          有效期:4.12-4.23

          疊加官方滿優(yōu)惠限當(dāng)當(dāng)自營(教輔教材除外)

          當(dāng)當(dāng)小程序、APP 和網(wǎng)站都可使用

          詳細(xì)使用方法見今日推送第二篇文章。



          大家好,歡迎來到 Crossin的編程教室 !

          今天分享的文章與計(jì)算機(jī)視覺相關(guān),用不到 20 行Python代碼將一張實(shí)拍圖片轉(zhuǎn)化為手繪風(fēng),無需對(duì)圖片進(jìn)行任何預(yù)處理、后處理;代碼中只借助了兩個(gè)常見庫,核心計(jì)算由  Numpy 負(fù)責(zé) ,Pillow 負(fù)責(zé)圖片讀寫

          在正文開始之前,先看一下效果,下面是單張圖片轉(zhuǎn)換前后對(duì)比

          圖一

          圖二

          圖三

          為了增加趣味性,再將這段代碼應(yīng)用到一個(gè)視頻中,新鮮的 “手繪風(fēng)視頻” 出爐

          “手繪風(fēng)”實(shí)現(xiàn)步驟

          講解之前,需要了解手繪圖像的三個(gè)主要特點(diǎn):

          • 圖片需為灰度圖,是單通道的;
          • 邊緣部分線條較重涂抹為黑色,相同或相近像素值轉(zhuǎn)換后趨于白色;
          • 在光源效果的加持下,灰度變化可模擬人類視覺的遠(yuǎn)近效果

          讀取圖片,轉(zhuǎn)化為數(shù)組

          因?yàn)楹竺嬉玫较袼赜?jì)算,為了方便,事先將讀取后的圖片轉(zhuǎn)化為數(shù)組

          a = np.asarray(Image.open("Annie1.jpg").convert('L')).astype('float')

          計(jì)算 x,y,z 軸梯度值,并歸一化

          剛才提到手繪照片的一個(gè)特點(diǎn),就是 手繪照片對(duì)邊緣區(qū)域更加側(cè)重,定位圖片邊緣部分,最有效方式就是計(jì)算梯度,用灰度變化來模擬圖片遠(yuǎn)近效果,depth 表示預(yù)設(shè)深度,z 軸默認(rèn)梯度為 1

          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.

          對(duì)梯度值完成歸一化操作

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

          加入光源效果

          手繪風(fēng)圖片除了計(jì)算梯度值之外,還需要考慮光源影響。光源入射的角度不同會(huì)對(duì) x,y,z 各軸上的梯度值有不同程度的影響。添加一個(gè)模擬光源,放置在斜上方,與 x , y 分別形成兩個(gè)夾角

          并且這兩個(gè)夾角是通過實(shí)驗(yàn)得到是已知的,然后根據(jù)正弦余弦函數(shù)計(jì)算出最終新的像素值

          vec_el = np.pi / 2.2  # 光源的俯視角度,弧度值
          vec_az = np.pi / 4.  # 光源的方位角度,弧度值
          dx = np.cos(vec_el) * np.cos(vec_az)  # 光源對(duì) x軸的影響
          dy = np.cos(vec_el) * np.sin(vec_az)  # 光源對(duì) y軸的影響
          dz = np.sin(vec_el)  # 光源對(duì)z 軸的影響

          b = 255 * (dx * uni_x + dy * uni_y + dz * uni_z)  # 光源歸一化,8 255
          b = b.clip(0, 255)# 對(duì)像素值低于0,高于255部分做截?cái)嗵幚?/span>

          導(dǎo)出圖片,并保存

          im.save("Annie_shouhui.jpg")

          以下是該步驟涉及到的的全部代碼

          from PIL import Image
          import numpy as np


          a = np.asarray(Image.open("Annie1.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)  # 光源對(duì) x軸的影響
          dy = np.cos(vec_el) * np.sin(vec_az)  # 光源對(duì) y軸的影響
          dz = np.sin(vec_el)  # 光源對(duì)z 軸的影響

          b = 255 * (dx * uni_x + dy * uni_y + dz * uni_z)  # 光源歸一化
          b = b.clip(0, 255)

          im = Image.fromarray(b.astype('uint8'))  # 重構(gòu)圖像
          im.save("Annie_shouhui.jpg")

          制作手繪風(fēng)視頻

          圖片轉(zhuǎn)化后的效果雖然也不錯(cuò),但圖片畢竟是靜態(tài)的,人作為視覺動(dòng)物,如果能做成動(dòng)態(tài)的那再好不過了,知道上面的方法之后,只需對(duì)視頻再加上一個(gè)拆幀合并操作,就能制作一個(gè)手繪風(fēng)視頻效果。

          首先我們需要一個(gè)待轉(zhuǎn)換的視頻文件。這里我用 you-get 工具在 B 站上找了一個(gè)視頻,下載了下來

          you-get --format=dash-flv -o ./ https://www.bilibili.com/video/BV1tT4y1j7a9?from=search&8014393453748720686

          下載完之后,用 OpenCV2 對(duì)視頻進(jìn)行切幀操作,將視頻轉(zhuǎn)為一張張圖片,同時(shí)對(duì)圖片進(jìn)行手繪風(fēng)格轉(zhuǎn)化,再寫出到本地視頻文件中

           vc = cv2.VideoCapture(video_path)
              c = 0
              if vc.isOpened():
                  rval,frame = vc.read()
                  height,width = frame.shape[0],frame.shape[1]
                  print(height, width)
              else:
                  rval = False
                  height,width = 960,1200

              # jpg_list = [os.path.join('Pic_Directory/',i) for i in os.listdir('Pic_Directory') if i.endswith('.jpg')]

              fps = 24 # 視頻幀率
              video_path1 = './text.mp4'
              video_writer = cv2.VideoWriter(video_path1,cv2.VideoWriter_fourcc(*'mp4v'),fps,(width,height))

              while rval:
                  rval,frame = vc.read()# 讀取視頻幀
                  img = coonvert_jpg(Image.fromarray(frame))
                  frame_converted = np.array(img)

                  # 轉(zhuǎn)化為三通道
                  image = np.expand_dims(frame_converted,axis = 2)
                  result_arr = np.concatenate((image,image,image),axis = -1)

                  video_writer.write(result_arr)
                  print('Sucessfully Conveted---------{}'.format(c))
                  c = c + 1
                  if c >= 3000:
                      break
              video_writer.release()

          在圖片序列提取時(shí),需要注意一點(diǎn),因?yàn)檗D(zhuǎn)化后的圖片是單通道的,直接借助 OpenCV 生成視頻序列是無法播放的,需增加一個(gè)步驟單通道轉(zhuǎn)化為三通道!

           # 轉(zhuǎn)化為三通道
           image = np.expand_dims(frame_converted,axis = 2)
           result_arr = np.concatenate((image,image,image),axis = -1)

          想讓生成的視頻更有感覺的話可以添加一個(gè)背影音樂,借助剪輯軟件、Python 都可以實(shí)現(xiàn)。

          小結(jié)

          本文主要介紹了如何用 Python將一張圖片轉(zhuǎn)化為手繪風(fēng)格,代碼量不多,可以很方便地應(yīng)用。不過背后的原理并不簡單,涉及數(shù)學(xué)、物理相關(guān)的識(shí)點(diǎn)

          文中涉及到的源碼大部分其實(shí)都已經(jīng)貼在文章,但為了方便起見,我已經(jīng)將數(shù)據(jù)和源碼整合在一起,想獲取的同學(xué)可以,請(qǐng)?jiān)诠?hào)后臺(tái)回復(fù)關(guān)鍵字:手繪

          如果文章對(duì)你有幫助,歡迎轉(zhuǎn)發(fā)/點(diǎn)贊/收藏~

          作者:zeroing

          來源:小張Python


          _往期文章推薦_

          Python+OpenCV十幾行代碼模仿世界名畫




          如需了解付費(fèi)精品課程教學(xué)答疑服務(wù)
          請(qǐng)?jiān)?strong style="max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box !important;">Crossin的編程教室內(nèi)回復(fù): 666

          瀏覽 51
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产精品97 | 青草久久茄子视频 | 日本免费A片 | 懂色av懂色av粉嫩av-百度 | 丁香五月天激情 |