Xamarin.iOS の Core Image
Core Image は、画像処理とライブ ビデオ拡張機能を提供するために iOS 5 で導入された新しいフレームワークです。 この記事では、Xamarin.iOS サンプルを使用してこれらの機能について説明します。
Core Image は、iOS 5 で導入された新しいフレームワークであり、顔検出など、画像やビデオに適用する組み込みのフィルターや効果を多数提供します。
このドキュメントには、次の簡単な例が含まれています。
- 顔検出。
- 画像にフィルターを適用する。
- 使用可能なフィルターを一覧表示する。
これらの例は、Core Image 機能を Xamarin.iOS アプリケーションに組み込む作業を開始するのに役立ちます。
要件
最新バージョンの Xcode を使用する必要があります。
顔検出
Core Image の顔検出機能はその名の通り、写真内の顔の識別を試み、認識した顔の座標を返します。 この情報は、画像内の人の数を数えたり、画像上にインジケーターを描画したり (写真内の人物を "タグ付け" する場合など)、その他思いつく限りのあらゆる用途に使用できます。
CoreImage\SampleCode.cs の次のコードは、埋め込み画像で顔検出を作成して使用する方法を示しています。
var image = new UIImage("photoFace.JPG");
var context = CIContext.FromOptions(null);
var detector = CIDetector.CreateFaceDetector (context, true);
var ciImage = CIImage.FromCGImage(image.CGImage);
CIFeature[] features = detector.FeaturesInImage(ciImage);
特徴配列には CIFaceFeature
オブジェクトが設定されます (顔が検出された場合)。 顔ごとに CIFaceFeature
があります。 CIFaceFeature
には、次のプロパティがあります。
- HasMouthPosition – この顔に対して口が検出されたかどうか。
- HasLeftEyePosition – この顔に対して左目が検出されたかどうか。
- HasRightEyePosition – この顔に対して右目が検出されたかどうか。
- MouthPosition – この顔の口の座標。
- LeftEyePosition – この顔の左目の座標。
- RightEyePosition – この顔の右目の座標。
これらのプロパティの座標は、左上を原点として使用する UIKit とは異なり、左下に原点があります。 CIFaceFeature
で座標を使用するときは、必ずそれらを "反転" してください。 CoreImage\CoreImageViewController.cs にあるこの非常に基本的なカスタム イメージ ビューは、画像に "顔インジケーター" の三角形を描画する方法を示しています (FlipForBottomOrigin
メソッドに注目してください)。
public class FaceDetectImageView : UIView
{
public Xamarin.iOS.CoreImage.CIFeature[] Features;
public UIImage Image;
public FaceDetectImageView (RectangleF rect) : base(rect) {}
CGPath path;
public override void Draw (RectangleF rect) {
base.Draw (rect);
if (Image != null)
Image.Draw(rect);
using (var context = UIGraphics.GetCurrentContext()) {
context.SetLineWidth(4);
UIColor.Red.SetStroke ();
UIColor.Clear.SetFill ();
if (Features != null) {
foreach (var feature in Features) { // for each face
var facefeature = (CIFaceFeature)feature;
path = new CGPath ();
path.AddLines(new PointF[]{ // assumes all 3 features found
FlipForBottomOrigin(facefeature.LeftEyePosition, 200),
FlipForBottomOrigin(facefeature.RightEyePosition, 200),
FlipForBottomOrigin(facefeature.MouthPosition, 200)
});
path.CloseSubpath();
context.AddPath(path);
context.DrawPath(CGPathDrawingMode.FillStroke);
}
}
}
}
/// <summary>
/// Face recognition coordinates have their origin in the bottom-left
/// but we are drawing with the origin in the top-left, so "flip" the point
/// </summary>
PointF FlipForBottomOrigin (PointF point, int height)
{
return new PointF(point.X, height - point.Y);
}
}
次に、SampleCode.cs ファイルで画像と特徴が割り当てられてから、画像が再描画されます。
faceView.Image = image;
faceView.Features = features;
faceView.SetNeedsDisplay();
スクリーンショットはサンプル出力を示しています。検出された顔の特徴の場所は UITextView に表示され、CoreGraphics を使用してソース画像に描画されます。
顔認識の仕組みにより、人間の顔以外のもの (これらのおもちゃのサルなど) も検出されることがあります。
フィルター
50 を超えるさまざまな組み込みフィルターがあり、フレームワークは拡張可能であるため、新しいフィルターを実装できます。
フィルターの使用
画像にフィルターを適用するには、画像の読み込み、フィルターの作成、フィルターの適用、結果の保存 (または表示) という 4 つの異なる手順があります。
まず、画像を CIImage
オブジェクトに読み込みます。
var uiimage = UIImage.FromFile ("photo.JPG");
var ciimage = new CIImage (uiimage);
次に、フィルター クラスを作成し、そのプロパティを設定します。
var sepia = new CISepiaTone();
sepia.Image = ciimage;
sepia.Intensity = 0.8f;
3 番目に、OutputImage
プロパティにアクセスし、CreateCGImage
メソッドを呼び出して最終結果をレンダリングします。
CIImage output = sepia.OutputImage;
var context = CIContext.FromOptions(null);
var cgimage = context.CreateCGImage (output, output.Extent);
最後に、ビューに画像を割り当てて結果を確認します。 実際のアプリケーションでは、結果の画像はファイルシステム、フォト アルバム、ツイート、または電子メールに保存される可能性があります。
var ui = UIImage.FromImage (cgimage);
imgview.Image = ui;
これらのスクリーンショットは、CoreImage.zip サンプル コードで示されている CISepia
と CIHueAdjust
の各フィルターの結果を示しています。
CIColorControls
フィルターの例については、画像レシピのコントラストと明るさの調整に関するページを参照してください。
var uiimage = UIImage.FromFile("photo.JPG");
var ciimage = new CIImage(uiimage);
var hueAdjust = new CIHueAdjust(); // first filter
hueAdjust.Image = ciimage;
hueAdjust.Angle = 2.094f;
var sepia = new CISepiaTone(); // second filter
sepia.Image = hueAdjust.OutputImage; // output from last filter, input to this one
sepia.Intensity = 0.3f;
CIFilter color = new CIColorControls() { // third filter
Saturation = 2,
Brightness = 1,
Contrast = 3,
Image = sepia.OutputImage // output from last filter, input to this one
};
var output = color.OutputImage;
var context = CIContext.FromOptions(null);
// ONLY when CreateCGImage is called do all the effects get rendered
var cgimage = context.CreateCGImage (output, output.Extent);
var ui = UIImage.FromImage (cgimage);
imgview.Image = ui;
var context = CIContext.FromOptions (null);
var context = CIContext.FromOptions(new CIContextOptions() {
UseSoftwareRenderer = true // CPU
});
var cgimage = context.CreateCGImage (output, output.Extent);
var ui = UIImage.FromImage (cgimage);
imgview.Image = ui;
フィルターとそのプロパティの一覧表示
CoreImage\SampleCode.cs のこのコードは、組み込みフィルターとそのパラメーターの完全なリストを出力します。
var filters = CIFilter.FilterNamesInCategories(new string[0]);
foreach (var filter in filters){
display.Text += filter +"\n";
var f = CIFilter.FromName (filter);
foreach (var key in f.InputKeys){
var attributes = (NSDictionary)f.Attributes[new NSString(key)];
var attributeClass = attributes[new NSString("CIAttributeClass")];
display.Text += " " + key;
display.Text += " " + attributeClass + "\n";
}
}
CIFilter クラス リファレンスでは、50 個の組み込みフィルターとそのプロパティについて説明しています。 上記のコードを使用すると、パラメータの既定値や許容される最大値と最小値 (フィルターを適用する前に入力を検証するために使用できます) など、フィルター クラスに対してクエリを実行できます。
リスト カテゴリの出力は、シミュレーターでは次のようになります。リストをスクロールして、すべてのフィルターとそのパラメータを表示できます。
一覧表示されている各フィルターは Xamarin.iOS のクラスとして公開されているため、アセンブリ ブラウザーで Xamarin.iOS.CoreImage API を探索したり、Visual Studio for Mac または Visual Studio でオートコンプリートを使用したりすることもできます。
まとめ
この記事では、顔検出や画像へのフィルターの適用など、iOS 5 Core Image フレームワークの一部の新機能の使用方法について説明しました。 フレームワークには、使用できるさまざまな画像フィルターが多数あります。