teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

追補

2020/01/10 12:34

投稿

退会済みユーザー
answer CHANGED
@@ -1,3 +1,153 @@
1
+ 追補
2
+ ---
3
+ 補完方法にどれだけ差があるか試したことがなかったため、KERASの方法を正としてOpenCV、PILの方法を比較しました。
4
+ ![イメージ説明](bd16cabd9868535b4744ea67f036f16d.png)
5
+ 結果: 補完方法による「差はない」は言い過ぎですが、**データ増強の変化量と比べればないも同然程度の差**しかありませんでした。
6
+ ![イメージ説明](fdafc3e9033f9850e357160d9bc944d0.png)
7
+ ```Python3
8
+ from PIL import Image
9
+ import cv2
10
+ import os
11
+ import numpy as np
12
+
13
+ from keras.preprocessing.image import ImageDataGenerator,img_to_array
14
+
15
+ path = ".\lenna.png"
16
+ size = (256,256)
17
+
18
+ def PIL2OpenCV(img):
19
+ img = np.asarray(img)
20
+ if len(img.shape)==3:
21
+ # RGB --> BGR
22
+ img = cv2.cvtColor(img,cv2.COLOR_RGB2BGR)
23
+ return img
24
+
25
+ def pure_PIL(path,size):
26
+ img_PIL = Image.open(path)
27
+ img_PIL = img_PIL.resize(size)
28
+
29
+ return PIL2OpenCV(img_PIL)
30
+
31
+ def pure_OpenCV(path,size,flag):
32
+ img_OpenCV = cv2.imread(path)
33
+ img_OpenCV = cv2.resize(img_OpenCV,size,interpolation=flag)
34
+ return img_OpenCV
35
+
36
+ def by_keras(path,size):
37
+ img_by_keras = ImageDataGenerator.flow_from_directory(path,target_size=size)
38
+ print(img_by_keras)
39
+ return img_by_keras
40
+
41
+ if __name__=="__main__":
42
+
43
+ img_by_keras = pure_OpenCV(path,size,cv2.INTER_LANCZOS4)
44
+ # cv2.imshow("KERAS",cv2.absdiff(img_by_keras,img_by_keras))
45
+
46
+ img_PIL = pure_PIL(path,size)
47
+ # cv2.imshow("PIL",cv2.absdiff(img_by_keras,img_PIL))
48
+
49
+ img_nearest = pure_OpenCV(path,size,cv2.INTER_NEAREST)
50
+ # cv2.imshow("OpenCV (NEAREST)",cv2.absdiff(img_by_keras,img_nearest))
51
+
52
+ img_linear = pure_OpenCV(path,size,cv2.INTER_LINEAR)
53
+ # cv2.imshow("OpenCV (LINEAR)",cv2.absdiff(img_by_keras,img_linear))
54
+
55
+ img_cubic = pure_OpenCV(path,size,cv2.INTER_CUBIC)
56
+ # cv2.imshow("OpenCV (CUBIC)",cv2.absdiff(img_by_keras,img_cubic))
57
+
58
+ img_area = pure_OpenCV(path,size,cv2.INTER_AREA)
59
+ # cv2.imshow("OpenCV (AREA)",cv2.absdiff(img_by_keras,img_area))
60
+
61
+ img_lanczos = pure_OpenCV(path,size,cv2.INTER_LANCZOS4)
62
+ # cv2.imshow("OpenCV (LANCZOS4)",cv2.absdiff(img_by_keras,img_lanczos))
63
+
64
+ # img_strange = img_to_array(img_nearest)
65
+ # cv2.imshow("STRANGE CODE",img_strange)
66
+
67
+ img_stacked = np.hstack((cv2.absdiff(img_by_keras,img_by_keras),
68
+ cv2.absdiff(img_by_keras,img_PIL),
69
+ cv2.absdiff(img_by_keras,img_nearest),
70
+ cv2.absdiff(img_by_keras,img_linear),
71
+ cv2.absdiff(img_by_keras,img_cubic),
72
+ cv2.absdiff(img_by_keras,img_area),
73
+ cv2.absdiff(img_by_keras,img_lanczos)
74
+ ))
75
+ cv2.imwrite("./stacked.png",img_stacked)
76
+ cv2.imshow("KERAS/PIL/NEAREST/LINEAR/CUBIC/AREA/LANCZOS/STRANGE",img_stacked)
77
+
78
+ cv2.waitKey(0)
79
+ ```
80
+ また、
81
+ > 学習した特徴量(kerasでリサイズ)がモデルを使用するときの画像(opencvでリサイズ)に使えない状態
82
+
83
+ これについて検証するため、掲載のコードを手元のWindowsで動くように若干修正したのが以下のコードです。
84
+ 結果: OpenCVではBGRに対して、PILではRGBでデータが格納されています。この違いにより、PIL経由でデータを表示させたものは異常な色になりました。これが学習がうまくいかなかった原因と思われます。
85
+ これを防ぐには、上記の`PIL2OpenCV`をかませる等で対応してください。
86
+
87
+ ![イメージ説明](3f3178bf3d15a9400aa3de083897892f.png)
88
+ ```Python3
89
+ from PIL import Image
90
+ import cv2
91
+ import os
92
+ import numpy as np
93
+
94
+ from keras.preprocessing.image import ImageDataGenerator,img_to_array
95
+
96
+ path = ".\lenna.png"
97
+ size = (256,256)
98
+
99
+ def PIL2OpenCV(img):
100
+ img = np.asarray(img)
101
+ if len(img.shape)==3:
102
+ # RGB --> BGR
103
+ img = cv2.cvtColor(img,cv2.COLOR_RGB2BGR)
104
+ return img
105
+
106
+ def pure_PIL(path,size):
107
+ img_PIL = Image.open(path)
108
+ img_PIL = img_PIL.resize(size)
109
+
110
+ return PIL2OpenCV(img_PIL)
111
+
112
+ def pure_OpenCV(path,size,flag):
113
+ img_OpenCV = cv2.imread(path)
114
+ img_OpenCV = cv2.resize(img_OpenCV,size,interpolation=flag)
115
+ return img_OpenCV
116
+
117
+ def by_keras(path,size):
118
+ img_by_keras = ImageDataGenerator.flow_from_directory(path,target_size=size)
119
+ print(img_by_keras)
120
+ return img_by_keras
121
+
122
+ if __name__=="__main__":
123
+
124
+ img_by_keras = pure_OpenCV(path,size,cv2.INTER_LANCZOS4)
125
+ cv2.imshow("KERAS",cv2.absdiff(img_by_keras,img_by_keras))
126
+ img_PIL = pure_PIL(path,size)
127
+ cv2.imshow("PIL",cv2.absdiff(img_by_keras,img_PIL))
128
+
129
+ img_OpenCV = pure_OpenCV(path,size,cv2.INTER_NEAREST)
130
+ cv2.imshow("OpenCV (NEAREST)",cv2.absdiff(img_by_keras,img_OpenCV))
131
+
132
+ img_OpenCV = pure_OpenCV(path,size,cv2.INTER_LINEAR)
133
+ cv2.imshow("OpenCV (LINEAR)",cv2.absdiff(img_by_keras,img_OpenCV))
134
+
135
+ img_OpenCV = pure_OpenCV(path,size,cv2.INTER_CUBIC)
136
+ cv2.imshow("OpenCV (CUBIC)",cv2.absdiff(img_by_keras,img_OpenCV))
137
+
138
+ img_OpenCV = pure_OpenCV(path,size,cv2.INTER_AREA)
139
+ cv2.imshow("OpenCV (AREA)",cv2.absdiff(img_by_keras,img_OpenCV))
140
+
141
+ img_OpenCV = pure_OpenCV(path,size,cv2.INTER_LANCZOS4)
142
+ cv2.imshow("OpenCV (LANCZOS4)",cv2.absdiff(img_by_keras,img_OpenCV))
143
+
144
+ img_OpenCV = img_to_array(img_OpenCV)
145
+ cv2.imshow("STRANGE CODE",img_OpenCV)
146
+
147
+ cv2.waitKey(0)
148
+ ```
149
+ ---
150
+
1
151
  **■リファレンスの情報**
2
152
  - [Kerasのload_imgのリサイズはパスを入れて**PIL形式を返す**](https://www.tensorflow.org/api_docs/python/tf/keras/preprocessing/image/load_img)です。
3
153
  つまり、