2017. 8. 16.
石立 喬

Visual C#とWin2DによるUWPでの画像処理(2)

――― 積和演算、色変換、明暗部強調などの画像処理Effectクラスを使用する ―――

 Win2Dには、数多くの画像処理用クラスがある。Visual C#を用いての、それらの使用方法については、「Visual C#とWin2DによるUWPでの画像処理(1)」で概略を述べた。ここでは、周辺ピクセルとの積和演算、ピクセル単独の色変換を行う各画像処理Effectクラスやコントラストの増減に有効なHighlightsAndShadowsEffectクラスについて、プロパティを変化させてその効果を確認した。

注目するピクセルと、その周辺ピクセルを含めた積和演算による画像処理の代表例
 この種の画像処理の例として、GaussianBlurEffect、SharpenEffect、EdgeDetectionEffectの3種について試みた結果を下記に示す。すべに説明したC#コードにおいて、各画像処理Effectクラスのプロパティを設定するだけで良いので、プログラムは省略する。これらに共通して使用した原画像を図1に示す。


図1 ここで共通して使用した原画像


◎GaussianBlurEffectクラス
 平滑化、ぼかしと呼ばれる処理で、ガウス分布に従った重みを掛けて加算(積和演算)して処理結果とする。平滑化単独での用途は少なく、多くは、後述のエッジ検出などの前処理として使用される。画像の部分的なぼかしは、個人情報保護などに用いられる。  BlurAmountプロパティのデフォルトは3であるが、試行結果によれば、ここで使用したような小型画像に対してはボケの度合いが強すぎるようであるので、デフォルトより小さい値を設定して比較した。
 BorderModeプロパティには、EffectBorderMode.Hardを設定してある(デフォルトはSoftで、この場合は原画像の周辺も含めて平滑化されるので、原画像の外にボケが現れる)。

BlurAmount = 0.5 BlurAmount = 1.0
BlurAmount = 1.5 BlurAmount = 2.0

図2 GaussianBlurEffectクラスによる画像処理の結果


◎SharpenEffectクラス
 鮮鋭化と呼ばれる処理で、注目するピクセルと周辺ピクセルとの違いを拡大させるように重みづけして積和演算を行い、処理結果とする。ピントの甘い画像を引き立たせるのに用いられる。解像度を高めて画像情報を増やすわけではないので、過度な鮮鋭化は違和感が生じる。Amountプロパティの範囲は0~10で、デフォルトは0である。図3に結果によれば、目的にもよるが、このサイズの例では、Amount = 0.5~1.0が適度であった。

Amount = 0.5 Amount = 1.0
Amount = 1.5 Amount = 2.0

図3 SharpenEffectクラスによる画像処理の結果


◎EdgeDetectionEffectクラス
 エッジ検出は、物体の形状を明確にしやすいので、認識の前処理として用いられることが多い。結果が線画のようになるので、線画化を目的としても使用できる。
 Amountプロパティ(検出感度)の範囲は0~1で、デフォルトは0.5である。この値を大きくすると、僅かなエッジでも検出する。目的にもよるが、この例では、Amount = 0.5(デフォルト値)が手ごろである。
 BlurAmountプロパティは、エッジ検出前のノイズ除去前処理としての平滑化の度合いで、デフォルトは0、範囲は0~10である。ここでは、デフォルトのままとし、実施していない。
 Modeプロパティは、デフォルトのEdgeDetectionEffectMode.Sobelのままとした。Prewitt(平滑化効果がやや強い)も選択できる。
 一定の閾値を設け、1、0(白、黒)で判定する方が良いと思うが、その機能はなく、エッジ強度の大小がそのまま濃淡で現れている。
 図4は、EdgeDetectionEffectの結果を、InvertEffectで反転してある。使用目的にもよるが、Amountを大きくするとノイズが出すぎる。

Amount = 0.2 Amount = 0.3
Amount = 0.4 Amount = 0.5

図4 EdgeDetectionEffectクラスによる画像処理の結果


注目するピクセル単独に色変換を行う演算処理の代表例
◎PosterizeEffectクラス
 日本語でもポスタライズと呼ばれ、使用する色の数を減らして表示することを意味する。掲示するポスターを印刷するのに、インクを節約するために色数を減らしたところからこの名称がある。絵を描くときに、絵の具の種類を減らすような効果があり、より絵画的に変換できる。BlueValueCount、GrayValueCount、RedValueCount各プロパティの範囲は2~16で、デフォルトは4である。プロパティ値が4の場合は、RGBを0~255で表すとして、0、85、170、255しか使わないことに相当する。図5の結果を見ると、ValueCountを8程度に下げても、原画像との顕著な差は見られない。

各色ValueCount = 16 各色Value Count = 8
各色ValueCount = 4 各色ValueCount = 2

図5 PosterizeEffectクラスによる画像処理の結果


