В настоящее время я использую CIDetector для обнаружения прямоугольников в моем UIImage. Я делаю предложенный способ передачи координат в фильтр, чтобы вернуть CIImage, чтобы переместить полученный UIImage. Это выглядит следующим образом:Представьте CIRectangleFeature с UIBezierPath - Swift
func performRectangleDetection(image: UIKit.CIImage) -> UIKit.CIImage? {
var resultImage: UIKit.CIImage?
let detector:CIDetector = CIDetector(ofType: CIDetectorTypeRectangle, context: nil, options: [CIDetectorAccuracy : CIDetectorAccuracyHigh])
// Get the detections
let features = detector.featuresInImage(image)
for feature in features as! [CIRectangleFeature] {
resultImage = self.drawHighlightOverlayForPoints(image, topLeft: feature.topLeft, topRight: feature.topRight,
bottomLeft: feature.bottomLeft, bottomRight: feature.bottomRight)
}
return resultImage
}
func drawHighlightOverlayForPoints(image: UIKit.CIImage, topLeft: CGPoint, topRight: CGPoint,
bottomLeft: CGPoint, bottomRight: CGPoint) -> UIKit.CIImage {
var overlay = UIKit.CIImage(color: CIColor(red: 1.0, green: 0.55, blue: 0.0, alpha: 0.45))
overlay = overlay.imageByCroppingToRect(image.extent)
overlay = overlay.imageByApplyingFilter("CIPerspectiveTransformWithExtent",
withInputParameters: [
"inputExtent": CIVector(CGRect: image.extent),
"inputTopLeft": CIVector(CGPoint: topLeft),
"inputTopRight": CIVector(CGPoint: topRight),
"inputBottomLeft": CIVector(CGPoint: bottomLeft),
"inputBottomRight": CIVector(CGPoint: bottomRight)
])
return overlay.imageByCompositingOverImage(image)
}
Вызов performRectangleDetection отображает обнаруженный прямоугольник через CIImage.
Это похоже на изображение выше. Мне нужно отобразить тот же красный прямоугольник с UIBezierPath, который настроен на обводку. Мне нужно иметь это, чтобы пользователь мог настроить обнаружение, если он не на 100% точным. Я попытался проложить путь, но он не увенчался успехом. Вот как я рисую путь. Я использую собственный класс rect, чтобы удерживать 4 балла. Вот обнаружение:
func detectRect() -> Rect{
var rect:Rect?
let detector:CIDetector = CIDetector(ofType: CIDetectorTypeRectangle, context: nil, options: [CIDetectorAccuracy : CIDetectorAccuracyHigh])
// Get the detections
let features = detector.featuresInImage(UIKit.CIImage(image: self)!)
for feature in features as! [CIRectangleFeature] {
rect = Rect(tL: feature.topLeft, tR: feature.topRight, bR: feature.bottomRight, bL: feature.bottomLeft)
}
return rect!
}
Далее я должен масштабировать координаты. Вот функция внутри класса Rect, что делает это:
func scaleRect(image:UIImage, imageView:UIImageView) ->Rect{
let scaleX = imageView.bounds.width/image.size.width
var tlx = topLeft.x * scaleX
var tly = topLeft.y * scaleX
tlx += (imageView.bounds.width - image.size.width * scaleX)/2.0
tly += (imageView.bounds.height - image.size.height * scaleX)/2.0
let tl = CGPointMake(tlx, tly)
var trx = topRight.x * scaleX
var trY = topRight.y * scaleX
trx += (imageView.bounds.width - image.size.width * scaleX)/2.0
trY += (imageView.bounds.height - image.size.height * scaleX)/2.0
let tr = CGPointMake(trx, trY)
var brx = bottomRight.x * scaleX
var bry = bottomRight.y * scaleX
brx += (imageView.bounds.width - image.size.width * scaleX)/2.0
bry += (imageView.bounds.height - image.size.height * scaleX)/2.0
let br = CGPointMake(brx, bry)
var blx = bottomLeft.x * scaleX
var bly = bottomLeft.y * scaleX
blx += (imageView.bounds.width - image.size.width * scaleX)/2.0
bly += (imageView.bounds.height - image.size.height * scaleX)/2.0
let bl = CGPointMake(blx, bly)
let rect = Rect(tL: tl, tR: tr, bR: br, bL: bl)
return rect
}
Наконец я рисую путь:
var tet = image.detectRect()
tet = tet.scaleRect(image, imageView: imageView)
let shapeLayer = CAShapeLayer()
let path = ViewController.drawPath(tet.topLeft, p2: tet.topRight, p3: tet.bottomRight, p4: tet.bottomLeft)
shapeLayer.path = path.CGPath
shapeLayer.lineWidth = 5
shapeLayer.fillColor = nil
shapeLayer.strokeColor = UIColor.orangeColor().CGColor
imageView.layer.addSublayer(shapeLayer)
Путь был выключен экран и неточными. Я знаю, что мне нужно настроить координаты координат CoreImage на координаты UIKit, а затем масштабировать их для UIImageView. К сожалению, я не знаю, как это сделать. Я знаю, что могу повторно использовать некоторые из моих кодов обнаружения, чтобы выполнить это, но я не знаю правильных шагов. Любая помощь будет оценена! Благодарю. Вот пример того, что происходящий:
Update
Для того, чтобы испытывать мое масштабирование, что я выступаю в scaleRect() я решил сделать свой размер ImageView такого же размера, как мой Размер изображения. Затем я напечатал координаты до и после масштабирования. Я думаю, что, поскольку они одинаковы, мое масштабирование выполняется правильно. Вот код:
var tet = image.detectRect()
//Before scaling
print(tet.topLeft)
print(tet.topRight)
print(tet.bottomRight)
print(tet.bottomLeft)
print("**************************************************")
//After scaling
tet = tet.scaleRect(image, imageView: imageView)
print(tet.topLeft)
print(tet.topRight)
print(tet.bottomRight)
print(tet.bottomLeft)
Здесь выход:
(+742,386596679688, 927,240844726562)
(1514,93835449219, 994,811096191406)
(1514,29675292969, 155,2802734375)
(741,837524414062 , 208.55403137207)
(742,386596679688, 927,240844726562)
(1514,93835449219, 994,811096191406)
(1514,29675292969, 155,2802734375)
(741,837524414062, 208.55403137207)
Update
Я попробовал еще две вещи, чтобы попытаться и масштабировать свои координаты.
Номер 1: Я попытался использовать функцию преобразования UIView для преобразования точки с изображения в UIImageView. Вот как я закодировал: я заменил функцию scaleRect() с
let view_image = UIView(frame: CGRectMake(0, 0, image.size.width, image.size.height))
let tL = view_image.convertPoint(self.topLeft, toView: imageView)
let tR = view_image.convertPoint(self.topRight, toView: imageView)
let bR = view_image.convertPoint(self.bottomRight, toView: imageView)
let bL = view_image.convertPoint(self.bottomLeft, toView: imageView)
Затем я вернулся новый прямоугольник с этими точками.
Номер 2: Я пробовал простой перевод координат, основанный на различии в ширине и высоте изображения и изображения. Heres код:
let widthDiff = (image.size.width - imageView.frame.size.width)
let highDiff = (image.size.height - imageView.frame.size.height)
let tL = CGPointMake(self.topLeft.x-widthDiff, self.topLeft.y-highDiff)
let tR = CGPointMake(self.topRight.x-widthDiff, self.topRight.y-highDiff)
let bR = CGPointMake(self.bottomRight.x-widthDiff, self.bottomRight.y-highDiff)
let bL = CGPointMake(self.bottomLeft.x-widthDiff, self.bottomLeft.y-highDiff)
Update Я также попытался с помощью CGAffineTransform. Код:
var transform = CGAffineTransformMakeScale(1, -1)
transform = CGAffineTransformTranslate(transform, 0, -imageView.bounds.size.height)
let tL = CGPointApplyAffineTransform(self.topLeft, transform)
let tR = CGPointApplyAffineTransform(self.topRight, transform)
let bR = CGPointApplyAffineTransform(self.bottomRight, transform)
let bL = CGPointApplyAffineTransform(self.bottomLeft, transform)
Ничего не работало. Я не знаю, что еще я могу попробовать. Пожалуйста помоги. Было бы весьма полезно. Благодаря!
Могу ли я использовать toSize в качестве размера imageView? – John55
да, размер изображенияView - это конечный размер изображения, при этом размер масштабируемого изображения – 4oby
Oby еще раз спасибо за ответ. Мне было интересно, нужно ли мне перевернуть точки, чтобы вернуться к исходным пунктам, возможно ли это с помощью этого кода или это еще одна проблема? – John55