追補
補完方法にどれだけ差があるか試したことがなかったため、KERASの方法を正としてOpenCV、PILの方法を比較しました。
結果: 補完方法による「差はない」は言い過ぎですが、データ増強の変化量と比べればないも同然程度の差 しかありませんでした。
Python3
1 from PIL import Image
2 import cv2
3 import os
4 import numpy as np
5
6 from keras.preprocessing.image import ImageDataGenerator,img_to_array
7
8 path = ".\lenna.png"
9 size = (256,256)
10
11 def PIL2OpenCV(img):
12 img = np.asarray(img)
13 if len(img.shape)==3:
14 # RGB --> BGR
15 img = cv2.cvtColor(img,cv2.COLOR_RGB2BGR)
16 return img
17
18 def pure_PIL(path,size):
19 img_PIL = Image.open(path)
20 img_PIL = img_PIL.resize(size)
21
22 return PIL2OpenCV(img_PIL)
23
24 def pure_OpenCV(path,size,flag):
25 img_OpenCV = cv2.imread(path)
26 img_OpenCV = cv2.resize(img_OpenCV,size,interpolation=flag)
27 return img_OpenCV
28
29 def by_keras(path,size):
30 img_by_keras = ImageDataGenerator.flow_from_directory(path,target_size=size)
31 print(img_by_keras)
32 return img_by_keras
33
34 if __name__=="__main__":
35
36 img_by_keras = pure_OpenCV(path,size,cv2.INTER_LANCZOS4)
37 # cv2.imshow("KERAS",cv2.absdiff(img_by_keras,img_by_keras))
38
39 img_PIL = pure_PIL(path,size)
40 # cv2.imshow("PIL",cv2.absdiff(img_by_keras,img_PIL))
41
42 img_nearest = pure_OpenCV(path,size,cv2.INTER_NEAREST)
43 # cv2.imshow("OpenCV (NEAREST)",cv2.absdiff(img_by_keras,img_nearest))
44
45 img_linear = pure_OpenCV(path,size,cv2.INTER_LINEAR)
46 # cv2.imshow("OpenCV (LINEAR)",cv2.absdiff(img_by_keras,img_linear))
47
48 img_cubic = pure_OpenCV(path,size,cv2.INTER_CUBIC)
49 # cv2.imshow("OpenCV (CUBIC)",cv2.absdiff(img_by_keras,img_cubic))
50
51 img_area = pure_OpenCV(path,size,cv2.INTER_AREA)
52 # cv2.imshow("OpenCV (AREA)",cv2.absdiff(img_by_keras,img_area))
53
54 img_lanczos = pure_OpenCV(path,size,cv2.INTER_LANCZOS4)
55 # cv2.imshow("OpenCV (LANCZOS4)",cv2.absdiff(img_by_keras,img_lanczos))
56
57 # img_strange = img_to_array(img_nearest)
58 # cv2.imshow("STRANGE CODE",img_strange)
59
60 img_stacked = np.hstack((cv2.absdiff(img_by_keras,img_by_keras),
61 cv2.absdiff(img_by_keras,img_PIL),
62 cv2.absdiff(img_by_keras,img_nearest),
63 cv2.absdiff(img_by_keras,img_linear),
64 cv2.absdiff(img_by_keras,img_cubic),
65 cv2.absdiff(img_by_keras,img_area),
66 cv2.absdiff(img_by_keras,img_lanczos)
67 ))
68 cv2.imwrite("./stacked.png",img_stacked)
69 cv2.imshow("KERAS/PIL/NEAREST/LINEAR/CUBIC/AREA/LANCZOS/STRANGE",img_stacked)
70
71 cv2.waitKey(0)
また、
学習した特徴量(kerasでリサイズ)がモデルを使用するときの画像(opencvでリサイズ)に使えない状態
これについて検証するため、掲載のコードを手元のWindowsで動くように若干修正したのが以下のコードです。
結果: OpenCVではBGRに対して、PILではRGBでデータが格納されています。この違いにより、PIL経由でデータを表示させたものは異常な色になりました。これが学習がうまくいかなかった原因と思われます。
これを防ぐには、上記のPIL2OpenCV
をかませる等で対応してください。
Python3
1 from PIL import Image
2 import cv2
3 import os
4 import numpy as np
5
6 from keras.preprocessing.image import ImageDataGenerator,img_to_array
7
8 path = ".\lenna.png"
9 size = (256,256)
10
11 def PIL2OpenCV(img):
12 img = np.asarray(img)
13 if len(img.shape)==3:
14 # RGB --> BGR
15 img = cv2.cvtColor(img,cv2.COLOR_RGB2BGR)
16 return img
17
18 def pure_PIL(path,size):
19 img_PIL = Image.open(path)
20 img_PIL = img_PIL.resize(size)
21
22 return PIL2OpenCV(img_PIL)
23
24 def pure_OpenCV(path,size,flag):
25 img_OpenCV = cv2.imread(path)
26 img_OpenCV = cv2.resize(img_OpenCV,size,interpolation=flag)
27 return img_OpenCV
28
29 def by_keras(path,size):
30 img_by_keras = ImageDataGenerator.flow_from_directory(path,target_size=size)
31 print(img_by_keras)
32 return img_by_keras
33
34 if __name__=="__main__":
35
36 img_by_keras = pure_OpenCV(path,size,cv2.INTER_LANCZOS4)
37 cv2.imshow("KERAS",cv2.absdiff(img_by_keras,img_by_keras))
38 img_PIL = pure_PIL(path,size)
39 cv2.imshow("PIL",cv2.absdiff(img_by_keras,img_PIL))
40
41 img_OpenCV = pure_OpenCV(path,size,cv2.INTER_NEAREST)
42 cv2.imshow("OpenCV (NEAREST)",cv2.absdiff(img_by_keras,img_OpenCV))
43
44 img_OpenCV = pure_OpenCV(path,size,cv2.INTER_LINEAR)
45 cv2.imshow("OpenCV (LINEAR)",cv2.absdiff(img_by_keras,img_OpenCV))
46
47 img_OpenCV = pure_OpenCV(path,size,cv2.INTER_CUBIC)
48 cv2.imshow("OpenCV (CUBIC)",cv2.absdiff(img_by_keras,img_OpenCV))
49
50 img_OpenCV = pure_OpenCV(path,size,cv2.INTER_AREA)
51 cv2.imshow("OpenCV (AREA)",cv2.absdiff(img_by_keras,img_OpenCV))
52
53 img_OpenCV = pure_OpenCV(path,size,cv2.INTER_LANCZOS4)
54 cv2.imshow("OpenCV (LANCZOS4)",cv2.absdiff(img_by_keras,img_OpenCV))
55
56 img_OpenCV = img_to_array(img_OpenCV)
57 cv2.imshow("STRANGE CODE",img_OpenCV)
58
59 cv2.waitKey(0)
■リファレンスの情報
つまり、
PIL_IMG = load_img(PATH, target_size=(img_width, img_height))
■掲載のコード
エラー等の情報なく、とりあえずうまくいかないとのことですのでコードを確認すると、
コード リファレンスの要求 NUMPY_IMG = img_to_array(PIL_IMG)
掲載のコード NUMPY_IMG = img_to_array(NUMPY_IMG)
のように入力しているデータの形式が異なっていることが分かります。
実際に動かしていないのですが、一番怪しいのはこのように形式の相違と思われます。
■対策
「OpenCVで読み込み・リサイズした画像をPIL形式に直してからimg_to_array
する」か、エラーが出ないようであれば「OpenCVで読み込み・リサイズした画像をそのままnp.expand_dims()につっこむ」でよいのではないでしょうか?
ただし、cv2.imread
経由の値はnp.uint8
形式ですが、img_to_array
経由での値は同じ値をfloat
で(例えば、5を5.のように)返すそうですので、必要であればここに注意して動作確認をしてください。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/01/09 15:14