简体   繁体   English

将检测到的矩形从纵向CIImage转换为横向CIImage

[英]Translate detected rectangle from portrait CIImage to landscape CIImage

I am modifying code found here . 我正在修改此处找到的代码。 In the code we are capturing video from the phone camera using AVCaptureSession and using CIDetector to detect a rectangle in the image feed. 在代码中,我们使用AVCaptureSession从手机摄像头捕获视频,并使用CIDetector检测图像源中的矩形。 The feed has an image which is 640x842 (iphone5 in portrait). Feed的图像为640x842(iphone5为纵向)。 We then do an overlay on the image so the user can see the detected rectangle (actually it's a trapezoid most of the time). 然后我们对图像进行叠加,以便用户可以看到检测到的矩形(实际上大部分时间它都是梯形)。

When the user presses a button on the UI, we capture an image from the video and re-run the rectangle detection on this larger image (3264x2448) which as you can see is landscape. 当用户按下UI上的按钮时,我们从视频中捕获图像并在这个较大的图像(3264x2448)上重新运行矩形检测,如您所见,它是横向的。 We then do a perspective transform on the detected rectangle and crop on the image. 然后,我们对检测到的矩形进行透视变换并在图像上裁剪。

This is working pretty well but the issue I have is say 1 out of 5 captures the detected rectangle on the larger image is different to the one detected (and presented to the user) from the smaller image. 这个工作得很好,但我所遇到的问题是,5个中的1个捕获较大图像上检测到的矩形与从较小图像检测到(并呈现给用户)的矩形不同。 Even though I only capture when I detect the phone is (relatively) still, the final image then does not represent the rectangle the user expected. 即使我只是在检测到手机(相对)静止时捕获,但最终图像并不代表用户期望的矩形。

To resolve this my idea is to use the coordinates of the originally captured rectangle and translate them to a rectangle on the captured still image. 为了解决这个问题,我的想法是使用最初捕获的矩形的坐标,并将它们转换为捕获的静止图像上的矩形。 This is where I'm struggling. 这是我在努力的地方。

I tried this with the detected rectangle: 我用检测到的矩形尝试了这个:

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);

So given a detected rect: 所以给定检测到的矩形:

TopLeft: 88.213425, 632.31329 TopRight: 545.59302, 632.15546 BottomRight: 575.57819, 369.22321 BottomLeft: 49.973862, 369.40466 TopLeft:88.213425,632.31329 TopRight:545.59302,632.15546 BottomRight:575.57819,369.22321 BottomLeft:49.973862,369.40466

I now have this rotated rect: 我现在有这个旋转的矩形:

origin = (x = 369.223206, y = -575.578186) size = (width = 263.090088, height = 525.604309) origin =(x = 369.223206,y = -575.578186)size =(width = 263.090088,height = 525.604309)

How do I translate the rotated rectangle coordinates in the smaller portrait image to coordinates to the 3264x2448 image? 如何将较小的纵向图像中的旋转矩形坐标转换为3264x2448图像的坐标?

Edit Duh.. reading my own approach realised that creating a rectangle out of a trapezoid will not solve my problem! 编辑 Duh ..阅读我自己的方法意识到用梯形创建一个矩形不会解决我的问题!

Supporting code to detect the rectangle etc... 支持代码检测矩形等...

// 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....
}

This is a summarized version of how the still image is obtained: 这是如何获取静止图像的摘要版本:

// 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];
         }
    }

Thank you. 谢谢。

I had the same issue while doing this kind of stuff.I have resolved it by doing below code in swift. 在做这种事情时我遇到了同样的问题。我已经通过在swift中执行以下代码解决了这个问题。 Take a look if it can help you. 看看它是否可以帮到你。

 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)
            }
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM