圖像處理與特徵提取 —— 從 MATLAB 到 Python(一)圖像、矩陣與數據的讀寫

最近幾個實驗從 MATLAB 環境轉入到 Python 環境做,踩了幾個小坑,記錄一下。

寫一半發現太長,分開幾篇寫,計劃如下:

  • 圖像、矩陣與數據的讀寫(本篇)
  • 基本圖像處理
  • 特徵提取
  • 分類
  • 距離、度量、評價指標與效果評估,及相關繪圖

主要內容就是介紹 MATLAB 中的各種操作在 Python 中如何實現。中間夾雜一些比較、感想和評論。希望能兩到三天更新一篇。

一、圖像文件的讀寫

MATLAB 中常見的圖像的讀寫使用 imread 和 imwrite 函數。

A = imread(filename, fmt)imwrite(A,filename)

Python 中圖像的讀寫可以使用 scikit-image 包的 io module 中的 imread 和 imsave 函數。

from skimage import ioimg_array = io.imread(fname, as_grey=False, plugin=None, flatten=None, **plugin_args)io.imsave(fname, arr, plugin=None, **plugin_args)

二、CSV 文件的讀寫

MATLAB 中 CSV 文件的讀寫使用 csvwrite 和 csvread 函數。

csvwrite(filename,M)M = csvread(filename)

Python 中 CSV 文件的讀寫,可以使用 numpy 包的 savetxt 和 genfromtxt 函數。

import numpynumpy.savetxt(fname, X, fmt=%.18e, delimiter= , newline=
, header=, footer=, comments=# )numpy.genfromtxt(fname, dtype=<type float>, comments=#, delimiter=None, skip_header=0, skip_footer=0, converters=None, missing_values=None,filling_values=None, usecols=None, names=None, excludelist=None, deletechars=None, replace_space=_, autostrip=False, case_sensitive=True, defaultfmt=f%i, unpack=None, usemask=False, loose=True, invalid_raise=True, max_rows=None)

numpy 有 loadtxt 和 genfromtxt 使用 delimiter=, 都可以讀取 csv 文件,但 genfromtxt 可以處理數據丟失,更穩健。在確保數據完整的時候,也可以用 loadtxt。

三、二維矩陣

這裡有點問題了。MATLAB 中的二維矩陣用 size 描述,先行後列,串列輸出時列優先。Python 中的二維矩陣(數組的數組)的外形(shape)表述是先外後內、從右到左,flatten 默認行優先。

二維矩陣表達

MATLAB 中二維矩陣是這樣的。

>> A = [1 2 3; 4 5 6]A = 1 2 3 4 5 6>> size(A)ans = 2 3>> A(:)ans = 1 4 2 5 3 6

A 是兩行三列的矩陣。size 第一是行,第二是列。用 :串列輸出時,是按照列從左到右首尾相接。size(A(:)) 是 [6 1];ndims(A(:)) 是 2。

Python 的 Numpy 中二維矩陣是這樣的。

A = numpy.array([[1, 2, 3], [4, 5, 6]])print(A)[[1 2 3] [4 5 6]]print(A.shape)(2, 3)print(A.flatten())[1 2 3 4 5 6]print(A.flatten(F))[1 4 2 5 3 6]

A 是兩行三列的矩陣,也是一個數組的數組。底層數組包含三個基本元素,上層數組包含兩個數組。shape 第一是行數,第二是列數。像剝洋蔥一樣,左邊第一個參數是外層,即有多少行,第二個參數是內層,即每行多少像素。用 flatten 串列輸出時,默認是行優先從上到下首尾相接,即撥開外層後按照順序連接內層。如果想同 MATLAB 一樣的,按照列優先串列輸出,可以使用 F 參數。這裡默認 C 參數表示 c-style,即為行優先,『F』 參數表示 fortran-style,即為列優先。但即使列優先輸出,輸出的也是一個數組,即行向量。A.flatten(F).shape 是 (6,);A.flatten(F).ndim 是 1。

從圖像文件中讀寫二維矩陣

MATLAB

>> imwrite(reshape(1:20, [4 5])/255, matrix.png)>> imread(matrix.png)ans = 1 5 9 13 17 2 6 10 14 18 3 7 11 15 19 4 8 12 16 20

Python

from skimage import ioio.imsave(matrix.png, numpy.arange(1,21).reshape((4, 5)))print(io.imread(matrix.png))[[ 1 2 3 4 5] [ 6 7 8 9 10] [11 12 13 14 15] [16 17 18 19 20]]io.imsave(matrix.png, numpy.arange(1,21).reshape((4, 5), order=F))print(io.imread(matrix.png))[[ 1 5 9 13 17] [ 2 6 10 14 18] [ 3 7 11 15 19] [ 4 8 12 16 20]]

這裡也要注意 Python 中 reshape 默認行優先,與 MATLAB 的列優先不同。

從 CSV 文件中讀寫二維矩陣

MATLAB

>> csvwrite(matrix.csv,reshape(1:20, [4 5]))>> csvread(matrix.csv)ans = 1 5 9 13 17 2 6 10 14 18 3 7 11 15 19 4 8 12 16 20

Python

import numpy as npnp.savetxt(matrix.csv, np.arange(1, 21).reshape((4, 5)), delimiter=,)print(np.loadtxt(matrix.csv,delimiter=,,dtype=np.int))[[ 1 2 3 4 5] [ 6 7 8 9 10] [11 12 13 14 15] [16 17 18 19 20]]np.savetxt(matrix.csv, np.arange(1, 21).reshape((4, 5), order=F), delimiter=,)print(np.loadtxt(matrix.csv, delimiter=,, dtype=np.int))[[ 1 5 9 13 17] [ 2 6 10 14 18] [ 3 7 11 15 19] [ 4 8 12 16 20]]

四、高維矩陣存儲

二維矩陣存成圖像或者 csv 還都算方便,高維矩陣就費勁了。

MATLAB 數據存儲,一般直接 MAT 文件格式,常用 save,load。

Python 數據存儲,有多種方法。

讀寫 MAT 文件,可以使用 scipy 包的 io 模塊的 loadmat 和 savemat 函數。

scipy.io.loadmat(file_name, mdict=None, appendmat=True, **kwargs)scipy.io.savemat(file_name, mdict, appendmat=True, format=5, long_field_names=False, do_compression=False, oned_as=row)

Python 原生的數據存儲方法,一般使用 pickle 包,或者 C 實現的速度更快的 cPickle。
推薦閱讀:

The Django Book(最新版) —MVC設計模式
在Python里實現Lazy
Python練習第七題,我要倒過來看
【重讀經典】《Python核心編程(第3版)》
《機器學習實戰》學習總結(五)——Logistic回歸

TAG:MATLAB | Python | 圖像處理 |