tensorflowのtutorialをやっておりまして、やっと理解しかけたので今回はtensorflowを使ってLeafClassificationをしようと思います。
ちなみに、前回英語論文でなんとなく理解した192個の特徴量は使わず990枚の画像の99クラス分類問題として扱っています。
前処理にはOpenCVを使用しました。
画像前処理
まずは読み込み
読み込み.py
import cv2
import matplotlib.pyplot as plt
images = []
for i in range(1,1585):
image = cv2.imread("images/%d.jpg"%i)
grayed = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
images.append(grayed)
まずは同フォルダ内にある「image」フォルダからそれぞれの画像についてグレースケール化を行いつつ読み込み、imagesというリストの中に格納していきます。
次に、前回の記事の前処理を試していきます。
imagesの中の一つ目は元々ほぼ正方形なので、ここではimages[1]について見ていきます。ちなみにimages[1]はこれ。
横に細長い形であることがわかります。
一つ目。(100,100)に比率はあまり考えず直す方法です。
前処理1.py
plt.imshow(cv2.resize(images[1], (100, 100)), "gray")
plt.show()
やはり、細長いという特徴が消えてしまっているので、よくなさそうです。
では2つ目。比率を保ちながら最終的に正方形にします。
前処理2.py
end_size = 100 #最終的な縦横サイズ
max_ = np.maximum(images[1].shape[0], images[1].shape[1]) #縦横のうち、大きな方をmax_という変数に代入。
scale = end_size / max_
height, width = images[1].shape
size = (int(width*scale), int(height*scale)) #scaleを保ったまま大きな方を100に合わせる。
rescale_image = cv2.resize(images[1], size, interpolation=cv2.INTER_CUBIC) #リサイズを行う。
height, width = rescale_image.shape #その後、もう一度とりなおします。
#幅の方が大きければ、[(幅ー高さ)/2,幅]の0行列を作り、上下に足す処理です。
#こうすることで画像が真ん中に保たれます。
if width > height:
z_pad = np.zeros([int((width-height)/2), width], dtype=np.uint8)
end_image = np.vstack((z_pad, rescale_image, z_pad))
else:
z_pad = np.zeros([height, int((height - width)/2)], dtype=np.uint8)
end_image = np.hstack((z_pad, rescale_image, z_pad))
#幅ー高さの値が奇数の場合、99となってしまうので100にリサイズしています。
end_image = cv2.resize(end_image, (100, 100))
print(end_image.shape)
plt.imshow(end_image, "gray")
どうやら成功しました。
ちなみに、一部を変えて、
前処理2_2.py
if width > height:
z_pad = np.zeros([width-height, width], dtype=np.uint8)
attempt_image = np.vstack((z_pad, rescale_image))
M = np.float32([[1,0,0],[0,1,-(width-height)/2]])
end_image = cv2.warpAffine(attempt_image, M,(end_size,end_size))
else:
z_pad = np.zeros([height, height - width], dtype=np.uint8)
attempt_image = np.hstack((z_pad, rescale_image))
M = np.float32([[1,0,-(height-width)/2],[0,1,0]])
end_image = cv2.warpAffine(attempt_image, M,(end_size,end_size))
とすることでも同じ画像が得られます。
こちらでは先に
こういう画像(attempt_image)を作ってから、並行移動することで真ん中に引き上げています。
これを全てに適用して、前処理は終わりです。
他にも、100x100のnumpyのarrayを0で埋めたものを作ってからそこに$100×K(k≤100)$にスケールを変えた画像をおくという方法でもできるなーとか思います。
実装編はまた長くなりそうなので一回分けることにします。