リスト 2.8 : srcnn/eval.py def —pad(image, pad) : if pad [INDEX_PADDING_LEFT] and pad [INDEX_PADDING_TOP] return image w n ew h image . width image . height S 1 w + pad [INDEX_PADDING_LEFT] + pad [INDEX—PADDING_R 工 GHT] , + pad [INDEX_PADDING_TOP] + pad [ 工 NDEX_PADDING_BOTTOM] (pad[INDEX_PADDING_LEFT] , pad[INDEX_PADDING_TOP] ) new—size, color=@xffffff) —image. paste(image, 1 mage lmage . new('RGB' プロックに分割 return new_image 2 次元配列に格納する際、 NumPy の Array 形式に変換します。また、 255 で除算すること サイズとスライド幅は同じ値になります。 stride は、プロックのスライド幅です。プロック同士が重複なく処理する場合、プロック 納します。 リスト 2.9 の関数 __extract_blocks は、画像をプロック 3 に分割したあと 2 次元配列に格 V num image . height / / stride[INDEX—VERTICAL] def extract_blocks(image, stride) : リスト 2.9 : srcnn/eval.py で、ピクセルの値域を @ー 255 から @ . @-I. @ に整えます。 [@ for i in range(h—num)] for j in range(v—num) btocks # blocks [v—num] [h—num] h—num = image . width / / stride[INDEX—HOR 工 ZONTAL] shape (MODEL. INPUT_SIZE, MODEL. INPUT_SIZE, 34 第 2 章 CNN で超解像
OS . path . join(dir, MODEL. NAME) dir if not os . path . exists(dir) : os . mkdir(dir) OS . path . j 0i n ( di r , 96s—96dx ・ png OS . path . j Oi n ()i r , '96s-96dx—resuIt. png padded_fite % (name, scate)) resutt file % (name, scale)) lmage . open(image—path) 1 mage image. resize( resized_image (image. width ☆ scale, image . height ☆ scale) , lmage . BICUBIC) if MODEL . CHANNELS resized image resized_image . convert('L') calc—padding(resized—image, stride) padding —pad(resized—image, padding=padding) resized_image —save—image(resized—image, padded—file, padding=padding) extract_btocks(resized—image, stride) btocks —process(blocks, train—dir) btocks —reconstruct(btocks) resutt_image normalize(result_image) ☆ 255 result_image round((MODEL. INPUT_SIZE MODEL . OUTPUT_SIZE) / 2 ) pad pad padding[INDEX_PADDING_LEFT] pad paddingCINDEX_PADDING_TOP] padding[INDEX_PADDING_RIGHT] + = pad padding[INDEX_PADDING_BOTTOM] + = pad —save_image(result image, result—fite, padding=padding) file, padded—file return result 平価 一平価用の画像として、縦横 510PX5 の画像を用意しました ( 図 2.5 ) 。 三ロ 38 第 2 章 CNN で超解像
リスト 3.6 : srcnn/eval.py def _srcnn(image—path, scale, # スライド幅を変更 stride (MODEL. OUTPUT_SIZE, train_dir): MODEL. OUTPUT_SIZE) name, ext = OS. path. sptitext(os. path. basename(image_path)) dir OS . path . dirname(image_path) dir OS . path. join(dir, MODEL . NAME) if not os . path . exists(dir): os . mkdir(dir) padded_fite result fite OS . path . j Oi n ()i r , 96s—96dx ・ png % (name, scale)) OS . path . join(dir, '96s—96dx—resuIt ・ png % (name, scale)) lmage ・ open(image—path) 1 mage resized_image image . resize( (image. width 大 scale, image ・ height ☆ scale) , 工 mage. BICUBIC) if MODEL . CHANNELS resized image 1 : resized—image. convert('L') padding calc—padding(resized—image, stride) resized_image —pad(resized—image, padding=padding) —save—image(resized—image, padded—fite, padding=padding) blocks blocks extract_blocks(resized—image, stride) —process(btocks, train—dir) resutt_image result_image —reconstruct(blocks) _normalize(resutt_image) ☆ 255 # パディングの再計算 pad round ( (MODEL. INPUT_SIZE MODEL. OUTPUT_S 工 (E) / 2 ) padding[ 工 NDEX_PADDING_LEFT] pad padding[ 工 NDEX—PADDING_TOP] pad padding[INDEX_PADDING_RIGHT] + = pad padding[INDEX_PADDING_BOTTOM] + ニ pad —save—image(resutt—image, result—file, padding=padding) 第 3 章超解像奮闘記 51
図 : プロック単位に処理できるように大きさを調整 リスト 2.7 の関数 __calc_padding は、プロックのスライド幅 (stride) に対して必要な パディングを計算します。 リスト 2.7 : srcnn/eval.py INDEX_PADDING_LEFT = 0 INDEX PADDING TOP INDEX PADDING RIGHT = 2 INDEX PADDING BOTTOM 3 INDEX VERTICAL INDEX HORIZONTAL 1 def __calc—padding(image, stride) : padding—vertical stride[INDEX_VERTICAL] \ image. height % stride[INDEX_VERT 工 CAL] stride[INDEX_HORIZONTAL] \ image. width % stride[INDEX_HORIZONTAL] padding—horizontal padding padding[INDEX_PADDING_LEFT] padding[INDEX_PADDING_TOP] padding[INDEX_PADDING_RIGHT] padding—horizontal / / 2 padding—verticat / / 2 padding—horizontal \ padding[INDEX_PADDING_LEFT] padding—verticat \ padding[INDEX_PADDING_TOP] padding[INDEX_PADDING_BOTTOM] return padding リスト 2.8 の関数ーー pad は、画像にパディングを付加します。パディングを付加したサイズの 画像を作成して、中央にオリジナルの画像を貼り付けます。 第 2 章 CNN で超解像 33
return result—file, padded-file 畳み込み層を通るときに失われるピクセル分、出力サイズは小さくなります。出力プロック が小さくなる分、画像の左端と上端のピクセルが失われます。 関数 --calc-padding を変更して、付加するパディングを 1 プロック ( スライド幅 ) 分加算 します ( リスト 3.7 ) 。 さらにリスト 3.6 の関数ーー srcnn を、パディングを取り除く前に、パディングの量を再計算 するように変更します。 リスト 3.7 : srcnn/eval.py catc—padding(image, stride) : def strideCINDEX_VERTICAL] \ padding—vertical image . height % stride[INDEX—VERTICAL] stride[INDEX_HORIZONTAL] \ image. width % stride[INDEX_HORIZONTAL] padding—horizontal # パディングを追加 padding—vertical + = stride[lNDEX—VERTICAL] padding—horizontat + = stride[INDEX—HORIZONTAL] padding padding[INDEX padding[INDEX paddingC 工 NDEX PADDING_LEFT] PADDING_TOP] padding—horizontal / / 2 padding—vertical / / 2 PADDING_RIGHT] padding[INDEX_PADDING_BOTTOM] return padding padding—horizontat \ padding[INDEX_PADDING_LEFT] padding—vertical \ padding[INDEX_PADD 工 NG—TOP] 図 3.11 は、表 32 の条件で学習した場合の誤差の変化です。 表 3.2 : 学習条件 条件 画像の倍率 (scale) 学習率 (learning-rate ) ニバッチサイズ (batch_size) ステップ数 (max_step) チャンネル数 (CHANNELS) 値 2x 0. 開 1 128 1 開Ⅱ ) 1 ( グレースケール ) 52 第 3 章超解像奮闘記