2017-06-15 15 views
0

私は画像を処理するためにVisionフレームワークを使用しています。私はそれを使用している関数は正常に実行されていると、完了ハンドラでエラーを返しませんが、結果は空です。顔の検出VNDetectFaceRectanglesRequest

これは私の関数である:関数の

func recognizeImage() { 
     let request = VNDetectFaceRectanglesRequest { (res: VNRequest, error: Error?) in 
      print("Reuslt : \(res.accessibilityActivationPoint)") 
     } 

     if let cgContet = image.image.cgImage { 
      let handler = VNImageRequestHandler(cgImage: cgContet) 
      try? handler.perform([request]) 
     } 
    } 

結果は次のとおりです。

Reuslt : (0.0, 0.0) 
+0

ここに正確に何を聞かれていますか? – rambossa

+0

@rambossaなぜ使用される関数がエラーなしで空の結果を返すのですか? –

答えて

3

かなり十分に確認するために、ここでの情報、おそらく...

顔認識はありません画像の向きを知る必要がある。 (正確には、どのようなピクセルの顔であるかどうかがわからないため、右上の顔のみを探すときには、はるかに簡単です。)

CGImageは、その情報を個別に取得してVNImageRequestHandlerイニシャライザthat takes an orientationのいずれかに渡す必要があります。

これらのイニシャライザは、EXIF方向値(別名CGImagePropertyOrientation)を使用します。 UIImageから始める場合、その列挙型の基礎となる数値はUIImageOrientationの数値と一致しないため、変換する必要があります。 sample code attached to the Vision session from WWDC17にそれを行う便利な方法があります。

3

あなたが顔を検出し、それぞれの四角形を描画したい場合は、これを試してみてください。

let request=VNDetectFaceRectanglesRequest{request, error in 
    var final_image=UIImage(named: image_to_process) 

    if let results=request.results as? [VNFaceObservation]{ 
     print(results.count, "faces found") 
     for face_obs in results{ 
      //draw original image 
      UIGraphicsBeginImageContextWithOptions(final_image.size, false, 1.0) 
      final_image.draw(in: CGRect(x: 0, y: 0, width: final_image.size.width, height: final_image.size.height)) 

      //get face rect 
      var rect=face_obs.boundingBox 
      let tf=CGAffineTransform.init(scaleX: 1, y: -1).translatedBy(x: 0, y: -final_image.size.height) 
      let ts=CGAffineTransform.identity.scaledBy(x: final_image.size.width, y: final_image.size.height) 
      let converted_rect=rect.applying(ts).applying(tf)  

      //draw face rect on image 
      let c=UIGraphicsGetCurrentContext()! 
      c.setStrokeColor(UIColor.red.cgColor) 
      c.setLineWidth(0.01*final_image.size.width) 
      c.stroke(converted_rect) 

      //get result image 
      let result=UIGraphicsGetImageFromCurrentImageContext() 
      UIGraphicsEndImageContext() 

      final_image=result! 
     } 
    } 

    //display final image 
    DispatchQueue.main.async{ 
     self.image_view.image=final_image 
    } 
} 


guard let ciimage=CIImage(image:image_to_process) else{ 
    fatalError("couldn't convert uiimage to ciimage") 
} 

let handler=VNImageRequestHandler(ciImage: ciimage) 
DispatchQueue.global(qos: .userInteractive).async{ 
    do{ 
     try handler.perform([request]) 
    }catch{ 
     print(error) 
    } 
} 
+1

私の* UIImageView *が* UIScrollView *に埋め込まれているときや向きが変わったときを含め、すべてのケースで役に立ちました。 StackOverflowの他の応答は、いくつかのシナリオ、特にピクセルバッファとライブカメラフィードを扱う際に役立ちましたが、これはほとんどの場合、UIImageには非常に役立ちました。 – ZbadhabitZ

+0

それが@ZbadhabitZを助けることができてうれしい! :) –

0

この問題は、私があまりにも夢中になるました。元の問題は、cgiImageまたはciiImageが正しく処理できない画像の向きであることが判明しました。私がどこかからコピーしたコードの中には、単純なキャスティング(画像は同じ順序ではない)によって、画像からcgiへの向きが間違って変換されています。

私はオリエンテーションコンバータを作成し、以下のコードは、私の作品:

let handler = VNImageRequestHandler(cgImage: image.cgImage!, orientation: self.convertImageOrientation(orientation: image.imageOrientation)) 

... 

func convertImageOrientation(orientation: UIImageOrientation) -> CGImagePropertyOrientation { 
    let cgiOrientations : [ CGImagePropertyOrientation ] = [ 
     .up, .down, .left, .right, .upMirrored, .downMirrored, .leftMirrored, .rightMirrored 
    ] 

    return cgiOrientations[orientation.rawValue] 
}