Swift 3循环到图像的中心像素

时间:2016-11-09 15:53:32

标签: ios swift swift3 flir

语言: 斯威夫特3

我使用的是什么硬件:iPhone 6和FLIR One热像仪 软件:Xcode 8.1,锁定FLIROne SDK(为obj-c编写和记录,并且几乎没有文档)

我想做什么: 从返回的摄像机流中获取中心像素的温度

问题: 我在应用程序中有所有内容我正在构建设置并按预期工作,不包括获取此热量数据。我已经能够从相机返回的流中获得温度,但是我只能获得0,0(左上角)像素的温度。我在图像视图的中心有十字线,流进入,我想在这个中心点(图像的确切中心)获得像素。我已经为此工作了两天,我似乎无法弄清楚如何做到这一点。 SDK不允许您指定从我在线阅读的内容中读取哪个像素,您必须遍历每个像素并停在中心位置。

以下代码将从像素0,0获取温度并正确显示。我想让温度读取中心像素。温度必须是UInt16,以提供正确的开尔文读数(至少从我的理解),但我从数据接收辐射数据!作为UInt8。注意:NSData!不适用于这些代表。尝试使用它(即使在swift 2.3中)会导致委托从不开火。我必须使用数据!因为它甚至运行代表。我觉得很奇怪我不能使用swift 2.3,因为它只有NSData。如果这是因为我搞砸了,请告诉我。

func flirOneSDKDelegateManager(_ delegateManager: FLIROneSDKDelegateManager!, didReceiveRadiometricData radiometricData: Data!, imageSize size: CGSize) {

    let byteArray = radiometricData?.withUnsafeBytes{
        [UInt8](UnsafeBufferPointer(start: $0, count: (radiometricData?.count)!))
    }

    let temperature = UnsafePointer(byteArray!).withMemoryRebound(to: UInt16.self, capacity: 1){
        $0.pointee
    }

    debugPrint(temperature)

    DispatchQueue.main.async{
        self.tempLabel.text = NSString(format: "%.1f",self.convertToFarenheit(kelvin: temperature)) as String
    }
}

我是Swift的新手所以我不确定这是否是最好的方法,所以如果你有更好的方法,请告诉我。

当前解决方案: 获取中心像素,但不动态(这是我想要的)

    let byteArray = radiometricData?.withUnsafeBytes{
        [UInt8](UnsafeBufferPointer(start: $0, count: (radiometricData?.count)!))
    }

    let bytes:[UInt8] = [(byteArray?[74170])!,(byteArray?[74171])!]

    let temperature = UnsafePointer(bytes).withMemoryRebound(to: UInt16.self, capacity: 1){
        $0.pointee
    }

1 个答案:

答案 0 :(得分:1)

假设您尝试从swift的Data

中读取一些UInt16值
import Foundation

var data = Data([1,0,2,0,255,255,1]) // 7 bytes
var arr: [UInt16] = []

// in my data only 6 bytes could be represented as Int16 values, so i have to ignore the last one ...
for i in stride(from: 0, to: 2 * (data.count / 2) , by: MemoryLayout<UInt16>.stride) {
    arr.append(data.subdata(in: i..<(i+MemoryLayout<UInt16>.stride)).withUnsafeBytes { $0.pointee })
}

print(arr) // [1, 2, 65535]

或者您可以使用类似

的内容
let arr0: [UInt16] = data.withUnsafeBytes { (p: UnsafePointer<UInt8>)->[UInt16] in
    let capacity = data.count / MemoryLayout<UInt16>.stride
    return p.withMemoryRebound(to: UInt16.self, capacity: capacity) {
        var arr = [UInt16]()
        for i in 0..<capacity {
            arr.append(($0 + i).pointee)
        }
        return arr
    }
}
print(arr0) // [1, 2, 65535]

extension Data {
    func scan<T>(offset: Int, bytes: Int) -> T {
        return self.subdata(in: offset..<(offset+bytes)).withUnsafeBytes { $0.pointee }
    }
}

let k: UInt16 = data.scan(offset: 2, bytes: MemoryLayout<UInt16>.stride)
print(k) // 2

甚至更好

extension Data {
    func scan<T>(from: Int)->T {
        return self.withUnsafeBytes { (p: UnsafePointer<UInt8>)->T in
            p.advanced(by: from).withMemoryRebound(to: T.self, capacity: 1) {
                $0.pointee
            }
        }
    }
}
let u0: UInt16 = data.scan(from: 2)
print(u0) // 2

    extension Data {
        func scan2<T>(from: Int)->T {
            return self.withUnsafeBytes { 
// Precondition: The underlying pointer plus offset is properly aligned for accessing T.
// Precondition: The memory is initialized to a value of some type, U, such that T is layout compatible with U.
                 UnsafeRawPointer($0).load(fromByteOffset: from, as: T.self)
            }
        }
    }

    let u2: UInt16 = data.scan2(from: 2)
    print(u2) // 2

您的数据中的正确偏移量是什么,读取值?很难说你在问题中提供的信息。