2017-06-28 1 views
1

Je suis coincé avec un problème. Comment puis-je définir le point lumineux sur l'image binarisée. J'utilise ios11 et Vision maintenant.iOS Vision détecter la lumière sur l'image binarisée

J'utilise le filtre de binarisation CIColorControls (également essayé de combiner cela avec CIColorInvert). Pour la détection de la lumière, j'utilise VNImageRequestHandler avec VNDetectRectanglesRequest. Dans VNDetectRectanglesRequest Je vérifie pour VNDetectedObjectObservation Mais ne peut pas atteindre la détection de trame 100% (parfois app ne peut pas reconnaître le point de lumière sur les cadres). Qu'est ce que je fais mal? Apprécierait toute aide

Voici mon code

lazy var rectanglesRequest: VNDetectRectanglesRequest = { 
     return VNDetectRectanglesRequest(completionHandler: self.handleRectangles) 
    }() 

func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) { 
      connection.videoOrientation = AVCaptureVideoOrientation.portrait 
      guard let uiImage = imageFromSampleBuffer(sampleBuffer: sampleBuffer) else { return } 

      let correctedImage = uiImage 
       .applyingFilter("CIColorControls", withInputParameters: [ 
        kCIInputSaturationKey: 0, 
        kCIInputContrastKey: 4.5, 
        kCIInputBrightnessKey: -1.54 
        ]) 
       //.applyingFilter("CIColorInvert", withInputParameters: nil) 
       self.searchLightSpot(ciImage: correctedImage) 

      DispatchQueue.main.async { [unowned self] in //unowned 
       self.frameImageView.image = UIImage(ciImage: correctedImage) 
      } 
     } 

func searchLightSpot(ciImage: CIImage) { 
     var requestOptions: [VNImageOption: Any] = [:] 
     let handler = VNImageRequestHandler(ciImage: ciImage, options: requestOptions) 
     DispatchQueue.global(qos: .userInteractive).async { 
      do { 
       try handler.perform([self.rectanglesRequest]) 
      } catch { 
       print(error) 
      } 
     } 
    } 

func handleRectangles(request: VNRequest, error: Error?) { 
     guard let observations = request.results as? [VNDetectedObjectObservation] 
      else { 
       print("unexpected result type from VNDetectedObjectObservation") 
       return 
     } 
     guard let detectedObject = observations.first else { 
       print("not detected object") 
      return 
     } 

     print("detected object: ", detectedObject) 
    } 

enter image description here

Répondre

0

Après avoir fait des recherches supplémentaires, je compris qu'il semble comme Apple faire des optimisations supplémentaires avec des cadres

Par exemple, si nous obtenons la lumière dans la 1ère image et les 5 images suivantes seraient les mêmes Il nous montrera le même cadre donc à la place 5 images - nous avons seulement 1 Cela signifie que nous ne pouvons pas relaient nombre statique de cadres en deuxième position avec 100% sûr

Je ne peut pas détecter la durée du signal et ainsi de suite ....

Une des solutions possibles peuvent être:

1 Nous pouvons démarrer notre minuterie qui obtiendra l'image actuelle de la caméra (par exemple chaque 100ms)

2. Ensuite, nous allons vérifier si le cadre a un point blanc. Sur la base de ces résultats de Histogramme enter image description here

y - couleur (0/1 affiche si la couleur blanche existe sur le cadre)

x - timeline (ms)

3. Ainsi, la sortie de cette diagramme pourrait être

[01111100001111…] 

4. Ensuite, nous pouvons analyser et détecter le signal

Vous pouvez utiliser EasyImagy et écrire votre propre extension de binariser et détecter des taches blanches

extension Image where Pixel == RGBA { 

     fileprivate func getPixelCount() -> Int { 
      return Int(10 * width/100) 
     } 

     func binarize() -> (isWhite: Bool, binarizedImage: Image<RGBA>) { 

      var kWidth = 0 
      var img = self 
      let pixelCount = getPixelCount() 
      for x in 0..<width{ 
       var kHeight = 0 
       for y in 0..<height { 

        if let _pixel = pixel(x, y) { 
         if _pixel.gray < 245 { 
          img[x, y] = .black 
          kHeight = 0 
         } else { 
          img[x, y] = .white 
          kHeight += 1 
         } 

         if kHeight > pixelCount { 
          kWidth += 1 
          break 
         } 
        } 
       } 
       print("Hwhite: \(kHeight) Wwhite: \(kWidth)") 
       if kHeight >= pixelCount && kWidth >= pixelCount { 
        return (true, img) 
       } 
      } 
      return (false, img) 
     } 
    }