如何从 CIFilter.areaHistogram() 中提取直方图数据

问题描述

如何从 CIFilter.areaHistogram() 返回的 ciImage 中提取 rgb 直方图值。

据我所知,此过滤器返回一个 1 像素高的图像,其中包含指定 bin 中 rgba 的值。因此,如果指定了 256 个 bin,则图像将为 1 x 1024 像素。 那么如何将像素值提取到四个 [Int] 数组中。

有什么办法可以将 CIImage 覆盖到可以读取的缓冲区中吗?我原以为这会非常简单,但我想 CIImage 可以成为各种事物的包装器。

from matplotlib.ticker import LogFormatterMathtext
import matplotlib.pyplot as plt
import numpy as np

fig,ax1 = plt.subplots(1,figsize=(15,9))

# axup scaler
scale = lambda x: x*1.e37/(2.*(3.809e8))

# set axup.xlim to scale(ax1.xlim)
def scale_axup(ax1):
    # mirror xlim on both axes
    left,right = scale(np.array(ax1.get_xlim()))
    axup.set_xlim(left,right)
    
    # set xticks to 0.1e28 intervals
    xticks = np.arange(float(f'{left:.1e}'),float(f'{right:.1e}'),0.1e28)
    axup.set_xticks([float(f'{tick:.0e}') for tick in xticks])
    axup.xaxis.set_major_formatter(LogFormatterMathtext())
    
    # redraw to update xticks
    axup.figure.canvas.draw()

# connect ax1 with axup (before ax1.set_xlim())
axup = ax1.twiny()
axup.set_xscale('log')
axup.set_xlabel(r'Log axis')
ax1.callbacks.connect(r'xlim_changed',scale_axup)

ax1.set_ylabel(r'y axis')
ax1.set_xlabel(r'Linear axis')
ax1.set_ylim(0.1,1.)
ax1.set_xlim(0.1,10.)

plt.show()

输出如下

if let areahistogram = self.ciMgr.areaHistogramFilter(ciImage) {
        
        let attrs = [kCVPixelBufferCGImageCompatibilityKey: kCFBooleanTrue,kCVPixelBufferCGBitmapContextCompatibilityKey: kCFBooleanTrue] as CFDictionary
        var pixelBuffer : CVPixelBuffer?
        let status = CVPixelBufferCreate(kCFAllocatorDefault,Int(areahistogram.extent.size.width),Int(areahistogram.extent.size.height),kCVPixelFormatType_32ARGB,attrs,&pixelBuffer)
        
        guard (status == kCVReturnSuccess) else {
            return
        }
        
        self.hContext.render(areahistogram,to: pixelBuffer!)
        
        CVPixelBufferLockBaseAddress(pixelBuffer!,CVPixelBufferLockFlags(rawValue: 0));
        let int32Buffer = unsafeBitCast(CVPixelBufferGetBaseAddress(pixelBuffer!),to: UnsafeMutablePointer<UInt32>.self)
        let int32PerRow = CVPixelBufferGetBytesPerRow(pixelBuffer!)
        
        
        var data = [Int]()
        for i in 0..<256 {
            // Get BGRA value for pixels
            let BGRA = int32Buffer[i]
            data.append(Int(BGRA))
            
            let red = (BGRA >> 16) & 0xFF;
            let green = (BGRA >> 8) & 0xFF;
            let blue = BGRA & 0xFF;
            
            os_log("data[\(i)]:\(BGRA) red: \(red)  green: \(green)  blue: \(blue)")
        }
        
        CVPixelBufferUnlockBaseAddress(pixelBuffer!,CVPixelBufferLockFlags(rawValue: 0))
        
    }

我想我遗漏了一些东西,因为除了最后一个像素之外,像素缓冲区本身似乎始终为零。

或者这个

data[0]:0 red: 0  green: 0  blue: 0
data[1]:0 red: 0  green: 0  blue: 0
...
data[255]:134678783 red: 7  green: 7  blue: 7

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...