よちよちpython

独習 python/Qpython/Pydroid3/termux/Linux

【Numpy】2次元配列の3次元結合と画像生成、配列の拡大実験

前回前々回に続き、配列の変形や結合と画像生成を実験します。

Excelで作ったこれをPandasで読んでNumpyでゴニョゴニョ操作

f:id:chayarokurokuro:20200912131903j:plain
エクセル

水色になっているのは選択中だからです。
選択した状態で「関数の入力」窓に数値を入力し、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'))

f:id:chayarokurokuro:20200912132051j:plain



細身なので幅と高さも増やす(配列を拡大)


上の人が細身かつ画像が小さいので拡大したい。
高さを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'))

f:id:chayarokurokuro:20200912132222j:plain

このようにしなくとも、もっと簡単な方法でできる。次。

配列の拡大のもっと簡単な方法


元の配列.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などにしても空の配列になる。


今回は以上です。