2017-08-03 131 views
2

中爲不同通道工作我正在嘗試計算kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange圖像緩衝區中Y通道的直方圖。當我使用vImageHistogramCalculation_Planar8時,我只傳遞一個參考值到一個直方圖。直方圖如何在vImageHistogramCalculation_Planar8

如何知道使用哪個通道創建直方圖?如果我想閱讀所有頻道,我該怎麼辦?

也可以對代碼示例進行批判。

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

     let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)! 
     CVPixelBufferLockBaseAddress(imageBuffer, CVPixelBufferLockFlags(rawValue: 0)) 

     let height = CVPixelBufferGetHeight(imageBuffer) 
     let width = CVPixelBufferGetWidth(imageBuffer) 
     let bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer) 
     let pixelBuffer = CVPixelBufferGetBaseAddress(imageBuffer) 

//  let format = CVPixelBufferGetPixelFormatType(imageBuffer) 
//  print("format: \(format)") 

     ///kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange = '420v' 

     var vBuffer = vImage_Buffer() 
     vBuffer.data = pixelBuffer 
     vBuffer.rowBytes = bytesPerRow 
     vBuffer.width = vImagePixelCount(width) 
     vBuffer.height = vImagePixelCount(height) 

     let luma = [UInt](repeating: 0, count: 256) 

     let lumaHist = UnsafeMutablePointer<vImagePixelCount>(mutating: luma) 

     vImageHistogramCalculation_Planar8(&vBuffer, lumaHist, UInt32(kvImageNoFlags)) 

     CVPixelBufferUnlockBaseAddress(imageBuffer, CVPixelBufferLockFlags(rawValue: 0)) 
    } 
} 

回答

2

kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange是一種平面格式,所有平面都編碼到緩衝區中。而平面功能一次只能在一個平面上工作。 上面的代碼是在三個平面上計算直方圖,但將其視爲一個大飛機,這可能不是您想要的。

它可以訪問的基地址和每行的字節爲Y平面與這些功能的數量:

let bytesPerRow = CVPixelBufferGetBytesPerRowOfPlane(imageBuffer, 0) 
let pixelBuffer = CVPixelBufferGetBaseAddressOfPlane(imageBuffer, 0) 

平面指數取決於緩衝格式。這個名字通常會給你一個提示。這裏是YpCbCr,所以Y飛機應該是第一個,在索引0

0

根據頭部,CVPixelBufferGetBaseAddress將返回:

For chunky buffers, this will return a pointer to the pixel at 
     0,0 in the buffer. 
    For planar buffers this will return a pointer to a PlanarComponentInfo struct 
     (defined in QuickTime). 

所以,如果屬實,這不是一次計算所有三個通道的直方圖。它正在計算PlanarComponentInfo結構的甚至不太有用的直方圖,並且可能會崩潰。

要閱讀所有通道,就可以得到第二架飛機出使用Sparga的回答以上(CVPixelBufferGetBytesPerRowOfPlane(ImageBuffer的,1)和CVPixelBufferGetBaseAddressOfPlane(ImageBuffer的,1))描述的接口,並做半寬的ARGB直方圖色度圖像並將偶數直方圖和奇數直方圖一起添加。請注意,因爲這是420,所以色度平面的高度和寬度與亮度平面不同。

我還會提交一份bug報告,請求vImageHistogramCalculation_RG88處理雙平面色度數據。