質問編集履歴

2

2020/04/23 17:00

投稿

muby8
muby8

スコア13

test CHANGED
@@ -1 +1 @@
1
- 画像の黒い部分が白くなってしまう
1
+ Python 画像処理
test CHANGED
File without changes

1

もう少し詳しく書き直しました

2020/04/23 17:00

投稿

muby8
muby8

スコア13

test CHANGED
@@ -1 +1 @@
1
- YUV(YCbCr)で読み込んだ画像BMPで保存する方法
1
+ 画像の黒い部分が白くなってしまう
test CHANGED
@@ -1,12 +1,36 @@
1
+ ### 実現したいこと
2
+
1
- YUVで読み込んだ画像をBMPに変換して保存したいのですがうまくいきません.
3
+ **YUVで読み込んだ画像をBMPに変換して保存したい**
4
+
5
+
6
+
2
-
7
+ ### 問題点
8
+
3
- 図のように違った雰囲気の画像が出力されてしまいます.
9
+ Aはインプット画像でYUV形式の画像です.図Bはアウトプット画像です,本来黒であるべき部分が白くなってしまいます.
4
10
 
5
11
  ![変換前(YUV)](552939472d39fd191904418c879e7768.jpeg)
6
12
 
13
+ 図A インプット
14
+
15
+
16
+
7
17
  ![変換後(BMP)](7db089a9b071d53b59b60a39ac22f10b.jpeg)
8
18
 
