1. 程式人生 > >Python實現圖片與陣列的轉化

Python實現圖片與陣列的轉化

作者:石煒賢&曾翔鈺

cifar-10這個資料相信很多接觸過機器學習的人都肯定有所瞭解。今天,我們通過cifar-10儲存將圖片轉化為可訓練資料的思路將我們自己的圖片轉化為Python格式的資料。

本篇文章主要實現兩個功能:
①圖片轉化為陣列並存為二進位制檔案;
②從二進位制檔案中讀取資料並重新恢復為圖片

圖片大小為32*32。現在我們來聊聊步驟:
①圖片轉化為陣列並存為二進位制檔案:
1.使用PIL開啟圖片,並將其分離為RGB三個通道
2.利用numpy分別將RGB三個通道轉化為陣列並將其轉為一維陣列 (32*32->1024)
3.將RGB三個一維陣列(1024)拼接成一個一維陣列(3072),再接入大陣列,最終形成n*3072的一維陣列,最終在reshape成n行3072列的二維陣列
4.使用pickle序列化陣列物件並儲存到檔案裡

②從二進位制檔案中讀取資料並重新恢復為圖片:
1.開啟資料檔案並使用pickle載入並反序列化資料得到陣列
2.使用PIL分別得到每張圖片的RGB通道,然後將其合併
3.使用matplotlib顯示影象
4.儲存影象

來一波程式碼(這裡Python版本為2.7,不過3.x的應該問題也不大):

# encoding:utf-8
"""
關於圖片的一些操作:
①圖片轉化為陣列並存為二進位制檔案;
②從二進位制檔案中讀取資料並重新恢復為圖片
"""

from __future__ import print_function
import numpy as
np import PIL.Image as Image import pickle as p import matplotlib.pyplot as pyplot class Operation(object): image_base_path = "../images/" data_base_path = "../data/" def image_to_array(self, filenames): """ 圖片轉化為陣列並存為二進位制檔案; :param filenames:檔案列表 :return: """
n = filenames.__len__() # 獲取圖片的個數 result = np.array([]) # 建立一個空的一維陣列 print("開始將圖片轉為陣列") for i in range(n): image = Image.open(self.image_base_path + filenames[i]) r, g, b = image.split() # rgb通道分離 # 注意:下面一定要reshpae(1024)使其變為一維陣列,否則拼接的資料會出現錯誤,導致無法恢復圖片 r_arr = np.array(r).reshape(1024) g_arr = np.array(g).reshape(1024) b_arr = np.array(b).reshape(1024) # 行拼接,類似於接火車;最終結果:共n行,一行3072列,為一張圖片的rgb值 image_arr = np.concatenate((r_arr, g_arr, b_arr)) result = np.concatenate((result, image_arr)) result = result.reshape((n, 3072)) # 將一維陣列轉化為count行3072列的二維陣列 print("轉為陣列成功,開始儲存到檔案") file_path = self.data_base_path + "data2.bin" with open(file_path, mode='wb') as f: p.dump(result, f) print("儲存檔案成功") def array_to_image(self, filename): """ 從二進位制檔案中讀取資料並重新恢復為圖片 :param filename: :return: """ with open(self.data_base_path + filename, mode='rb') as f: arr = p.load(f) # 載入並反序列化資料 rows = arr.shape[0] arr = arr.reshape(rows, 3, 32, 32) for index in range(rows): a = arr[index] # 得到RGB通道 r = Image.fromarray(a[0]).convert('L') g = Image.fromarray(a[1]).convert('L') b = Image.fromarray(a[2]).convert('L') image = Image.merge("RGB", (r, g, b)) # 顯示圖片 pyplot.imshow(image) pyplot.show() image.save(self.image_base_path + "result" + str(index) + ".png", 'png') if __name__ == "__main__": my_operator = Operation() images = [] for j in range(5): images.append(str(j) + ".png") my_operator.image_to_array(images) my_operator.array_to_image("data2.bin")