520,用Python訂製你的《本草綱目女孩》
摘要:讓我們來用Python訂製出心儀的「本草綱目女孩」,敲出魔性的程式碼舞蹈,520,準備好心儀女孩的舞蹈影片,把這份別出心裁的禮物給TA
本文分享自華為雲社區《【雲駐共創】華為雲AI之用Python訂製我的《本草綱目女孩》》,作者:愚公搬程式碼。
前言
近日,《本草綱目》毽子操的影片刷屏網路。公司里更是多了很多劉畊宏女孩,在520到來之際特意奉獻這篇文章給大家。如果有心儀的女孩這篇文章可以幫助你哦。
歌詞:抬腿!拍腿!,側邊的肥肉咔咔掉,人魚線馬甲線我都要!劉畊宏的男孩女孩看過來。
讓我們來用Python訂製出心儀的「本草綱目女孩」,敲出魔性的程式碼舞蹈,520,準備好心儀女孩的舞蹈影片,把這份別出心裁的禮物給TA❤️。
一、華為雲ModelArts-Notebook介紹
1.華為雲ModelArts-Notebook
ModelArts集成了基於開源的Jupyter Notebook和JupyterLab,可為您提供在線的互動式開發調試工具。您無需關注安裝配置,在ModelArts管理控制台直接使用Notebook,編寫和調測模型訓練程式碼,然後基於該程式碼進行模型的訓練。
其中,ModelArts還提供了華為自研的分散式訓練加速框架MoXing,您可以在Notebook中使用MoXing編寫訓練腳本,讓您程式碼編寫更加高效、程式碼更加簡潔。
1.1 Jupyter Notebook是什麼
Jupyter Notebook是一個可以在瀏覽器中使用的互動式的計算應用程式,該應用程式的所有可見的內容,以筆記型電腦文檔表示,包括計算的輸入和輸出、解釋文本、數學、影像和對象的富媒體等表示。因此,Jupyter Notebook可以實現將程式碼、文字完美結合起來,非常適合從事機器學習、數據分析等數據科學工作的人員。
Jupyter Notebook相關文檔://docs.jupyter.org/en/latest/
1.2 JupyterLab是什麼
JupyterLab是一個互動式的開發環境,是Jupyter Notebook的下一代產品,可以使用它編寫Notebook、操作終端、編輯MarkDown文本、打開交互模式、查看csv文件及圖片等功能。
JupyterLab相關文檔://jupyterlab.readthedocs.io/en/stable/
1.3 什麼是Moxing
MoXing是華為雲ModelArts團隊自研的分散式訓練加速框架,它構建於開源的深度學習引擎TensorFlow、MXNet、PyTorch、Keras之上。相對於TensorFlow和MXNet原生API而言,MoXing API讓模型程式碼的編寫更加簡單,允許用戶只需要關心數據輸入(input_fn)和模型構建(model_fn)的程式碼,即可實現任意模型在多GPU和分散式下的高性能運行,降低了TensorFlow和MXNet的使用門檻。另外,MoXing-TensorFlow還將支援自動超參選擇和自動模型結構搜索,用戶無需關心超參和模型結構,做到模型全自動學習。
Moxing相關文檔://github.com/huaweicloud/ModelArts-Lab/tree/master/docs/moxing_api_doc
2.Python-Opencv
Python由荷蘭數學和電腦科學研究學會的吉多·范羅蘇姆於1990年代初設計,作為一門叫做ABC語言的替代品。Python提供了高效的高級數據結構,還能簡單有效地面向對象編程。Python語法和動態類型,以及解釋型語言的本質,使它成為多數平台上寫腳本和快速開發應用的程式語言,隨著版本的不斷更新和語言新功能的添加,逐漸被用於獨立的、大型項目的開發。
Python解釋器易於擴展,可以使用C語言或C++(或者其他可以通過C調用的語言)擴展新的功能和數據類型。Python也可用於可訂製化軟體中的擴展程式語言。Python豐富的標準庫,提供了適用於各個主要系統平台的源碼或機器碼。
OpenCV用C++語言編寫,它具有C++,Python,Java和MATLAB介面,並支援Windows,Linux,Android和Mac OS,OpenCV主要傾向於實時視覺應用,並在可用時利用MMX和SSE指令,如今也提供對於C#、Ch、Ruby,GO的支援。
opencv-python的github網址://pypi.org/project/opencv-python/
OpenCV官網://opencv.org/
二、本地案例實現Python訂製我的《本草綱目女孩》
1.案例實現流程
眾所周知,影片是由一幀幀影像構成,Opencv處理影片影像資訊的原理就是將影片轉為一幀幀影像,處理完影像後再轉換為影片。
用Python實現案例流程如下:
2.案例環境部署
2.1 本機環境
- vs2022
- anaconda(已經包括opencv和PIL)
- python
2.2 安裝對應的anaconda包
anaconda這是一個非常常用的python包集成管理工具,其中預安裝了很多python庫,使得我們不需要去手動安裝各種的第三方庫,我們知道自己取手動安裝的過程中,很容易就會遇到一些報錯,解決起來也非常的麻煩。
anaconda官網://www.anaconda.com/products/distribution#Downloads
下載完軟體包一路點擊安裝就行了,安裝成功後會出現如下介面。
查看是否安裝成功命令:conda --version
2.3 安裝opencv-python
進入anaconda控制台輸入如下命令:
pip install opencv-python
3.案例實現程式碼
本案例的實現過程主要分為以下幾步:
1. 導入數據 2. 導入庫函數 3. 將影片轉化為影像幀 4. 對圖片幀進行ASCII碼的轉換 5. 將轉換好的圖片幀合成影片
3.1 導入數據
3.2 導入庫函數
#導入Python庫 import cv2 from PIL import Image,ImageFont,ImageDraw import os from cv2 import VideoWriter, VideoWriter_fourcc, imread, resize
3.3 將影片轉化為影像幀
#將影片轉換為圖片存入目標文件夾 def video_to_pic(vp): number = 0 # 判斷載入的影片是否可以打開 if vp.isOpened(): #r:布爾型 (True 或者False),代表有沒有讀取到圖片,frame:表示截取到的一幀的圖片的數據,是個三維數組 r,frame = vp.read() #判斷文件夾是否存在,不存在的話則新建文件夾 if not os.path.exists('cache_pic'): os.mkdir('cache_pic') os.chdir('cache_pic') else: r = False #遍歷影片,並將每一幀圖片寫入文件夾 while r: number += 1 cv2.imwrite(str(number)+'.jpg',frame) r,frame = vp.read() print('\n由影片一共生成了{}張圖片!'.format(number)) # 修改當前工作目錄至主目錄 os.chdir("..") return number
3.4 對圖片幀進行ASCII碼的轉換
#將圖片進行批量化處理 def star_to_char(number, save_pic_path): #判斷文件夾是否存在,不存在的話則新建文件夾 if not os.path.exists('cache_char'): os.mkdir('cache_char') # 生成目標圖片文件的路徑列表 img_path_list = [save_pic_path + r'/{}.jpg'.format(i) for i in range(1, number + 1)] task = 0 for image_path in img_path_list: # 獲取圖片的解析度 img_width, img_height = Image.open(image_path).size task += 1 #處理圖片,並顯示處理進程 img_to_char(image_path, img_width, img_height, task) print('{}/{} is processed.'.format(task, number)) print('=======================') print('All pictures were processed!') print('=======================') return 0 # 將圖片轉換為灰度影像後進行ascii_char中的ASCII值輸出 # 函數輸入像素RGBA值,輸出對應的字元碼。其原理是將字元均勻地分布在整個灰度範圍內,像素灰度值落在哪個區間就對應哪個字元碼。 def get_char(r, g, b, alpha=256): #ascii_char就是字元列表,用來將不同灰度的像素進行不同字元體替換的參照。 ascii_char = list("#RMNHQODBWGPZ*@$C&98?32I1>!:-;. ") #alpha在為0的時候便是完全透明的圖片,所以返回空 if alpha == 0: return '' length = len(ascii_char) #轉為灰度圖 #RGBA是代表Red(紅色)、Green(綠色)、Blue(藍色)和Alpha的色彩空間,Alpha通道一般用作不透明度參數 #如果一個像素的alpha通道數值為0%,那它就是完全透明的,而數值為100%則意味著一個完全不透明的像素 gray = int(0.2126 * r + 0.7152 * g + 0.0722 * b) # unit = (256.0 + 1) / len(ascii_char) unit = 256 / len(ascii_char) return ascii_char[int(gray / unit)] def img_to_char(image_path, raw_width, raw_height, task): width = int(raw_width / 6) height = int(raw_height / 15) # 以RGB模式打開 im = Image.open(image_path).convert('RGB') im = im.resize((width, height), Image.NEAREST) txt = '' color = [] #遍歷圖片的每個像素 for i in range(height): for j in range(width): pixel = im.getpixel((j, i)) # 將顏色加入進行索引 color.append((pixel[0], pixel[1], pixel[2])) if len(pixel) == 4: txt += get_char(pixel[0], pixel[1], pixel[2], pixel[3]) else: txt += get_char(pixel[0], pixel[1], pixel[2]) txt += '\n' color.append((255, 255, 255)) im_txt = Image.new("RGB", (raw_width, raw_height), (255, 255, 255)) dr = ImageDraw.Draw(im_txt) font = ImageFont.load_default().font x, y = 0, 0 font_w, font_h = font.getsize(txt[1]) font_h *= 1.37 # 調整字體大小 for i in range(len(txt)): if (txt[i] == '\n'): x += font_h y = -font_w dr.text((y, x), txt[i], fill=color[i]) y += font_w #存儲處理後的圖片至文件夾 os.chdir('cache_char') im_txt.save(str(task) + '.jpg') #直接進入新創建的文件夾將生成的圖片直接存入文件夾中 os.chdir("..") return 0
3.5 將轉換好的圖片幀合成影片
# 進度條顯示 def process_bar(percent, start_str='', end_str='', total_length=0): bar = ''.join("■ " * int(percent * total_length)) + '' bar = '\r' + start_str + bar.ljust(total_length) + ' {:0>4.1f}%|'.format(percent * 100) + end_str print(bar, end='', flush=True) #圖片幀合成影片 def jpg_to_video(char_image_path, FPS): # 設置影片編碼器,這裡使用MP42編碼器 video_fourcc = VideoWriter_fourcc(*"MP42") # 生成目標字元圖片文件的路徑列表 char_img_path_list = [char_image_path + r'/{}.jpg'.format(i) for i in range(1, number + 1)] # 獲取圖片的解析度 char_img_test = Image.open(char_img_path_list[1]).size if not os.path.exists('video'): os.mkdir('video') video_writter = VideoWriter('video/output.avi', video_fourcc, FPS, char_img_test) sum = len(char_img_path_list) count = 0 for image_path in char_img_path_list: img = cv2.imread(image_path) video_writter.write(img) end_str = '100%' count = count + 1 process_bar(count / sum, start_str='', end_str=end_str, total_length=15) video_writter.release() print('\n') print('=======================') print('The video is finished!') print('=======================')
3.6 主函數
if __name__ == "__main__": #初始影片路徑 video_path = 'test_demo0510.mp4' #原始影片轉為圖片的圖片保存路徑 save_pic_path = 'cache_pic' #圖片經處理後的圖片保存路徑 save_charpic_path = 'cache_char' # 讀取影片 vp = cv2.VideoCapture(video_path) # 將影片轉換為圖片 並進行計數,返回總共生成了多少張圖片 number = video_to_pic(vp) # 計算影片幀數 FPS = vp.get(cv2.CAP_PROP_FPS) # 將影像進行字元串處理後 star_to_char(number, save_pic_path) vp.release() # 將圖片合成為影片 jpg_to_video(save_charpic_path, FPS)
3.7 運行結果
運行後一共生成了382張圖片,和影片文件,保存在如下文件夾下。
4.案例播放程式碼
import cv2 from IPython.display import clear_output, Image, display def show_video(video_path, show_text): video = cv2.VideoCapture(video_path) while True: try: clear_output(wait=True) # 讀取影片 ret, frame = video.read() if not ret: break height, width, _ = frame.shape cv2.putText(frame, show_text, (0, 100), cv2.FONT_HERSHEY_TRIPLEX, 3.65, (255, 0, 0), 2) frame = cv2.resize(frame, (int(width / 2), int(height / 2))) _, ret = cv2.imencode('.jpg', frame) display(Image(data=ret)) except KeyboardInterrupt: video.release() #影片循環播放 i=1 while i>0: show_video('video/output.avi',str(i)) i=i+1
三、華為雲AI實現Python訂製我的《本草綱目女孩》
1.基礎配置
“本草綱目”健身操字元串影片操作實例的案例頁面如下://developer.huaweicloud.com/develop/aigallery/Notebook/detail?id=c81526e5-cc88-497f-8a21-41a5632e014e
點擊Run in ModelArts,進入JupyterLab頁面。
配置當前運行環境,切換規格,並選擇免費的就好了。
2.導入數據
選擇下方程式碼,點擊運行。
運行完成後如下:
3.安裝相關依賴
選擇下方程式碼,點擊運行安裝opencv包
pip install opencv_python
4.導入庫函數
#導入Python庫 import cv2 from PIL import Image,ImageFont,ImageDraw import os from cv2 import VideoWriter, VideoWriter_fourcc, imread, resize
5.將影片轉化為影像幀
#將影片轉換為圖片存入目標文件夾 def video_to_pic(vp): number = 0 # 判斷載入的影片是否可以打開 if vp.isOpened(): #r:布爾型 (True 或者False),代表有沒有讀取到圖片,frame:表示截取到的一幀的圖片的數據,是個三維數組 r,frame = vp.read() #判斷文件夾是否存在,不存在的話則新建文件夾 if not os.path.exists('cache_pic'): os.mkdir('cache_pic') os.chdir('cache_pic') else: r = False #遍歷影片,並將每一幀圖片寫入文件夾 while r: number += 1 cv2.imwrite(str(number)+'.jpg',frame) r,frame = vp.read() print('\n由影片一共生成了{}張圖片!'.format(number)) # 修改當前工作目錄至主目錄 os.chdir("..") return number
6.對圖片幀進行ASCII碼的轉換
#將圖片進行批量化處理 def star_to_char(number, save_pic_path): #判斷文件夾是否存在,不存在的話則新建文件夾 if not os.path.exists('cache_char'): os.mkdir('cache_char') # 生成目標圖片文件的路徑列表 img_path_list = [save_pic_path + r'/{}.jpg'.format(i) for i in range(1, number + 1)] task = 0 for image_path in img_path_list: # 獲取圖片的解析度 img_width, img_height = Image.open(image_path).size task += 1 #處理圖片,並顯示處理進程 img_to_char(image_path, img_width, img_height, task) print('{}/{} is processed.'.format(task, number)) print('=======================') print('All pictures were processed!') print('=======================') return 0 # 將圖片轉換為灰度影像後進行ascii_char中的ASCII值輸出 # 函數輸入像素RGBA值,輸出對應的字元碼。其原理是將字元均勻地分布在整個灰度範圍內,像素灰度值落在哪個區間就對應哪個字元碼。 def get_char(r, g, b, alpha=256): #ascii_char就是字元列表,用來將不同灰度的像素進行不同字元體替換的參照。 ascii_char = list("#RMNHQODBWGPZ*@$C&98?32I1>!:-;. ") #alpha在為0的時候便是完全透明的圖片,所以返回空 if alpha == 0: return '' length = len(ascii_char) #轉為灰度圖 #RGBA是代表Red(紅色)、Green(綠色)、Blue(藍色)和Alpha的色彩空間,Alpha通道一般用作不透明度參數 #如果一個像素的alpha通道數值為0%,那它就是完全透明的,而數值為100%則意味著一個完全不透明的像素 gray = int(0.2126 * r + 0.7152 * g + 0.0722 * b) # unit = (256.0 + 1) / len(ascii_char) unit = 256 / len(ascii_char) return ascii_char[int(gray / unit)] def img_to_char(image_path, raw_width, raw_height, task): width = int(raw_width / 6) height = int(raw_height / 15) # 以RGB模式打開 im = Image.open(image_path).convert('RGB') im = im.resize((width, height), Image.NEAREST) txt = '' color = [] #遍歷圖片的每個像素 for i in range(height): for j in range(width): pixel = im.getpixel((j, i)) # 將顏色加入進行索引 color.append((pixel[0], pixel[1], pixel[2])) if len(pixel) == 4: txt += get_char(pixel[0], pixel[1], pixel[2], pixel[3]) else: txt += get_char(pixel[0], pixel[1], pixel[2]) txt += '\n' color.append((255, 255, 255)) im_txt = Image.new("RGB", (raw_width, raw_height), (255, 255, 255)) dr = ImageDraw.Draw(im_txt) font = ImageFont.load_default().font x, y = 0, 0 font_w, font_h = font.getsize(txt[1]) font_h *= 1.37 # 調整字體大小 for i in range(len(txt)): if (txt[i] == '\n'): x += font_h y = -font_w dr.text((y, x), txt[i], fill=color[i]) y += font_w #存儲處理後的圖片至文件夾 os.chdir('cache_char') im_txt.save(str(task) + '.jpg') #直接進入新創建的文件夾將生成的圖片直接存入文件夾中 os.chdir("..") return 0
7.將轉換好的圖片幀合成影片
# 進度條顯示 def process_bar(percent, start_str='', end_str='', total_length=0): bar = ''.join("■ " * int(percent * total_length)) + '' bar = '\r' + start_str + bar.ljust(total_length) + ' {:0>4.1f}%|'.format(percent * 100) + end_str print(bar, end='', flush=True) #圖片幀合成影片 def jpg_to_video(char_image_path, FPS): # 設置影片編碼器,這裡使用MP42編碼器 video_fourcc = VideoWriter_fourcc(*"MP42") # 生成目標字元圖片文件的路徑列表 char_img_path_list = [char_image_path + r'/{}.jpg'.format(i) for i in range(1, number + 1)] # 獲取圖片的解析度 char_img_test = Image.open(char_img_path_list[1]).size if not os.path.exists('video'): os.mkdir('video') video_writter = VideoWriter('video/output.avi', video_fourcc, FPS, char_img_test) sum = len(char_img_path_list) count = 0 for image_path in char_img_path_list: img = cv2.imread(image_path) video_writter.write(img) end_str = '100%' count = count + 1 process_bar(count / sum, start_str='', end_str=end_str, total_length=15) video_writter.release() print('\n') print('=======================') print('The video is finished!') print('=======================')
8.運行主函數
if __name__ == "__main__": #初始影片路徑 video_path = 'test_demo0510.mp4' #原始影片轉為圖片的圖片保存路徑 save_pic_path = 'cache_pic' #圖片經處理後的圖片保存路徑 save_charpic_path = 'cache_char' # 讀取影片 vp = cv2.VideoCapture(video_path) # 將影片轉換為圖片 並進行計數,返回總共生成了多少張圖片 number = video_to_pic(vp) # 計算影片幀數 FPS = vp.get(cv2.CAP_PROP_FPS) # 將影像進行字元串處理後 star_to_char(number, save_pic_path) vp.release() # 將圖片合成為影片 jpg_to_video(save_charpic_path, FPS)
等待主函數執行完成,後會生成如下三個文件夾:
9.播放影片
總結
本文主要介紹了本地開發和華為雲ModelArts開發兩種形式,從開發流程中大家也明白那種形式開發更簡單。
ModelArts是面向開發者的一站式AI開發平台,為機器學習與深度學習提供海量數據預處理及半自動化標註、大規模分散式Training、自動化模型生成,及端-邊-雲模型按需部署能力,幫助用戶快速創建和部署模型,管理全周期AI工作流。
華為雲ModelArts-Notebook雲開發的優勢不需要本地進行安裝資源包,在ModelArts-Notebook環境就已經集成了這些環境,減少了人為部署壓力,更易於上手、更高性能、一站式服務、支援多種主流框架。
本文整理自華為雲社區【內容共創】活動第16期。查看活動詳情://bbs.huaweicloud.com/blogs/352652