19
+ 図B アウトプット
20
+
21
+
22
+
23
+ ### やったこと
24
+
25
+ read_YUVにインプット画像を入れて読み込む.出力は[フレーム数,高さ,幅,3]の4次元のnumpy.array.
26
+
9
- YUVからBMPへ変換後,画像の黒い部分が白くなってしまいます
27
+ 次にyuv_to_rgb()で8bitフルスケールへ変換
28
+
29
+ これを画像に保存したいわけですが,そのままImage.fromarray()を使って保存しようとしたらTypeErrorが出てしまったので
30
+
31
+ [ここ](https://pepper.is.sci.toho-u.ac.jp/pepper/index.php?%A5%CE%A1%BC%A5%C8%2Fpython%A1%A6matplotlib%A4%C7%B0%B7%A4%A6%B2%E8%C1%FC)を参考に作りました.
32
+
33
+
10
34
 
11
35
  ```Python
12
36
 
@@ -18,15 +42,205 @@
18
42
 
19
43
 
20
44
 
45
+ def read_YUV(filePath, height, width, frameNumber=0, count=1, colorFormat=444, depth=8, Y_only=False):
46
+
47
+ '''
48
+
49
+ 処理内容
50
+
51
+ 画像を読み込み,[フレーム数, 高さ, 幅, 3 or 1]の4次元配列に格納する.
52
+
53
+ カラーフォーマット420の場合,NearestNeighbor法に基づいてuy成分を2倍に拡大する.
54
+
55
+ 引数
56
+
57
+ filePath:画像のパス
58
+
59
+ height:高さ
60
+
61
+ width:幅
62
+
63
+ frameNumber:読み込み開始フレーム番号(デフォルト0)
64
+
65
+ count:読み込むフレーム数(デフォルト1)
66
+
67
+ colorFormat:カラーフォーマット(デフォルト420)
68
+
69
+ depth:ファイルのビット深度
70
+
71
+ Y_only:Trueなら輝度だけ読み込む(デフォルトFalse)
72
+
73
+ 戻り値
74
+
75
+ [フレーム数, 高さ, 幅, 3 or 1]の配列(dtype=np.uint8)
76
+
77
+ '''
78
+
79
+
80
+
81
+ if colorFormat == 420:
82
+
83
+ colorStride = 1.5
84
+
85
+ else:
86
+
87
+ colorStride = 3
88
+
89
+ if depth == 8:
90
+
91
+ depthStride = 1
92
+
93
+ dtype = np.uint8
94
+
95
+ elif depth > 8:
96
+
97
+ depthStride = 2
98
+
99
+ dtype = np.uint16
100
+
101
+
102
+
103
+ with open(filePath,'rb') as fp:
104
+
105
+ #目的のフレームまでシーク
106
+
107
+ fp.seek(int(height*width*frameNumber*depthStride*colorStride),0)
108
+
109
+
110
+
111
+ listImgY = []
112
+
113
+ listImgUV = []
114
+
115
+
116
+
117
+ for c in range(count):
118
+
119
+ bary = np.fromfile(fp,dtype=dtype,count=height*width)
120
+
121
+ imgY = np.reshape(bary,(1,height, width,1))
122
+
123
+ listImgY.append(imgY)
124
+
125
+
126
+
127
+ if Y_only is False:
128
+
129
+ if colorFormat == 420:
130
+
131
+ bary = np.fromfile(fp,dtype=dtype,count=int((height/2)*(width/2)*2))
132
+
133
+ imgUV = np.reshape(bary,(2,int(height/2),int(width/2),1))
134
+
135
+ imgUV = np.transpose(imgUV,(3,1,2,0))
136
+
137
+ imgUV = imgUV.repeat(2, axis=1).repeat(2, axis=2)
138
+
139
+ listImgUV.append(imgUV)
140
+
141
+ elif colorFormat == 444:
142
+
143
+ bary = np.fromfile(fp,dtype=dtype,count=height*width*2)
144
+
145
+ imgUV = np.reshape(bary,(2,height,width,1))
146
+
147
+ imgUV = np.transpose(imgUV,(3,1,2,0))
148
+
149
+ listImgUV.append(imgUV)
150
+
151
+ else:
152
+
153
+ fp.seek(int(height*width*depthStride*(colorStride-1)),1)
154
+
155
+
156
+
157
+ imagesY = np.concatenate(listImgY,axis=0)
158
+
159
+ if Y_only is False:
160
+
161
+ imagesUV = np.concatenate(listImgUV,axis=0)
162
+
163
+ images = np.concatenate([imagesY,imagesUV],axis=3)
164
+
165
+ return images
166
+
167
+ else:
168
+
169
+ return imagesY
170
+
171
+
172
+
173
+ def yuv_to_rgb(img):
174
+
175
+ '''
176
+
177
+ 処理内容
178
+
179
+ ITU-R BT.601 規定YCbCrから8bitフルスケールRGBへの変換を行う
180
+
181
+ 参考サイト:https://vision.kuee.kyoto-u.ac.jp/~hiroaki/firewire/yuv.html
182
+
183
+ 引数
184
+
185
+ img:画像データ[高さ, 幅, 3]
186
+
187
+ 戻り値
188
+
189
+ [高さ, 幅, 3]のrgb配列(dtype=np.float32)
190
+
191
+
192
+
193
+ '''
194
+
195
+ height = img.shape[1]
196
+
197
+ width = img.shape[2]
198
+
199
+
200
+
201
+ rgb = np.zeros((1,height,width,3),dtype=np.float32)
202
+
203
+ img = img.astype(np.float32)
204
+
205
+
206
+
207
+ rgb[:,:,:,0] = 1.164 * (img[:,:,:,0]-16) + 1.596 * (img[:,:,:,2] - 128)
208
+
209
+ rgb[:,:,:,1] = 1.164 * (img[:,:,:,0]-16) - 0.391 * (img[:,:,:,1] - 128) - 0.813 * (img[:,:,:,2] -128)
210
+
211
+ rgb[:,:,:,2] = 1.164 * (img[:,:,:,0]-16) + 2.018 * (img[:,:,:,1] - 128)
212
+
213
+ rgb = np.floor(rgb)
214
+
215
+ return rgb
216
+
217
+
218
+
219
+ if __name__ == '__main__':
220
+
21
- file = './test.yuv'
221
+ file = './test.yuv'
22
-
222
+
23
- img =read_YUV(file, height, width).astype('float') //YUV読み込み用関数
223
+ img =read_YUV(file, height, width).astype('float') //YUV読み込み用関数
24
-
224
+
25
- img_n = yuv_to_rgb(img) //8bitフルスケールRGBへ変換
225
+ img_n = yuv_to_rgb(img) //8bitフルスケールRGBへ変換
26
-
226
+
27
- img_nn = img_n[0,:,:,] //3次元にシェイプ
227
+ img_nn = img_n[0,:,:,] //3次元にシェイプ
228
+
229
+
230
+
28
-
231
+ arrayimage = np.asarray(img_nn)
232
+
29
-
233
+ scale = 255.0 / np.max(arrayimage)
234
+
235
+ pilImg = Image.fromarray(np.uint8(arrayimage*scale))
236
+
237
+ ```
238
+
239
+ ###
240
+
241
+
242
+
243
+ ```Python
30
244
 
31
245
  arrayimage = np.asarray(img_nn)
32
246
 
@@ -36,36 +250,4 @@
36
250
 
37
251
  ```
38
252
 
39
-
40
-
41
- ### read_YUV関数
42
-
43
- YUVを読み込むための関数です
44
-
45
- 戻り値は[フレーム数,高さ,幅,3 or 1]の4次元配列
46
-
47
- ### yuv_to_rgb関数
48
-
49
- 規定YCbYrから8bitフルスケールRGBへ変換するための関数です
50
-
51
- 戻り値は[高さ,幅,3]のrgb配列
52
-
53
-
54
-
55
- ###
56
-
57
- 上記二つの関数は正しく機能しています
58
-
59
-
60
-
61
- ```Python
62
-
63
- arrayimage = np.asarray(img_nn)
64
-
65
- scale = 255.0 / np.max(arrayimage)
66
-
67
- pilImg = Image.fromarray(np.uint8(arrayimage*scale))
68
-
69
- ```
70
-
71
- おそらくこの部分が間違えていると思うのですがよくわからないのでどなたかご教授願います.
253
+ おそらくmain内のこの部分が間違えていると思うのですがよくわからないのでどなたかご教授願います.