iOS VisionFramework 矩形検知(VNDetectRectanglesRequest)のTips

iOS11 で登場した 画像認識機能を実現する VisionFramework。

その一つである、画像から矩形（長方形）を検知する VNDetectRectanglesRequest を使ってみた。
驚くほど簡単に使えたものの、細かいパラメータの機能が[API Document](https://developer.apple.com/documentation/vision/vndetectrectanglesrequest)にも載っておらず、わからなかったので動かして調べて見たメモ。


(Xcode9.2 時点）

こんな感じで簡単に使える

```swift
let handler = VNImageRequestHandler(ciImage: ciImage, orientation: CGImagePropertyOrientation.up, options: [:])
let request = VNDetectRectanglesRequest(completionHandler: {(request, error) in
    request.results?.map { result in
       // VNDetectRectanglesRequest の結果は VNRectangleObservation で返却される
       let observation = result as! VNRectangleObservation
       observation.topLeft // 認識対象の左上の点、topRight、bottomRight、topLeftも同様
       observation.boundingBox // 認識対象を包括する矩形
       observation.confidence // 信頼度: 現在1.0固定で帰ってくる
       return Observation
    }
})

/**
* Requestのパラメータ設定
*/

// request.maximumObservations = 1
// request.minimumAspectRatio = 0.2
// request.minimumConfidence = 0.5
// request.quadratureTolerance = 10.0
// request.regionOfInterest = CGRect(x: 0.25, y: 0.25, width: 0.5, height: 0.5)

try! handler.perform([request])

```

### 認識例
青い線が `boundingRect`

![名称未設定3.png](https://qiita-image-store.s3.amazonaws.com/0/46981/00592fab-bf39-3bec-831b-ffefc9334b2e.png)

## VNDetectRectanglesRequest
矩形認識のリクエストを行うオブジェクト。
なお、パラメータの CGPoint や CGRect は、CGRect(0,0,1.0,1.0)を基準としたCoreGraphic準拠の座標になっており、UIViewに反映する場合は変換する必要がある。

以下は各パラメータについて

### maximumObservations
default: 1
認識する矩形の数の最大値。defaultは1になっているので、その場合は、対象の画像に複数個矩形がある場合も１つしか認識されない。
その場合、中央寄り(0.5,0.5)にある矩形を認識するようになっている気がする。

ちなみに前掲の画像の場合、1から2に変更すると、内側の枠を探して認識をしてしまう。

| maximumObservations=1 | maximumObservations=2 |
|:---:|:---:|
|![名称未設定3.png](https://qiita-image-store.s3.amazonaws.com/0/46981/9c616200-d85c-648b-e347-840c09594d13.png)|![名称未設定２.png](https://qiita-image-store.s3.amazonaws.com/0/46981/e07c300e-a18f-20f5-a7ec-3fe2f72b7b3f.png)|

### minimumSize
default: 0.2
認識できる対象物の最小の閾値。
1.0 にすると理論上は画面いっぱいにならないと認識されない？

### minimumAspectRatio
default: 0.5
認識対象とする矩形のアスペクト比（長辺と短編の比率）。
認識したい対象のアスペクト比が決まっている場合に有効に機能しそう。

ここがデフォルトのままだと、以下のように1:2以上の長方形は認識されない。

| minimumAspectRatio=0.5(default) | maximumObservations=0.2 |
|:---:|:---:|
|![名称未設定.png](https://qiita-image-store.s3.amazonaws.com/0/46981/a792fcd4-00cc-f04e-5133-d8838031290d.png)|![名称未設定2.png](https://qiita-image-store.s3.amazonaws.com/0/46981/0c9f7d44-4a45-5bc1-cf36-83c4e063c7f9.png)|

### maximumAspectRatio
default: 1.0
minimumAspectRatio　と同様。

### minimumConfidence
default: 0.0
最低確信度。
`VNRectangleObservation.confidence` と対応している値と思われるが、 そちらは 1.0の固定が帰ってくるので、このパラーメータは機能しないと思われる。

### quadratureTolerance
default: 30.0
直訳すると直交の誤差(？)。
認識を許容する角度のことだと思われる。
ここを小さくすると、歪んだ矩形や、斜めからカメラを向けた場合に対象物が認識されなくなる。

### regionOfInterest
default: CGRect(0.0, 0.0, 1.0, 1.0)
認識対象を探索する画像の対象範囲。
CGRect(0.25, 0.25, 0.5, 0.5) にすると、中央50%の領域しか認識されない。

## VNRectangleObservation
矩形が認識された場合は、この型で返却される。
以下はプロパティ。

### topLeft, topRight, bottomLeft, bottomRight
それぞれ、認識対象の左上、右上、左下、右下の座標。
CGPointで 左上であれば(0.0, 1.0)、右下であれば(1.0, 0.0)のように返却される。

### boundingBox
認識対象を包括する矩形(CGRect)

### confidence
現在1.0固定でしか返却されない。
他の種類のRequestでは機能しているものと思われる。

### uuid
認識する毎に生成される。
そのため、動画でフレーム毎に認識させる場合では、同一オブジェクトかどうかの判定には使えない。

参考: 
https://developer.apple.com/videos/play/wwdc2017/506/
https://developer.apple.com/documentation/vision
https://developer.apple.com/documentation/vision/vndetectrectanglesrequest