2016-12-01 2 views
0

フロントカメラで作業していますが、フレームをキャプチャするとCCWが90度回転します。キャプチャされたイメージをCGContextで回転させたいのです(Core Graphicは他のフレームワークよりもはるかに高速です)。CGContextのSamplebufferからキャプチャされたフレームを回転する

はここに私のコードです:

func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) { 
    let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) 
    CVPixelBufferLockBaseAddress(imageBuffer!, CVPixelBufferLockFlags(rawValue: 0)) 

    let width = CVPixelBufferGetWidthOfPlane(imageBuffer!, 0) 
    let height = CVPixelBufferGetHeightOfPlane(imageBuffer!, 0) 

    let bytesPerRow = CVPixelBufferGetBytesPerRowOfPlane(imageBuffer!, 0) 

    let lumaBuffer = CVPixelBufferGetBaseAddressOfPlane(imageBuffer!, 0) 

    let grayColorSpace = CGColorSpaceCreateDeviceGray() 

    let context = CGContext(data: lumaBuffer, 
          width: width, 
          height: height, 
          bitsPerComponent: 8, 
          bytesPerRow: bytesPerRow, 
          space: grayColorSpace, 
          bitmapInfo: CGImageAlphaInfo.none.rawValue); 

    let transform1 = CGAffineTransform(rotationAngle: CGFloat(M_PI_2)) 
    context!.concatenate(transform1) 

    //context!.rotate(by: CGFloat(M_PI_2)) // also not working! 
    let dstImage = context!.makeImage() 

    detect(image: dstImage!) 
} 

答えて

1

検索や記事を読んだ多くの後、私はAVCaptureConnectionクラス内の私の解決策を見つけました! キャプチャ機能の中で次のサンプルコードを使ってバッファ内のフレームを回転させるだけの接続を求める必要があります!!

if connection.isVideoOrientationSupported 
{ 
    connection.videoOrientation = .portrait 
} 
    if connection.isVideoMirroringSupported 
{ 
    connection.isVideoMirrored = true 
} 

1

どのような角度でバッファを実際に物理的に回転させるかを検索する人は、ここでどのように行うことができます。 captureOutput didOutputSampleBuffer::(CMSampleBufferRef)sampleBuffer fromConnection:captureOutputに

static double radians (double degrees) {return degrees * M_PI/180;} 

static double ScalingFactorForAngle(double angle, CGSize originalSize) { 
    double oriWidth = originalSize.height; 
    double oriHeight = originalSize.width; 
    double horizontalSpace = fabs(oriWidth*cos(angle)) + fabs(oriHeight*sin(angle)); 
    double scalingFactor = oriWidth/horizontalSpace ; 
    return scalingFactor; 
} 

CGColorSpaceRef rgbColorSpace = NULL; 
CIContext *context = nil; 
CIImage *ci_originalImage = nil; 
CIImage *ci_transformedImage = nil; 

CIImage *ci_userTempImage = nil; 


static inline void RotatePixelBufferToAngle(CVPixelBufferRef thePixelBuffer, double theAngle) { 

    @autoreleasepool { 

     if (context==nil) { 
      rgbColorSpace = CGColorSpaceCreateDeviceRGB(); 
      context = [CIContext contextWithOptions:@{kCIContextWorkingColorSpace: (__bridge id)rgbColorSpace, 
                 kCIContextOutputColorSpace : (__bridge id)rgbColorSpace}]; 
     } 

     long int w = CVPixelBufferGetWidth(thePixelBuffer); 
     long int h = CVPixelBufferGetHeight(thePixelBuffer); 

     ci_originalImage = [CIImage imageWithCVPixelBuffer:thePixelBuffer]; 
     ci_userTempImage = [ci_originalImage imageByApplyingTransform:CGAffineTransformMakeScale(0.6, 0.6)]; 
     //  CGImageRef UICG_image = [context createCGImage:ci_userTempImage fromRect:[ci_userTempImage extent]]; 

     double angle = theAngle; 
     angle = angle+M_PI; 
     double scalingFact = ScalingFactorForAngle(angle, CGSizeMake(w, h)); 


     CGAffineTransform transform = CGAffineTransformMakeTranslation(w/2.0, h/2.0); 
     transform = CGAffineTransformRotate(transform, angle); 
     transform = CGAffineTransformTranslate(transform, -w/2.0, -h/2.0); 

     //rotate it by applying a transform 
     ci_transformedImage = [ci_originalImage imageByApplyingTransform:transform]; 

     CVPixelBufferLockBaseAddress(thePixelBuffer, 0); 

     CGRect extentR = [ci_transformedImage extent]; 
     CGPoint centerP = CGPointMake(extentR.size.width/2.0+extentR.origin.x, 
             extentR.size.height/2.0+extentR.origin.y); 
     CGSize scaledSize = CGSizeMake(w*scalingFact, h*scalingFact); 
     CGRect cropRect = CGRectMake(centerP.x-scaledSize.width/2.0, centerP.y-scaledSize.height/2.0, 
            scaledSize.width, scaledSize.height); 


     CGImageRef cg_img = [context createCGImage:ci_transformedImage fromRect:cropRect]; 
     ci_transformedImage = [CIImage imageWithCGImage:cg_img]; 

     ci_transformedImage = [ci_transformedImage imageByApplyingTransform:CGAffineTransformMakeScale(1.0/scalingFact, 1.0/scalingFact)]; 
     [context render:ci_transformedImage toCVPixelBuffer:thePixelBuffer bounds:CGRectMake(0, 0, w, h) colorSpace:NULL]; 

     CGImageRelease(cg_img); 
     CVPixelBufferUnlockBaseAddress(thePixelBuffer, 0); 

    } 
} 

移動:あなたのファイルの先頭にこれを追加(AVCaptureConnection *)接続と機能を適用します。

CVPixelBufferRef pixBuf = CMSampleBufferGetImageBuffer(sampleBuffer); 
RotatePixelBufferToAngle(pixBuf, radians(45.0)); 

45.0 - は希望の角度です

これは回転だけでなく、画像を拡大してビデオdimensi ons(Aspect Fillのようなもの)。 scalingFactを変更することで、スケールをオフにすることができます。

関連する問題