石立 喬のホームページVisual Studio Community 2017でPythonを始める>本ページ


2018. 5. 20.
石立 喬

Scikit-imageで画像処理を行う(1)
―一般的な紹介の後、exposureモジュールを使うー


 Pythonで使用できる画像処理ライブラリにscikit-imageがある。ここでは、まず最初に、注目するピクセル単位の画像処理(single pixel operation)と、ピクセル周辺を含めた画像処理(neighborhood operation)に分けて簡単な画像処理を紹介し、続いて、exposure モジュールについて、やや詳しく紹介する。

Scikit-imageとは
 Python用の、オープンソース画像処理ライブラリである。特にダウンロードやインストールの必要がなく使用できるので便利である。他に画像処理ライブラリPillowがあり、PIL(Python Image Library)からの発展として広く使用されている。Pillowについては追って取り上げる。

ピクセル単位の簡単な画像処理】
 画像処理の比較的単純なものに、注目するピクセルのみに関して、R、G、Bに分解して明るさ(luminance)を計算するグレイスケール化、各成分を255から引いて画像化する色反転がある。次に単純と言えるのは、グレイスケール画像の各ピクセルについて、一定の値と比較して白か黒かを決める二値化である。
 まずは、これらを図1のプログラムで実行し、得られた結果を図2に示す。
 color.rgb2grayでグレイスケール化した画像は、チャンネル成分のない(M, N)形式なので、そのままplt.imshowで表示させると、デフォルトのカラーマップ'viridis'で表示され、青→黄の色が付く。これを防止するために、プログラムの最初の部分で、
    plt.rcParams['image.cmap'] = 'gray'
と記述し、カラーマップを変更しておく。
 二値化では、代表的な方法として、「大津の方法」を採用した。

使用したメソッド等の説明
 あまり重要でない引数(パラメータ)は省略されている場合がある。
◎io.imread
 ファイルから画像を読み込むのに使用する。
   io.imread(
     fname ----------- 読込むファイル名、またはURL
     as_gray = False ---- Trueにすると、グレイスケール画像として読み込む
   )
 グレイスケールとして読み込むと、画像の形式は(M, N,)となる。
◎color.rgb2gray
 カラー画像をグレイスケール画像に変換する。
   color.rgb2gray(
     rgb ---------- RGBまたはRGBA形式のカラー画像
   )
 戻り値は、(M, N)型の画像である。
◎util.invert
  入力画像に対して、dtypeの最大値から差し引いた結果の画像を返す。
   util.invert(
     image -------- すべての入力画像
   )
◎filters.threshold_otsu
 大津の方法による二値化のしきい値(float型)を返す。
   filters.threshold_otsu(
      image -------- グレイスケール入力画像
      nbins = 256 --- ヒストグラムを採るのに用いるbinの数
   )
◎pyplot.imshow
 二次元座標上に画像を描画する。
   pyplot.imshow(
      X ------------------ すべての入力画像
      cmap = None --------- グレイスケール画像の場合のみ有効、デフォルトはrcParamsにより'viridis'(別途設定しない場合)
      aspect = None -------- アスペクト比、'auto'、'equal、''scalar'がある。デフォルトはrcParamsにより'equal'で原画像通り
      interpolation = None --- 内挿条件、'nearest'、'bilinear'、'bicubic'など多数。デフォルトはrcParamsにより'nearest'
   )



図1 ピクセル単位の画像処理プログラム



図2 ピクセル単位の画像処理の結果


【周辺ピクセルとの簡単な画像処理】
 ここで紹介するのは、画像処理としては本格的な処理で、注目するピクセルに対して、その周辺のピクセル・データとの演算を実行するものを取り上げる。ガウス平滑化は、周辺ピクセルに、ガウス分布に従った重みを掛ける積和演算を行い、中央値を求めるメディアンはすべての周辺ピクセルを調べる。エッジ検出方法では、代表的なsobelカーネルを使用する。
 filters.gaussian以外は、入力画像がグレイスケールに限られるので、あらかじめcolor.rgb2grayを用いた。
 プログラムを図3に、結果を図4に示す。
 ここでも、filters.medianとfilters.sobelは戻り値として、(M, N)形式のグレイスケール画像を返すので、plt.imshowのカラーマップを変更している。
 エッジ検出結果は、線画風の雰囲気を出すために、util.invertで反転してから表示させた。

