2015-10-18 5 views
0

Я использую класс CIDetector в IOS, чтобы найти CIRectangleFeatures в моем UIImage. Впоследствии я стараюсь показать, что угловые точки нарисованы в слой, который я затем, в свою очередь, добавляю в свой UIImageView. К сожалению, координаты, заданные с помощью CIRectangleFeature, находятся в пространстве изображения. И хотя я пытаюсь преобразовать их с помощью функции CGContextConvertToUserSpace, рисованный прямоугольник совершенно не совпадает с фактическим прямоугольником в изображении.Преобразование из CIRectangleFeature координаты для просмотра координат

Вот мой код, когда берется изображение, workWithTheImage называется:

func analyzeImage(image: UIImage) -> [RectanglePoint] 
    { 
     guard let ciImage = CIImage(image: image) 
      else { return [] } 

     let context = CIContext(options: nil) 

     let detector = CIDetector(ofType: CIDetectorTypeRectangle, context: context, options: nil) 

     let features = detector.featuresInImage(ciImage) 

     UIGraphicsBeginImageContext(ciImage.extent.size) 
     let currentContext = UIGraphicsGetCurrentContext() 

     var points: [RectanglePoint] = [] 

     for feature in features as! [CIRectangleFeature] 
     { 
      let topLeft = CGContextConvertPointToUserSpace(currentContext, feature.topLeft) 
      let topRight = CGContextConvertPointToUserSpace(currentContext, feature.topRight) 
      let bottomRight = CGContextConvertPointToUserSpace(currentContext, feature.bottomRight) 
      let bottomLeft = CGContextConvertPointToUserSpace(currentContext, feature.bottomLeft) 

      let point = RectanglePoint(bottomLeft: bottomLeft, topLeft: topLeft, bottomRight: bottomRight, topRight: topRight) 
      points.append(point) 
     } 

     UIGraphicsEndImageContext() 
     return points 
    } 



    func workWithImage(image: UIImage) 
    { 
     let imageView = UIImageView(frame: view.frame) 
     imageView.image = image 

     let path = UIBezierPath() 
     let shapeLayer = CAShapeLayer() 
     shapeLayer.frame = imageView.bounds 

     for i in analyzeImage(image) 
     { 
      path.moveToPoint(i.topLeft) 
      path.addLineToPoint(i.topRight) 
      path.addLineToPoint(i.bottomRight) 
      path.addLineToPoint(i.bottomLeft) 
      path.addLineToPoint(i.topLeft) 
     } 

     shapeLayer.path = path.CGPath 
     shapeLayer.fillColor = UIColor.clearColor().CGColor 
     shapeLayer.strokeColor = UIColor.redColor().CGColor 

     imageView.layer.addSublayer(shapeLayer) 
    } 
+0

вы можете также разместить образец изображения? CIDetector не слишком точен. –

ответ

2

Если ваш путь только от в измерении Y:

Я думаю, что они не в полной мере портированный CIDetector до UIKit. Координаты функции находятся в системе координат Какао. Просто сделать container.height - point.y будет конвертировать его.

Я также дал вашей структуре правильное имя. Остальная часть материала там, я использовал, чтобы выяснить, что происходит. Может быть полезно для вас.

Код:

func analyzeImage(image: UIImage) -> [Quadrilateral] 
{ 
    guard let ciImage = CIImage(image: image) 
     else { return [] } 

    let flip = true // set to false to prevent flipping the coordinates 

    let context = CIContext(options: nil) 

    let detector = CIDetector(ofType: CIDetectorTypeRectangle, context: context, options: [CIDetectorAccuracy:CIDetectorAccuracyHigh]) 

    let features = detector.featuresInImage(ciImage) 

    UIGraphicsBeginImageContext(ciImage.extent.size) 
    let currentContext = UIGraphicsGetCurrentContext() 

    var frames: [Quadrilateral] = [] 

    for feature in features as! [CIRectangleFeature] 
    { 
     var topLeft = CGContextConvertPointToUserSpace(currentContext, feature.topLeft) 
     var topRight = CGContextConvertPointToUserSpace(currentContext, feature.topRight) 
     var bottomRight = CGContextConvertPointToUserSpace(currentContext, feature.bottomRight) 
     var bottomLeft = CGContextConvertPointToUserSpace(currentContext, feature.bottomLeft) 

     if flip { 
      topLeft = CGPoint(x: topLeft.x, y: image.size.height - topLeft.y) 
      topRight = CGPoint(x: topRight.x, y: image.size.height - topRight.y) 
      bottomLeft = CGPoint(x: bottomLeft.x, y: image.size.height - bottomLeft.y) 
      bottomRight = CGPoint(x: bottomRight.x, y: image.size.height - bottomRight.y) 
     } 

     let frame = Quadrilateral(topLeft: topLeft, topRight: topRight, bottomLeft: bottomLeft, bottomRight: bottomRight) 

     frames.append(frame) 
    } 

    UIGraphicsEndImageContext() 
    return frames 
} 

Четырехугольник структура:

struct Quadrilateral { 
    var topLeft : CGPoint = CGPointZero 
    var topRight : CGPoint = CGPointZero 
    var bottomLeft : CGPoint = CGPointZero 
    var bottomRight : CGPoint = CGPointZero 

    var path : UIBezierPath { 
     get { 
      let tempPath = UIBezierPath() 
      tempPath.moveToPoint(topLeft) 
      tempPath.addLineToPoint(topRight) 
      tempPath.addLineToPoint(bottomRight) 
      tempPath.addLineToPoint(bottomLeft) 
      tempPath.addLineToPoint(topLeft) 
      return tempPath 
     } 
    } 

    init(topLeft topLeft_I: CGPoint, topRight topRight_I: CGPoint, bottomLeft bottomLeft_I: CGPoint, bottomRight bottomRight_I: CGPoint) { 
     topLeft = topLeft_I 
     topRight = topRight_I 
     bottomLeft = bottomLeft_I 
     bottomRight = bottomRight_I 
    } 

    var frame : CGRect { 
     get { 
      let highestPoint = max(topLeft.y, topRight.y, bottomLeft.y, bottomRight.y) 
      let lowestPoint = min(topLeft.y, topRight.y, bottomLeft.y, bottomRight.y) 
      let farthestPoint = max(topLeft.x, topRight.x, bottomLeft.x, bottomRight.x) 
      let closestPoint = min(topLeft.x, topRight.x, bottomLeft.x, bottomRight.x) 

      // you might want to set origin to (0,0) 
      let origin = CGPoint(x: closestPoint, y: lowestPoint) 
      let size = CGSize(width: farthestPoint, height: highestPoint) 

      return CGRect(origin: origin, size: size) 
     } 
    } 

    var size : CGSize { 
     get { 
      return frame.size 
     } 
    } 

    var origin : CGPoint { 
     get { 
      return frame.origin 
     } 
    } 
} 
+0

@R Menke, можете ли вы дать решение в объективе c, Pls –