簡體   English   中英

將檢測到的矩形從縱向CIImage轉換為橫向CIImage

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

我正在修改此處找到的代碼。 在代碼中,我們使用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 =(width = 263.090088,height = 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];
         }
    }

謝謝。

在做這種事情時我遇到了同樣的問題。我已經通過在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)
            }
        }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM