Vision Framework で水平角検出(傾き) Horizon Detection
iOS 11 関連記事
iOS 11 UIKit の変更点 - ObjecTips
iOS 11 Foundation の変更点 - ObjecTips
iOS 11 Messages Framework の変更点 - ObjecTips
iOS 11 PDFKit - ObjecTips
iOS 11 Core Image の変更点 - ObjecTips
koze.hatenablog.jp
Horizon Detection
Vision Framework を使って傾き検出と得られた結果から表示の補正を行う。
カメラロールの中に程良く傾いた景色の画像があったのでそれを使う。まず何も処理を入れず普通に UIImage
を作成して UIImageView
に配置する。
実装
Horizon Detection with Vision Framework
まず VNImageRequestHandler
を作成。
今回は UIImage
経由で CGImageRef
から作成している。
次に VNDetectHorizonRequest
作成しハンドラを設定してリクエストを実行する。
うまく傾きを検出できると request.results
に VNHorizonObservation
が入ってくる。
VNHorizonObservation
の持つプロパティは以下2つ
@property (readonly, nonatomic, assign) CGAffineTransform transform; @property (readonly, nonatomic, assign) CGFloat angle;
ドキュメントにもヘッダにも何も書かれていないけど、angle
は検出された傾きだろうという事が分かる。ちなみにこの値は radian になっている。
この angle
から以下の様に UIImageView
を補正表示するための CGAffineTransform
を作成する。
CGAffineTransform t = CGAffineTransformMakeRotation(-horizonObservation.angle);
これまで同様に座標系が逆になっているので結果の angle
にマイナス値をかけて値を補正している。
この CGAffineTransform
を UIImageView
に設定してやる。
実行結果
以下の様になる。
正しく傾きの補正が出来ている模様。
UIImageView
の中心をずらさずに回転のみで補正した形になる。
コメントアウト部分にある様に
CGAffineTransformInvert(CGAffineTransformMakeRotation(horizonObservation.angle));
この様に値を補正してやっても同じ結果になる。
実行結果2
検出結果の VNHorizonObservation
にもう1つプロパティがある。
@property (readonly, nonatomic, assign) CGAffineTransform transform;
これを使って UIImageView
を変形してみる。
検出結果の座標系は逆になっているので先の例と同じ様に Invert で補正してやる。
CGAffineTransformInvert(horizonObservation.transform);
結果は以下
傾きの補正はOKっぽい。
ただ位置の変形がこれでいいのかどうか、、?
transform
プロパティが何を表しているのか、どういった値が入ってくるのか現時点ではドキュメントも無いしWWDCのセッションもまだなので何かしら解説が出るのを待ってみたい。