====== numpy ======
==== 裏技 ====
=== 座標を得る ===
画像は高さ方向下向きに''H''で幅方向右向きに''W''と決まっている.
画像は''(H,W,C)''の形である.
コンピューターで使われる二次元座標はほとんどの場合右方向に''X'',下方向に''Y''となっている.
つまり画像中の座標は''(Y,X)''となっているのだ.
画像中の座標が求まると座標を利用した画像処理ができて便利.
''(H,W,2_xy)''の形の座標を作ってみよう.
H,W = Y,X = 5,7
grid = np.mgrid[:H,:W].transpose(1,2,0)[:,:,::-1]
grid = np.mgrid[:Y,:X].transpose(1,2,0)[:,:,::-1]
grid = np.stack(np.mgrid[:H,:W][::-1],-1)
grid = np.mgrid[:H,:W][::-1].transpose(1,2,0)
grid = np.mgrid[:W,:H].T
これをつかって画像中心からの距離を利用してグラデーションのかかった点を描画してみる
import numpy as np
from PIL import Image
H,W = 300,400
grid = np.c_[tuple(m[:,:,np.newaxis] for m in np.mgrid[:H,:W][::-1])]
window = 3
x,y = grid[:,:,0], grid[:,:,1]
x = x/W*window - (window/2)
y = y/H*window - (window/2)
v = np.e**(-(x**2+y**2))[:,:,np.newaxis] * 255
img = np.c_[v,v,v].astype(np.uint8)
Image.fromarray(img)
この場合,2x2行列での座標変換は
transformed = (np.array([[1,2],[3,4]]) @ grid.reshape(-1,2).T).T.reshape(grid.shape)
とやるのが良さそう.
=== 同次座標 ===
(N,2)のndarrayを同次座標に変えて戻す
harr = np.c_[arr,np.ones((arr.shape[0],1))]
arr = harr[:,:-1]
=== サンプリングを利用した画像変形 ===
H,W,C = Y,X,_ = img.shape
grid = np.mgrid[:H,:W].transpose(1,2,0)[:,:,::-1]
smp_x = grid[:,:,0].astype(np.int64).flatten()
smp_y = grid[:,:,1].astype(np.int64).flatten()
out = img[smp_y,smp_x,:].reshape(H,W,C)
=== int から one hot へ ===
==== 変形 ====
''np.r_''はaxis=0でのconcatenate.\\
''np.c_''はaxis=-1でのconcatenate.(要検証)
dtypeは常に意識するのが良い.
==== in-place ====
numpyやpytorchのin-placeな関数とは
破壊的代入をおこなう関数.copy()などで防げる.
==== 代入 ====
以下は同じ,式が使えない内包表記ではメソッドが便利
canvas[A==B] = hoge
canvas.place(A==B,hoge)
1チャンネル画像を3チャンネルにしたいときの書き方
# 持っている : alpha (H,W)
# 欲しい : img (H,W,C)
#通常
hoge = alpha[:,:,None]
img = np.c_[hoge,hoge,hoge]
#broadcast
img = np.zeros((1,1,3),dtype=alpha.dtype)+alpha[...,None]
#or
img = np.array([[[0,0,0]]],dtype=alpha.dtype)+alpha[...,None]
#内包
img = [np.c_[a,a,a] for a in [alpha[:,:,None]] ][-1]
#method
img = alpha[:,:,None].repeat(3,axis=2)
==== linalg ====
linear algebra (線形代数) パッケージ.
=== linalg.solve(A,B) ===
$AX=B$の$X$を返す.
=== 型変換 ===
''.astype()''でfloatからintへ変換すると,四捨五入ではなく小数点以下切り捨てとなる.
==== print関数の挙動を変更 ====
''numpy.set_printoptions()'' を使えば良い
* [[https://python.atelierkobato.com/print_option/|NumPy 表示形式の設定]]