使用したメソッド等の説明
 引数(パラメータ)は主要なもののみのことがある。
◎filters.gaussian
 一般的な平滑化で、ノイズ除去に用いられる。戻り値はカラーを含む画像である
   filters.gaussian(
     image ----------------- すべての入力画像
     sigma = 1 -------------- ガウス・カーネルの標準偏差
     mode = 'nearest' -------- 周辺部の処理方法、他に、'reflect'、 'constant'、 'mirror'、 'wrap'がある
     multichannel = None ----- Trueにすると、各チャンネル(R、G、B)を個別に実施することを明示する(カラーに警告が出ない)
   )
◎filters.median
 ゴマ塩のようなインパルスノイズの除去に適する。入力画像と同じグレイスケール画像を返す。
   filters.median(
     image ------------ グレイスケール入力画像
     selem = None ----- Noneの場合は、3 x 3のすべての周辺ピクセルを対象にする
   )
◎filters.sobel
 Sobelカーネルによる垂直方向と水平方向のエッジ検出結果を二乗和の平方根でグレイスケール画像として返す。
   filters.sobel(
     image --------- グレイスケール入力画像
   )



図3 周辺ピクセルとの画像処理プログラム



図4 周辺ピクセルとの画像処理の結果


【exposureを使った画像処理】
 exposureは写真用語で、「露出」(または「露光」)を意味する。露出は、撮影対象や照明、シャッタースピードなどによって決まり、写真としての出来栄えを左右する。
 写真画像には、全体として明るすぎたり、暗すぎたりする場合があり、コントラストの強すぎ、弱すぎもあるので、これを、撮影後に補正するのがexposureモジュールである。
 exposureモジュールには大別して、
 1)ヒストグラムを用いるもの
    equalize_hist -------- カラー画像ではなく、各カラーチャンネル毎の処理用なので、これだけでは使えない
    equalize_adapthist ---- カラー画像を直接使用でき、Contrast Limited Adaptive Histogramと言う高度な処理を行う
 2)入出力のトーンカーブを数学関数で設定するもの(いずれも、カラー画像の使用可)
    adjust_gamma ------- ガンマ特性による補正で、暗部または明部のコントラスト改善に適する
    adjust_sigmoid ------- シグモイド曲線による補正で、特に、中間部のコントラスト強調に適する
    adjust_log ---------- 顕著な作用はない
 3)入出力のトーンカーブを折れ線で設定するもの(カラー画像使用可)
    rescale_intensity ----- 入力値の最小と最大、出力値の最小と最大を与えて、間を直線で結ぶ、ヒストグラム補正の効果
 4)その他(いずれも、画像が直接得られるものではない)
    exposure.histogram --- ヒストグラムのデータを求めるだけの関数
    exposure.cumulative_distribution --- ヒストグラムの一種であるが、累積的な分布関数が得られる
    exposure.is_low_contrast --------- 入力画像のコントラストが低いとTrueが返る
がある。
 以上の結果から、equalize_adapthist、adjust_gamma、adjust_sigmoid、rescale_intensityについて、詳しく調べることにした。

使用したメソッドの説明
 引数(パラメータ)は主要なもののみのことがある。
◎exposure.equalize_adapthist
 局所的なコントラストに留意して、全体のコントラストを平坦化するCLAHE(Contrast Limited Adaptive Histogram Equalization)を用いる。
    exposure.equalize_adapthist(
        image --------------- すべての入力画像
        kernel_size = None ----- 特に指定しない場合のデフォルトは、全画像の縦横ともに 1 / 8(面積で 1 / 64)
        clip_limit = 0.01 -------- コントラスト強調を制限する比率、ゼロにしてはいけない
        nbins = 256 ----------- ヒストグラムを採るbinの数
    )
 exposure.equalize_histに比べると使い方が簡単で、カラー画像も使用でき、しかも優れた特性を有する。
