FlickrAPIで写真をダウンロード
Flickr Services
The safest and most inclusive global community of photography enthusiasts. The best place for inspiration, connection, a...
# Flickrで写真を検索して、ダウンロードする
from flickrapi import FlickrAPI
from urllib.request import urlretrieve
from pprint import pprint
import os, time, sys
# APIキーとシークレットの指定(★以下書き換えてください★)--- (*1)
key = "2dbebf0254c8a93800da42ca5417d0a3"
secret = "d44364b2f329f3dd"
wait_time = 1 # 待機秒数(1以上を推奨)
# キーワードとディレクトリ名を指定してダウンロード --- (*2)
def main():
go_download('マグロ 寿司', 'sushi')
go_download('サラダ', 'salad')
go_download('麻婆豆腐', 'tofu')
# Flickr APIで写真を検索 --- (*3)
def go_download(keyword, dir):
# 画像の保存パスを決定
savedir = "./image/" + dir
if not os.path.exists(savedir):
os.mkdir(savedir)
# APIを使ってダウンロード --- (*4)
flickr = FlickrAPI(key, secret, format='parsed-json')
res = flickr.photos.search(
text = keyword, # 検索語
per_page = 300, # 取得件数
media = 'photos', # 写真を検索
sort = "relevance", # 検索語の関連順に並べる
safe_search = 1, # セーフサーチ
extras = 'url_q, license')
# 検索結果を確認
photos = res['photos']
pprint(photos)
try:
# 1枚ずつ画像をダウンロード --- (*5)
for i, photo in enumerate(photos['photo']):
url_q = photo['url_q']
filepath = savedir + '/' + photo['id'] + '.jpg'
if os.path.exists(filepath): continue
print(str(i + 1) + ":download=", url_q)
urlretrieve(url_q, filepath)
time.sleep(wait_time)
except:
import traceback
traceback.print_exc()
if __name__ == '__main__':
main()
# 画像ファイルを読んでNumpy形式に変換
import numpy as np
from PIL import Image
import os, glob, random
outfile = "image/photos.npz" # 保存ファイル名
max_photo = 100 # 利用する写真の枚数
photo_size = 32 # 画像サイズ
x = [] # 画像データ
y = [] # ラベルデータ
def main():
# 各画像のフォルダを読む --- (*1)
glob_files("./image/sushi", 0)
glob_files("./image/salad", 1)
glob_files("./image/tofu", 2)
# ファイルへ保存 --- (*2)
np.savez(outfile, x=x, y=y)
print("保存しました:" + outfile, len(x))
# path以下の画像を読み込む --- (*3)
def glob_files(path, label):
files = glob.glob(path + "/*.jpg")
random.shuffle(files)
# 各ファイルを処理
num = 0
for f in files:
if num >= max_photo: break
num += 1
# 画像ファイルを読む
img = Image.open(f)
img = img.convert("RGB") # 色空間をRGBに
img = img.resize((photo_size, photo_size)) # サイズ変更
img = np.asarray(img)
x.append(img)
y.append(label)
if __name__ == '__main__':
main()
画像一覧チェック
import numpy as np
import matplotlib.pyplot as plt
# 写真データ読み込み
photos = np.load("image/photos.npz")
x = photos['x']
y = photos['y']
# 開始インデックス
idx = 0
plt.figure(figsize=(10,10))
for i in range(25):
plt.subplot(5,5,i+1)
plt.title(y[i+idx])
plt.imshow(x[i+idx])
plt.show()
CNNでモデルを構築
import keras
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras.optimizers import RMSprop
# CNNのモデルを定義する
def def_model(in_shape, nb_classes):
model = Sequential()
model.add(Conv2D(32,
kernel_size=(3, 3),
activation='relu',
input_shape=in_shape))
model.add(Conv2D(32, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(nb_classes, activation='softmax'))
return model
# コンパイル済みのCNNのモデルを返す
def get_model(in_shape, nb_classes):
model = def_model(in_shape, nb_classes)
model.compile(
loss='categorical_crossentropy',
optimizer=RMSprop(),
metrics=['accuracy'])
return model
CNNで学習
import cnn_model
import keras
import matplotlib.pyplot as plt
import numpy as np
from sklearn.model_selection import train_test_split
# 入力と出力を指定 --- (*1)
im_rows = 32 # 画像の縦ピクセルサイズ
im_cols = 32 # 画像の横ピクセルサイズ
im_color = 3 # 画像の色空間
in_shape = (im_rows, im_cols, im_color)
nb_classes = 3
# 写真データを読み込み --- (*2)
photos = np.load('image/photos.npz')
x = photos['x']
y = photos['y']
# 読み込んだデータをの三次元配列に変換 --- (*3)
x = x.reshape(-1, im_rows, im_cols, im_color)
x = x.astype('float32') / 255
# ラベルデータをone-hotベクトルに直す --- (*4)
y = keras.utils.to_categorical(y.astype('int32'), nb_classes)
# 学習用とテスト用に分ける --- (*5)
x_train, x_test, y_train, y_test = train_test_split(
x, y, train_size=0.8)
# CNNモデルを取得 --- (*6)
model = cnn_model.get_model(in_shape, nb_classes)
# 学習を実行 --- (*7)
hist = model.fit(x_train, y_train,
batch_size=32,
epochs=20,
verbose=1,
validation_data=(x_test, y_test))
# モデルを評価 --- (*8)
score = model.evaluate(x_test, y_test, verbose=1)
print('正解率=', score[1], 'loss=', score[0])
# 学習の様子をグラフへ描画 --- (*9)
# 正解率の推移をプロット
plt.plot(hist.history['accuracy'])
plt.plot(hist.history['val_accuracy'])
plt.title('Accuracy')
plt.legend(['train', 'test'], loc='upper left')
plt.show()
# ロスの推移をプロット
plt.plot(hist.history['loss'])
plt.plot(hist.history['val_loss'])
plt.title('Loss')
plt.legend(['train', 'test'], loc='upper left')
plt.show()
model.save_weights('./image/photos-model-light.weights.h5')
print('ok')
CNNのデータを水ます
import matplotlib.pyplot as plt
import cv2
import numpy as np
# 画像を読み込む
photos = np.load("image/photos.npz")
x =photos['x']
img = x[12]
plt.figure(figsize=(10,10))
for i in range(36):
plt.subplot(6,6, i+1)
#回転を実行
center = (16,16)
angle = i * 5
scale = 10.0
mtx = cv2.getRotationMatrix2D(center, angle, scale)
img2 = cv2.warpAffine(img, mtx, (32,32))
#回転した画像を表示
plt.imshow(img2)
plt.show()
増えたデータで学習
# CNNでMNISTの分類問題に挑戦
import cnn_model
import keras
import matplotlib.pyplot as plt
import numpy as np
from sklearn.model_selection import train_test_split
import cv2
# 入力と出力を指定
im_rows = 32 # 画像の縦ピクセルサイズ
im_cols = 32 # 画像の横ピクセルサイズ
im_color = 3 # 画像の色空間
in_shape = (im_rows, im_cols, im_color)
nb_classes = 3
# 写真データを読み込み
photos = np.load('image/photos.npz')
x = photos['x']
y = photos['y']
# 読み込んだデータをの三次元配列に変換
x = x.reshape(-1, im_rows, im_cols, im_color)
x = x.astype('float32') / 255
# ラベルデータをone-hotベクトルに直す
y = keras.utils.to_categorical(y.astype('int32'), nb_classes)
# 学習用とテスト用に分ける
x_train, x_test, y_train, y_test = train_test_split(
x, y, train_size=0.8)
# 学習用データを水増しする --- (*1)
x_new = []
y_new = []
for i, xi in enumerate(x_train):
yi = y_train[i]
for ang in range(-30, 30, 5):
# 回転させる --- (*2)
center = (16, 16) # 回転の中心点
mtx = cv2.getRotationMatrix2D(center, ang, 1.0)
xi2 = cv2.warpAffine(xi, mtx, (32, 32))
x_new.append(xi2)
y_new.append(yi)
# さらに左右反転させる --- (*3)
xi3 = cv2.flip(xi2, 1)
x_new.append(xi3)
y_new.append(yi)
# 水増しした画像を学習用に置き換える
print('水増し前=', len(y_train))
x_train = np.array(x_new)
y_train = np.array(y_new)
print('水増し後=', len(y_train))
# CNNモデルを取得 --- (*6)
model = cnn_model.get_model(in_shape, nb_classes)
# 学習を実行 --- (*8)
hist = model.fit(x_train, y_train,
batch_size=64,
epochs=20,
verbose=1,
validation_data=(x_test, y_test))
# モデルを評価 --- (*9)
score = model.evaluate(x_test, y_test, verbose=1)
print('正解率=', score[1], 'loss=', score[0])
# 学習の様子をグラフへ描画 --- (*10)
# 正解率の推移をプロット
plt.plot(hist.history['accuracy'])
plt.plot(hist.history['val_accuracy'])
plt.title('Accuracy')
plt.legend(['train', 'test'], loc='upper left')
plt.show()
# ロスの推移をプロット
plt.plot(hist.history['loss'])
plt.plot(hist.history['val_loss'])
plt.title('Loss')
plt.legend(['train', 'test'], loc='upper left')
plt.show()
model.save_weights('./image/photos-model.weights.h5')
手持ち写真で検証
import cnn_model
import keras
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
target_image = "test-sushi.jpg"
im_rows = 32 # 画像の縦ピクセルサイズ
im_cols = 32 # 画像の横ピクセルサイズ
im_color = 3 # 画像の色空間
in_shape = (im_rows, im_cols, im_color)
nb_classes = 3
LABELS = ["寿司", "サラダ", "麻婆豆腐"]
CALORIES = [588, 118, 648]
# 保存したCNNモデルを読み込む
model = cnn_model.get_model(in_shape, nb_classes)
model.load_weights('./image/photos-model.weights.h5')
def check_photo(path):
# 画像を読み込む
img = Image.open(path)
img = img.convert("RGB") # 色空間をRGBに
img = img.resize((im_cols, im_rows)) # サイズ変更
plt.imshow(img)
plt.show()
# データに変換
x = np.asarray(img)
x = x.reshape(-1, im_rows, im_cols, im_color)
x = x / 255
# 予測
pre = model.predict([x])[0]
idx = pre.argmax()
per = int(pre[idx] * 100)
return (idx, per)
def check_photo_str(path):
idx, per = check_photo(path)
# 答えを表示
print("この写真は、", LABELS[idx], "で、カロリーは", CALORIES[idx],"kcal")
print("可能性は、", per, "%")
if __name__ == '__main__':
check_photo_str('test-sushi.jpg')
check_photo_str('test-salad.jpg')
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 103ms/step
この写真は、 寿司 で、カロリーは 588 kcal
可能性は、 100 %
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 18ms/step
この写真は、 サラダ で、カロリーは 118 kcal
可能性は、 99 %