◎SaturationEffectクラス
 HSV(Hue、Saturation、Value)表色系でのSaturation(彩度)を調節する。Saturationが大きいほど原色に近づく。Saturationプロパティの範囲は0~1で、デフォルトは0..5である。Saturation = 0にすると、グレイスケール画像になる。図6の結果を見ると、この画像に限り、Saturationの影響は顕著でない。

Saturation = 1.0 Saturation = 0.8
Saturation = 0.6 Saturation = 0.4

図6 SaturationEffectクラスによる画像処理の結果


◎HueRotationEffectクラス
 Angleプロパティの範囲は0~2π(実際に数値を入れて確認した結果、入力した負の数をaとすると、自動的に2π - aになることが分かった)で、デフォルトは0である。図7の結果が示すように、Angleを正方向に増やすと緑がかってくる。Angleを負方向に増加すると(Angleの範囲は0~2πなので、2πから引いて設定、実際には負の値を入れても問題ない)、赤みがかってくる。原画像は3月ごろに撮った写真なので、Angleを負方向に回転させて温かみを持たせると良いかもしれない。

Angle = 0.1π Angle = 0.2π
Angle = 1.9π(= -0.1π) Angle = 1.8π(= -0.2π)

図7 HueRotationEffectクラスによる画像処理の結果


HighlightsAndShadowsEffectを使った改善の例
 HighlightsAndShadowsEffectクラスを使用すると、画像の白飛びや黒潰れを改善することができる。ここではプログラムを示して結果を紹介する。
 図8は、HighlightsAndShadowsEffectクラス3種類の宣言と、タイトルの表示の部分である。図9はCreateResourcesAsyncメソッドの内容で、原画像としてchesky.jpg(暗部に潰れがある画像の例)を読み込み、HighlightsAndShadowsEffectを設定する。

◎highlightsAndShadowsEffectクラス
 明部、暗部および中間部に分けて、そのコントラストを増減できる画像処理クラスで、主要なプロパティは下記から成る。
    Clarity ------- 中間部のコントラストの増減に用いる、デフォルトは0、範囲は-1~1である
    Highlights ----- 明部のコントラストの増減に用いる、デフォルトは0、範囲は-1~1である
    Shadows ------ 暗部のコントラストの増減に用いる、デフォルトは0、範囲は-1~1である
    MaskBlurAmount --- 明部か暗部かを判定する領域の範囲、小さい値は範囲が狭い、デフォルトは1.25、範囲は0~10
 MaskBlurAmountについては、寄与度は大きくないものの、画像によって最適値があった。試行錯誤の結果、図11に示す例では5を、図12の例では最大の10を用いた。
◎DrawTextメソッド
 多くのオーバーロードがある中で、ここでは
   DrawText(
     string        string, ------- 表示する文字列
     float        x, ----------- Canvas上のX座標
     float        y, ----------- Canvas上のY座標
     Color        color, ------- 表示色、Colors.Blackなど
     CanvasTextFormat  format --- 文字列のフォーマット、別途CanvasTextFormatクラスを設定する
   )
を使用した。CanvasTextFormatクラスは名前空間Windows.UI.Textに属し、FontFamily、FontStyle、FontSizeなどのプロパティがある。ここでは、FontSizeのみを設定し、他はデフォルトを使用した。

 図10はCanvasに画像処理結果を表示するためのメソッドで、文字列を表示させるためのFontSizeの設定とDrawTextメソッドが含まれている。


図8 HilightsAndShadowsクラスを3種類宣言する



図9 原画像を読み込み各プロパティを設定する



図10 画像と文字列を表示する


 図11は、暗部に潰れがある原画像の改善例で、Clarityによる中間部のコントラスト拡大とShadowsによる暗部の拡大の両者を併用すると良い結果が得られる。


図11 HilightsAndShadowsEffectクラスにより暗部の潰れを改善した結果


 図12は、明暗に乏しい原画像の例で、Clarityによる中間部の改善とShadowsによる暗部の改善をしても十分な結果が得られていない。Clarityを最大限にした上で、HighlightsとShadowsを抑えた結果がやや良かった。このプログラムは紹介しないが、容易に類推できると思う。


図12 HilightsAndShadowsEffectクラスによりコントラスの不足を改善した結果


単純なContrastEffectクラスによる結果との比較
 すでに紹介したContrastEffectクラスにおいて、Contrastプロパティを弱める方向の最大である-1と、強める方向の最大である1を使ってみた。操作が簡単であるメリットはあるが、性能的には、HighlightsAndShadowsEffectクラスを使用して細かく調整した方が、優れていることが分かった。

Contrast = -1 Contrast = 1

図13 ContrastEffectクラスを用いた結果、HighlightsAndShadowsEffectの方が優れている


感想
 Win2Dには多くの画像処理用クラスが用意されていて手軽に使用できるのはありがたい。しかし、閾値を与えたり自動で求めたりして行う二値化処理、ヒストグラムを使用したヒストグラム平坦化や拡張処理が無いのが残念である。ここで使用したコントラスト処理は、著しくコントラストの劣った画像の改善には十分でなかった。







「Visual C++の勉強部屋」(目次)へ