◎exposure.adjust_gamma
 ガンマ補正を行う。
    exposure.adjust_gamma(
        image -------- すべての入力画像
        gamma = 1 ---- 正の実数(float型)、下記数式を参照
        gain = 1 ------ 倍率、下記数式を参照
    )
 gamma > 1では、暗部、中間部がより暗くなり、明部のコントラストが広がる。gamma < 1の場合は明部、中間部がより明るくなり、暗部のコントラスが広がる。数式は、
      image_out = gain * image_ingamma
◎exposure.adjust_sigmoid
 中間部で傾斜が急になるシグモイド曲線を描く関数を使用する。中間部のコントラスト増強に効果がある。
    exposure.adjust_sigmoid(
        image ------------ すべての入力画像
        cutoff = 0.5 ------- 中間点の濃度、下記数式を参照
        gain = 10 --------- コントラストの傾斜、下記数式を参照
        inv = False -------- これをTrueにすると、シグモイド曲線が反転する
    )
 カラー画像も扱うことができ、使い方が簡単である。シグモイド関数による補正後の画像が戻り値である。
 数式は、
      image_out = 1 / (1 + egain (cutoff - image_in))
◎exposure.rescale_intensity
 入力画像と出力画像それぞれに対する最小濃度値、最大濃度値を与えて、折れ線によるトーンカーブを使用する。
    exposure.rescale_intensity(
        image ------------ すべての入力画像
        in_range ---------- 入力画像の最小と最大の濃度値、(Vin_min、Vin_max)の2-tuple形式
        out_range --------- 出力画像の最小と最大の濃度値、(Vout_min、Vout_max)の2-tuple形式
        nbins = 256 ------- ヒストグラムを採るbinの数
    )
 コントラストの拡張または縮小後の後の画像が戻り値である。

コントラストの弱い画像の補正
 濃度が中間部に集中していて、全体的に眠たい画像が対象である。equalize_adapthist、adjust_sigmoid、rescale_intensityが有効であるので、これらを使用する。
 図5は、試行錯誤で最適のパラメータを使用したプログラムで、図6は得られた結果である。これによると、equalize_adapthist(局所的ヒストグラム平坦化)を用いると、デフォルト設定のままでも非常に優れた結果が得られた。


図5 コントラストが強まるように引数の設定を行う



図6 引数の設定により、コントラストがかなり高くなり改善されている


コントラストの強い画像の補正
 濃度が明部、暗部、またはその両方に集中していて、明部が飛んだり、暗部が潰れたりして、見づらい画像が対象である。equalize_adapthist、adjust_gamma、rescale_intensityが有効であるので、これらを使用する。
 図7は、試行錯誤で最適のパラメータを使用したプログラムで、図8は得られた結果である。これによると、equalize_adapthist(局所的ヒストグラム平坦化)を用いると、デフォルト設定のままでも非常に優れた結果が得られる。


図7 コントラストが弱まるように引数の設定を行う



図8 引数の設定により、コントラストが低くなり、暗部が見えてきた


局所的ヒストグラム平坦化について、パラメータclip_limitの効果を調べる
 図6および図8に示したように、exposure.equalize_adapthistを用いたコントラスト補正は、アルゴリズムにCLAHE(Contrast Limited Adaptive Histogram Equalization、「コントラスト制限付き適応コントラスト平坦化」と訳される)を用いていて、非常に優れた性能を示している。
 exposure.equalize_adapthistの場合、局所的に適応するためのブロックサイズはkernel_sizeで与えられ、デフォルトでは全画面の 1 / 8(面積では 1 / 64)であり、一般的にはこれで十分である。濃淡の少ない、同一濃度にヒストグラムが集中しやすいブロックでは濃淡が誇張されてノイズが発生するので、これを制限するために、パラメータclip_limitを用いる(デフォルトでは、 clip_limit = 0.01)。
 ここでは、kernel_sizeはデフォルトのままとし、clip_limitを変えて、その影響を確認した。
 図9はその結果で、clip_limitを下げるとコントラスト平坦化の効果が薄くなり、clip_limitを上げると、暗部がはっきりしてくるが、均一部分でのノイズが目立つ。この例では、デフォルト条件がほぼ良かった。

図9 exposure.equalize_adapthistの引数clip_limitを変えて影響を調べた