こんにちは,ぱそきいろです.
ぱそきいろ (@takacpu55) | Twitter
今日は深層学習を使って人物認証で遊んだので,そのまとめになります.
具体的には僕が好きなユーチューバーのパオパオチャンネル(ぶんけい,@小豆)の二人を一枚の画像だけを使って分類してみました.
(パオパオチャンネル休止して寂しい)
長くなりそうだったので,今回は画像の前処理に関してのみ書いていきます.
学習に関してはこちらに載せています.
www.takacpu55.xyz
最後にソースコードを載せているので参考にしてください.
よろしくお願いします.
教師データを一枚にした理由
これは一言で言えます.
「教師データを準備するのがめんどくさかったから笑」
一枚づつ画像をダウンロードして,ラベル付けして,,,を何十枚とやる気力が起きません.
Webスクレイピングが出来る人は上手いことやるのでしょうが,そこまで手が回りません.
(いつかはちゃんと勉強しないと,,,)
そこで,二人が映った一枚の画像を使って人物認証をしていきたいと思います.
データが少ない分,ファインチューニングを用いて推定していきます.
学習に関してはまた別の記事で説明します.
OpenCVで顔の切り出し
まずはこちらの記事を参考に画像から顔の部分を切り出します.
ysss.hateblo.jp
切り出した画像がこちら
別々に保存したのがこちら
これらを画像処理を使ってデータの水増しをしていきます.
画像を使った学習ではデータの水増しをするのが常套手段みたいです.
データの水増し
これはこちらの記事を参考にさせていただきました.
qiita.com
ここで紹介されている手法×上下の反転で36枚に増やします.
元画像
増やしたデータ
これらを使って学習していきます.
まとめ
今回は深層学習に使う画像の前処理について書きました.
次回はこの画像を使って学習していきたいと思います.
ありがとうございました.
ソースコード
顔画像の切り出し
# coding: utf-8 import cv2 import matplotlib.pyplot as plt # 画像読込み origin_img = cv2.imread("kanta.jpg") # 画像コピー img = origin_img.copy() # カスケードファイルのパス cascade_path = "haarcascade_frontalface_alt.xml" # カスケード分類器の特徴量取得 cascade = cv2.CascadeClassifier(cascade_path) # 画像グレースケール化 grayscale_img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY) # 顔検出 # minSize 最小サイズ指定 front_face_list = cascade.detectMultiScale(grayscale_img, minSize=(100, 100)) # 検出判定 print(front_face_list) if len(front_face_list) == 0: print("Failed") quit() # 検出位置描画 for (x, y, w, h) in front_face_list: print("[x,y] = %d,%d [w,h] = %d,%d" % (x, y, w, h)) cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), thickness=10) # 顔検出画像表示 plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) plt.show() # 顔検出画像出力 cv2.imwrite("out.jpg", img) # 検出画像出力 for (x, y, w, h) in front_face_list: face_img = origin_img[y:y + h, x:x + w] dst=cv2.resize(face_img,dsize=(224,224)) filename = "face_" + str(x) + "-" + str(y) + ".jpg" cv2.imwrite(filename, dst)
データの水増し
# coding: utf-8 import numpy as np import cv2 import chainer FOLDER="./datas/kanta/image/" NAME="kanta.jpg" #反転 flip= cv2.imread(FOLDER+NAME, 1) hflip_img = cv2.flip(flip, 1) vflip_img = cv2.flip(flip, 0) vhflip_img=cv2.flip(hflip_img, 0) cv2.imwrite(FOLDER+"tate.jpg",hflip_img) cv2.imwrite(FOLDER+"yoko.jpg",vflip_img) cv2.imwrite(FOLDER+"tateyoko.jpg",vhflip_img) list=[flip,hflip_img,vflip_img,vhflip_img] for num,src in enumerate(list): print(num) # ルックアップテーブルの生成 min_table = 50 max_table = 205 diff_table = max_table - min_table LUT_HC = np.arange(256, dtype = 'uint8' ) LUT_LC = np.arange(256, dtype = 'uint8' ) # ハイコントラストLUT作成 for i in range(0, min_table): LUT_HC[i] = 0 for i in range(min_table, max_table): LUT_HC[i] = 255 * (i - min_table) / diff_table for i in range(max_table, 255): LUT_HC[i] = 255 # ローコントラストLUT作成 for i in range(256): LUT_LC[i] = min_table + i * (diff_table) / 255 # 変換 high_cont_img = cv2.LUT(src, LUT_HC) low_cont_img = cv2.LUT(src, LUT_LC) cv2.imwrite(FOLDER+"high"+str(num)+".jpg", high_cont_img) cv2.imwrite(FOLDER+"low"+str(num)+".jpg",low_cont_img) LUT_G1 = np.arange(256, dtype = 'uint8' ) LUT_G2 = np.arange(256, dtype = 'uint8' ) # ガンマ変換ルックアップテーブル gamma1 = 0.75 gamma2 = 1.5 for i in range(256): LUT_G1[i] = 255 * pow(float(i) / 255, 1.0 / gamma1) LUT_G2[i] = 255 * pow(float(i) / 255, 1.0 / gamma2) high_cont_img = cv2.LUT(src, LUT_G1) low_cont_img = cv2.LUT(src, LUT_G2) cv2.imwrite(FOLDER+"G1"+str(num)+".jpg", high_cont_img) cv2.imwrite(FOLDER+"G2"+str(num)+".jpg",low_cont_img) #平滑化 average_square = (2,2) blur_img = cv2.blur(src, average_square) cv2.imwrite(FOLDER+"hei"+str(num)+".jpg", blur_img) #ガウス row,col,ch= src.shape mean = 0 sigma = 15 gauss = np.random.normal(mean,sigma,(row,col,ch)) gauss = gauss.reshape(row,col,ch) gauss_img = src + gauss cv2.imwrite(FOLDER+"gauss"+str(num)+".jpg", gauss_img) #ソルトアンドペッパー row,col,ch = src.shape s_vs_p = 0.5 amount = 0.004 salt_img = src.copy() papper_img=src.copy() # 塩モード num_salt = np.ceil(amount * src.size * s_vs_p) coords = [np.random.randint(0, i-1 , int(num_salt)) for i in src.shape] salt_img[coords[:-1]] = (255,255,255) cv2.imwrite(FOLDER+"salt"+str(num)+".jpg", salt_img) # 胡椒モード num_pepper = np.ceil(amount* src.size * (1. - s_vs_p)) coords = [np.random.randint(0, i-1 , int(num_pepper)) for i in src.shape] papper_img[coords[:-1]] = (0,0,0) cv2.imwrite(FOLDER+"papper"+str(num)+".jpg",papper_img)