【Numpy】2次元配列の3次元結合と画像生成、配列の拡大実験
前回、前々回に続き、配列の変形や結合と画像生成を実験します。
↓ Excelで作ったこれをPandasで読んでNumpyでゴニョゴニョ操作
水色になっているのは選択中だからです。
選択した状態で「関数の入力」窓に数値を入力し、Ctrlを押しながらEnterをすると選択セルの全てに同じ値を入れることができた。
PandasでExcelシートの読込
事前に準備しておいたExcelシートを読み込む。
import pandas as pd import numpy as np import matplotlib.pyplot as plt # Excelファイル fname = "./excel_array_image.xlsx" # Excelブックの読込 df = pd.read_excel(fname, sheet_name=None) # シートの読込 Numpy配列に変換 sheet = pd.read_excel(fname, sheet_name="red").values
シートの配列の形を見る
sheet.shape
(101, 42)
配列の生成と結合、画像表示
Excelで読み取ったシートの配列sheet
を利用し、RGBに相当する2次元配列を合計3つ生成する。
# 行数と列数(配列「sheet」の形状 101,42) row, col = sheet.shape # RGBのR(赤)成分の配列生成 sheetのコピー sheet_red = sheet.copy() # RGBのG(緑)配列生成 全行全列が0~255のランダム値 sheet_green = sheet.copy() sheet_green[:,:]=np.random.randint(0,255, row*col).reshape(row, col) # RGBのB(青)配列生成 sheetのコピー sheet_blue = sheet.copy() # 3つの2次元配列を3次元方向に結合 img_excel_color = np.stack([sheet_red , sheet_green , sheet_blue], axis=2)
RGBのRとBは同じ2次元配列。Gは全要素を0~255の範囲でランダムな整数を入れた。
3次元方向に結合まで済んでいる。
画像として表示、保存。
# matplotlibで画像として表示 plt.imshow(img_excel_color) # 保存 plt.imsave("man.jpg", img_excel_color.astype('uint8'))
細身なので幅と高さも増やす(配列を拡大)
上の人が細身かつ画像が小さいので拡大したい。
高さを2倍 101 ⇒ 202
幅を4倍 42 ⇒ 168
(202, 168)のサイズに拡大する。
考え方としては次のような感じでよかろうか。
- 元の2次元配列をx行1列に変形。
- 同じ列配列を横に結合。
- 行数は同じで列数を二倍にした形状に変形。
まずは横幅を2倍にする。
配列は3つとも0か255が同じ位置に入っているため、白黒画像になる予定。
# 配列の作成 sheet_2 = sheet.copy() sheet_2 = sheet_2.reshape(-1,1) sheet_2 = np.hstack([sheet_2, sheet_2]).reshape(101, 84)
# 配列の結合 wide_2 = np.stack([sheet_2,sheet_2,sheet_2], axis=2) # 表示 plt.imshow(wide_2) # 保存 plt.imsave("wide_2.jpg", wide_2.astype('uint8'))
このようにしなくとも、もっと簡単な方法でできる。次。
配列の拡大のもっと簡単な方法
元の配列.repeat(倍数, axis=軸)
軸は、
- axis=0 縦方向(行 方向)
- axis=1 横方向(列 方向)
# 配列作成 a = np.arange(1,7).reshape(2, 3) a
array([[1, 2, 3],
[4, 5, 6]])
横に2倍拡大
a_1_2 = a.repeat(2, axis=1) a_1_2
array([[1, 1, 2, 2, 3, 3],
[4, 4, 5, 5, 6, 6]])
縦に4倍拡大
a_0_4 = a.repeat(4, axis=0) a_0_4
array([[1, 2, 3],
[1, 2, 3],
[1, 2, 3],
[1, 2, 3],
[4, 5, 6],
[4, 5, 6],
[4, 5, 6],
[4, 5, 6]])
3次元配列の場合は、
s = np.arange(27).reshape(3,3,3) SS = s.repeat(4,axis=2) print("【元の3次元配列】\n", s) print("\n\n【3次元方向に4倍】\n", SS)
【元の3次元配列】
[[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]]
[[ 9 10 11]
[12 13 14]
[15 16 17]]
[[18 19 20]
[21 22 23]
[24 25 26]]]
【3次元方向に4倍】
[[[ 0 0 0 0 1 1 1 1 2 2 2 2]
[ 3 3 3 3 4 4 4 4 5 5 5 5]
[ 6 6 6 6 7 7 7 7 8 8 8 8]]
[[ 9 9 9 9 10 10 10 10 11 11 11 11]
[12 12 12 12 13 13 13 13 14 14 14 14]
[15 15 15 15 16 16 16 16 17 17 17 17]]
[[18 18 18 18 19 19 19 19 20 20 20 20]
[21 21 21 21 22 22 22 22 23 23 23 23]
[24 24 24 24 25 25 25 25 26 26 26 26]]]
縮小はこれでは出来ないっぽい。倍率を0.5などにしても空の配列になる。
今回は以上です。