web-dev-qa-db-ja.com

CMSampleBufferをUIImageに変換します

SampleBufferをUIImageに変換し、colorspaceGrayを使用して画像ビューに表示しようとしています。ただし、次の画像のように表示されます。変換に問題があると思います。 CMSampleBufferを変換するにはどうすればよいですか?

It is a gray version of a red colored image

func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) {
    print("buffered")
    let imageBuffer: CVImageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)!
    CVPixelBufferLockBaseAddress(imageBuffer, CVPixelBufferLockFlags(rawValue: 0))
    let width: Int = CVPixelBufferGetWidth(imageBuffer)
    let height: Int = CVPixelBufferGetHeight(imageBuffer)
    let bytesPerRow: Int = CVPixelBufferGetBytesPerRow(imageBuffer)
    let lumaBuffer = CVPixelBufferGetBaseAddress(imageBuffer)

    //let planeCount : Int = CVPixelBufferGetPlaneCount(imageBuffer)
    let grayColorSpace: CGColorSpace = CGColorSpaceCreateDeviceGray()
    let context: CGContext = CGContext(data: lumaBuffer, width: width, height: height, bitsPerComponent: 8, bytesPerRow: bytesPerRow , space: grayColorSpace, bitmapInfo: CGImageAlphaInfo.none.rawValue)!
    let dstImageFilter: CGImage = context.makeImage()!
    let imageRect : CGRect = CGRect(x: 0, y: 0, width: width, height: height)
    context.draw(dstImageFilter, in: imageRect)
    let image = UIImage(cgImage: dstImageFilter)
    DispatchQueue.main.sync(execute: {() -> Void in
        self.imageTest.image = image
    })
}
6

変換は簡単です:

func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) {

     let imageBuffer: CVPixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)!
     let ciimage : CIImage = CIImage(cvPixelBuffer: imageBuffer)   
     let image : UIImage = self.convert(cmage: ciimage) 
}

// Convert CIImage to CGImage
func convert(cmage:CIImage) -> UIImage
{
     let context:CIContext = CIContext.init(options: nil)
     let cgImage:CGImage = context.createCGImage(cmage, from: cmage.extent)!
     let image:UIImage = UIImage.init(cgImage: cgImage)
     return image
}
40

CMSampleBufferがRGBAデータを提供しているように見えます。このデータから、グレースケール画像を直接作成します。ピクセルごとにgray = (pixel.red+pixel.green+pixel.blue)/3のようなことを行う新しいバッファを作成する必要があります。または、受信したデータから通常のRGBA画像を作成し、それをグレースケールに変換する必要があります。

しかし、あなたのコードでは、遷移はまったくありません。そこにあるデータの種類に関係なく、CVPixelBufferGetBaseAddressを使用してバッファへの生のポインタを取得しました。次に、受信したデータがグレースケールであると想定して、同じポインタを渡して画像を作成します。

1
Matic Oblak