2025.8.19 画像のリサイズ
画像をサイズをタテヨコ1/4ピクセルに間引く処理を考えた。
アホみたいな原因で悩んでいた。
code:p.py
from sklearn.datasets import fetch_olivetti_faces
import matplotlib.pyplot as plt
import numpy as np
X0, _ = fetch_olivetti_faces(return_X_y=True)
# この時点で X0.shape = (400, 4096)
# 0件目の画像を抽出して表示
img = X00,:.reshape(64, -1)
print(img.shape)
plt.imshow(img)
plt.show()
# 画像の間引き、4096pix(64x64) -> 1024(32x32)にする、つもり
X1 = X0:,::4 # <---(A)
# 0件目を抽出
img = X10,:.reshape(32, -1)
plt.imshow(img)
plt.show()
このとき、元画像
https://scrapbox.io/files/68a430cd825d5bcf26b7c54e.png
に対して、縮小画像が2名分並んでいるように見える
https://scrapbox.io/files/68a430d9f0800da252c562eb.png
結論:
(A)の処理ではヨコ方向に4ステップ間隔で間引きを行っているので、結果として(64, 16)の画像を生成していた。
確認のために表示すると、
code:(続きp.py
# 0件目を抽出(続き)
img = X10,:.reshape(64, -1)
plt.imshow(img)
plt.show()
https://scrapbox.io/files/68a431d153c0f0c7064ce37e.png
だ。タテ・ヨコともに2ステップづつ間引いて(32, 32)ピクセルの画像にするには、ヨコ2・タテともに2ピクセルおきに間引く必要がある。
一般のデータセットはベクトル化された画像が各列に並べられた2D形式で格納されている。
これを3D形式に拡張し、axis=1,2に対してスライスで間引けばよい。
code:p.py
X2 = X0.reshape(400, 64, 64) # 400x4049の2Dを -> 400x64x64の3Dに
X3 = X2:,::2,::2 # axis=1, 2を2ステップで間引き
X3 = X3.reshape(400, 32*32) # 400x32x32の2Dを -> 400x1024の2Dに
img = X30,:.reshape(32, 32) # 0件目を取り出し、32x32の3Dに
plt.imshow(img)
plt.show()
https://scrapbox.io/files/68a55ce4b9ecf0734658d17b.png