我正在修改找到的代码here。在代码中,我们使用AVCaptureSession从手机摄像头捕获视频,并使用CIDetector检测图像源中的矩形。 Feed的图像为640x842(iphone5为纵向)。然后我们对图像进行叠加,这样用户就可以看到检测到的矩形(实际上它大部分时间都是梯形)。
当用户按下UI上的按钮时,我们从视频中捕获图像并在这个较大的图像(3264x2448)上重新运行矩形检测,如您所见,它是横向的。然后,我们对检测到的矩形进行透视变换并在图像上进行裁剪。
这项工作非常顺利,但我所遇到的问题是,在5个中,有1个捕获较大图像上检测到的矩形与从较小图像检测到的(并呈现给用户)的矩形不同。即使我只是在检测到手机(相对)静止时捕获,但最终图像并不代表用户期望的矩形。
为了解决这个问题,我的想法是使用最初捕获的矩形的坐标,并将它们转换为捕获的静止图像上的矩形。这就是我挣扎的地方。
我用检测到的矩形尝试了这个:
CGFloat radians = -90 * (M_PI/180);
CGAffineTransform rotation = CGAffineTransformMakeRotation(radians);
CGRect rect = CGRectMake(detectedRect.bounds.origin.x, detectedRect.bounds.origin.y, detectedRect.bounds.size.width, detectedRect.bounds.size.height);
CGRect rotatedRect = CGRectApplyAffineTransform(rect, rotation);
所以给出了一个检测到的矩形:
TopLeft:88.213425,632.31329 TopRight:545.59302,632.15546 BottomRight:575.57819,369.22321 BottomLeft:49.973862,369.40466
我现在有这个旋转的矩形:
origin =(x = 369.223206,y = -575.578186) size =(宽度= 263.090088,身高= 525.604309)
如何将较小的纵向图像中的旋转矩形坐标转换为3264x2448图像的坐标?
修改 Duh ..阅读我自己的方法意识到用梯形创建一个矩形不会解决我的问题!
支持代码检测矩形等...
// In this method we detect a rect from the video feed and overlay
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
CVPixelBufferRef pixelBuffer = (CVPixelBufferRef)CMSampleBufferGetImageBuffer(sampleBuffer);
CIImage *image = [CIImage imageWithCVPixelBuffer:pixelBuffer];
// image is 640x852 on iphone5
NSArray *rects = [[CIDetector detectorOfType:CIDetectorTypeRectangle context:nil options:@{CIDetectorAccuracy : CIDetectorAccuracyHigh}] featuresInImage:image];
CIRectangleFeature *detectedRect = rects[0];
// draw overlay on image code....
}
这是如何获得静止图像的摘要版本:
// code block to handle output from AVCaptureStillImageOutput
[self.stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler: ^(CMSampleBufferRef imageSampleBuffer, NSError *error)
{
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];
CIImage *enhancedImage = [[CIImage alloc] initWithData:imageData options:@{kCIImageColorSpace:[NSNull null]}];
imageData = nil;
CIRectangleFeature *rectangleFeature = [self getDetectedRect:[[self highAccuracyRectangleDetector] featuresInImage:enhancedImage]];
if (rectangleFeature) {
enhancedImage = [self correctPerspectiveForImage:enhancedImage withTopLeft:rectangleFeature.topLeft andTopRight:rectangleFeature.topRight andBottomRight:rectangleFeature.bottomRight andBottomLeft:rectangleFeature.bottomLeft];
}
}
谢谢。
答案 0 :(得分:0)
我在做这种事情时遇到了同样的问题。我已经通过在swift中执行以下代码解决了这个问题。看看它是否可以帮到你。
if let videoConnection = stillImageOutput.connection(withMediaType: AVMediaTypeVideo) {
stillImageOutput.captureStillImageAsynchronously(from: videoConnection) {
(imageDataSampleBuffer, error) -> Void in
let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageDataSampleBuffer)
var img = UIImage(data: imageData!)!
let outputRect = self.previewLayer?.metadataOutputRectOfInterest(for: (self.previewLayer?.bounds)!)
let takenCGImage = img.cgImage
let width = (takenCGImage?.width)!
let height = (takenCGImage?.height)!
let cropRect = CGRect(x: (outputRect?.origin.x)! * CGFloat(width), y: (outputRect?.origin.y)! * CGFloat(height), width: (outputRect?.size.width)! * CGFloat(width), height: (outputRect?.size.height)! * CGFloat(height))
let cropCGImage = takenCGImage!.cropping(to: cropRect)
img = UIImage(cgImage: cropCGImage!, scale: 1, orientation: img.imageOrientation)
let cropViewController = TOCropViewController(image: self.cropToBounds(image: img))
cropViewController.delegate = self
self.navigationController?.pushViewController(cropViewController, animated: true)
}
}