1.1. 項目簡介
所謂圖像風格遷移,是利用深度學習技術,將一幅風格圖像輸人卷積神經網絡提取風格特徵,再將其應用到另一幅內容圖像上,從而生成一幅與風格囝像相仿的新圖像。如果選取繪畫大師的作品作爲風格囝像,那麼生成的新圖像就像是模仿大師風格創作的,讓人歎爲觀止。
(圖片來自網絡)
上圖中,圖A是原始圖像,其他5張圖像都是利用“圖像風格遷移”的AI技術生成的繪畫作品,每張圖像的左下角是用來改變原始圖像的風格圖像。
在本節將介紹利用已經訓練好的網絡模型對靜態圖像進行風格遷移。
1.2. 準備工作
在磁盤上創建一個名爲“painter“的文件夾作爲項目目錄,用於存放本項目的圖像、模型和源文件等,然後從原書的“資源包/第 35 課/”文件夾中把 models 和 images 兩個文件夾複製到“painter”文件夾中。models 文件夾中提供了一些己經訓練好的風格遷移網絡模型 ,images 文件夾中提供了一些用於測試的圖像文件 。
你也可以準備一些自己喜歡的照片放到 images 文件夾中,用於圖像風格遷移。
1.3. 圖像風格遷移
新建一個空白源文件,以Style_transfer.jl 作爲文件名保存到“painter”文件夾中 ,然後編寫程序實現圖像風格遷移,由於程序比較簡單,具體過程不做贅述,貼出python代碼和julia代碼,大家可以做個比較。
Python代碼:
1 ''' 2 程序:圖像風格遷移 3 作者:蘇秦@小海豚科學館公衆號 4 來源:圖書《Python趣味編程:從入門到人工智能》 5 ''' 6 import cv2 7 8 #指定圖像和模型路徑 9 image_file = 'image01.jpg' 10 model = 'starry_night.t7' 11 12 #加載風格遷移模型 13 net = cv2.dnn.readNetFromTorch('models/' + model) 14 15 #從文件中讀取圖像 16 image = cv2.imread('images/' + image_file) 17 (h, w) = image.shape[:2] 18 blob = cv2.dnn.blobFromImage(image, 1.0, (w, h), 19 (103.939, 116.779, 123.680), swapRB=False, crop=False) 20 21 #將圖像傳入風格遷移網絡,並對返回結果進行計算 22 net.setInput(blob) 23 out = net.forward() 24 #print(out.shape) 25 #print(out[0]) 26 #修正輸出張量,加上平均減法,然後交換通道排序。 27 out = out.reshape(3, out.shape[2], out.shape[3]) 28 out[0] += 103.939 29 out[1] += 116.779 30 out[2] += 123.68 31 out /= 255 32 out = out.transpose(1, 2, 0) 33 34 #顯示圖像到窗口,並保存圖像 35 #cv2.namedWindow('Image', cv2.WINDOW_NORMAL) 36 cv2.imshow('Image', out) 37 out *= 255.0 38 cv2.imwrite('output-' + model + '_' + image_file, out) 39 cv2.waitKey(0) 40 cv2.destroyAllWindows()
Julia代碼:
1 using PyCall 2 cv2=pyimport("cv2") 3 4 #指定圖像和模型路徑 5 image_file = "image01.jpg" 6 model = "starry_night.t7" 7 8 #加載風格遷移模型 9 net = cv2.dnn.readNetFromTorch("models/" * model) 10 11 #從文件中讀取圖像 12 image = cv2.imread("images/" * image_file) 13 (h, w) =size(image)[1:2] 14 blob = cv2.dnn.blobFromImage(image, 1.0, (w, h), 15 (103.939, 116.779, 123.680), swapRB=false, crop=false) 16 17 #將圖像傳入風格遷移網絡,並對返回結果進行計算 18 net.setInput(blob) 19 out = net.forward() 20 #修正輸出張量,加上平均減法,然後交換通道排序。 21 out =reshape(out,(3,size(out,3),size(out,4))) 22 out[:,:,1].+=103.939 23 out[:,:,2].+=116.779 24 out[:,:,3].+=123.68 25 out /= 255 26 out = permutedims(out,(2, 3, 1)) 27 28 #顯示圖像到窗口,並保存圖像 29 #cv2.namedWindow("Image", cv2.WINDOW_NORMAL) 30 cv2.imshow("Image", out) 31 out *= 255.0 32 println("output-" * model * "_" * image_file) 33 cv2.imwrite("output-" * model * "_" * image_file, out) 34 cv2.waitKey(0) 35 cv2.destroyAllWindows()
不過julia生成的圖像和python生成的圖像有差異,不知什麼原因。
這是julia生成的圖像:
這是pythn生成的圖像:
希望有高手能看看問題出在哪裏。
使用不同的風格遷移網絡模型,可以生成不同風格的圖像。在原書“資源包/第 35 課/models”文件夾中提供了9種已經訓練好的風格遷移網絡模型,大家可以選擇不同的模型進行圖像風格遷。