gpt4 book ai didi

ios - 如何使用 CAShapeLayer 和 UIBezierPath 在实时摄像头源上绘制检测到的矩形路径

转载 作者:可可西里 更新时间:2023-10-31 23:36:01 25 4
gpt4 key购买 nike

我正在开发一个应用程序来检测实时摄像头画面中的矩形并突出显示检测到的矩形。我使用 AVFoundation 做了相机的事情,并使用了下面的方法来检测和突出显示检测到的矩形。

var detector: CIDetector?;

override func viewDidLoad() {
super.viewDidLoad();

detector = self.prepareRectangleDetector();
}

func captureOutput(captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, fromConnection connection: AVCaptureConnection!) { // re check this method

// Need to shimmy this through type-hell
let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)

// Force the type change - pass through opaque buffer
let opaqueBuffer = Unmanaged<CVImageBuffer>.passUnretained(imageBuffer!).toOpaque()
let pixelBuffer = Unmanaged<CVPixelBuffer>.fromOpaque(opaqueBuffer).takeUnretainedValue()

let sourceImage = CIImage(CVPixelBuffer: pixelBuffer, options: nil)

// Do some detection on the image
self.performRectangleDetection(sourceImage);

var outputImage = sourceImage

// Do some clipping
var drawFrame = outputImage.extent
let imageAR = drawFrame.width / drawFrame.height
let viewAR = videoDisplayViewBounds.width / videoDisplayViewBounds.height

if imageAR > viewAR {
drawFrame.origin.x += (drawFrame.width - drawFrame.height * viewAR) / 2.0
drawFrame.size.width = drawFrame.height / viewAR
} else {
drawFrame.origin.y += (drawFrame.height - drawFrame.width / viewAR) / 2.0
drawFrame.size.height = drawFrame.width / viewAR
}

//videoDisplayView is a GLKView which is used to display camera feed
videoDisplayView.bindDrawable()
if videoDisplayView.context != EAGLContext.currentContext() {
EAGLContext.setCurrentContext(videoDisplayView.context)
}

// clear eagl view to grey
glClearColor(0.5, 0.5, 0.5, 1.0);
glClear(0x00004000)

// set the blend mode to "source over" so that CI will use that
glEnable(0x0BE2);
glBlendFunc(1, 0x0303);

renderContext.drawImage(outputImage, inRect: videoDisplayViewBounds, fromRect: drawFrame);

videoDisplayView.display();

}

func prepareRectangleDetector() -> CIDetector {

let options: [String: AnyObject] = [CIDetectorAccuracy: CIDetectorAccuracyHigh];
return CIDetector(ofType: CIDetectorTypeRectangle, context: nil, options: options);
}

func performRectangleDetection(image: CIImage){

let resultImage: CIImage? = nil;

if let detector = detector {

// Get the detections
let features = detector.featuresInImage(image, options: [CIDetectorAspectRatio:NSNumber(float:1.43)]);


if features.count != 0{ // feature found

for feature in features as! [CIRectangleFeature] {

self.previewImageView.layer.sublayers = nil;

let line: CAShapeLayer = CAShapeLayer();
line.frame = self.videoDisplayView.bounds;
let linePath: UIBezierPath = UIBezierPath();

linePath.moveToPoint(feature.topLeft);
linePath.addLineToPoint(feature.topRight);
linePath.addLineToPoint(feature.bottomRight);
linePath.addLineToPoint(feature.bottomLeft);
linePath.addLineToPoint(feature.topLeft);
linePath.closePath();

line.lineWidth = 5.0;
line.path = linePath.CGPath;
line.fillColor = UIColor.clearColor().CGColor;
line.strokeColor = UIColor(netHex: 0x3399CC, alpha: 1.0).CGColor;

// videoDisplayParentView is the parent of videoDisplayView and they both have same bounds
self.videoDisplayParentView.layer.addSublayer(line);
}
}
}
}

我使用 CAShapeLayerUIBezierPath 来绘制矩形。这非常非常慢。路径在几分钟后可见。

有人可以帮我弄清楚为什么它很慢,或者让我知道我在这里做错了什么。任何帮助将不胜感激。

或者如果有比这更简单的方法我也想知道。

最佳答案

如果您开始向 GLKView 添加子层,那将会很慢。这里的GLKView每秒刷新多次(因为是在captureOutput:didOutputSampleBuffer:..方法中),每次创建和添加子层的过程都会跟不上。

更好的方法是使用 CoreImage 绘制路径并将其合成到 resultImage 上。

关于ios - 如何使用 CAShapeLayer 和 UIBezierPath 在实时摄像头源上绘制检测到的矩形路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37748072/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com