LoginSignup
2
3

More than 5 years have passed since last update.

Leaf Classificationで良精度を出すまで_2日目

Posted at

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]はこれ。

スクリーンショット 2017-07-11 8.17.46.png

横に細長い形であることがわかります。

一つ目。(100,100)に比率はあまり考えず直す方法です。

前処理1.py
plt.imshow(cv2.resize(images[1], (100, 100)), "gray")
plt.show()

new_image.jpg

やはり、細長いという特徴が消えてしまっているので、よくなさそうです。

では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")

スクリーンショット 2017-07-11 8.24.55.png

どうやら成功しました。

ちなみに、一部を変えて、

前処理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))

とすることでも同じ画像が得られます。
こちらでは先に

new_image2.jpg
こういう画像(attempt_image)を作ってから、並行移動することで真ん中に引き上げています。

これを全てに適用して、前処理は終わりです。

他にも、100x100のnumpyのarrayを0で埋めたものを作ってからそこに$100×K(k≤100)$にスケールを変えた画像をおくという方法でもできるなーとか思います。

実装編はまた長くなりそうなので一回分けることにします。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3