3

言語: Swift 3

私が使用しているものハードウェア:iPhone 6およびFLIR Oneサーマルカメラ ソフトウェア:Xcode 8.1、ロックダウンFLIROne SDK(obj-c用に作成および文書化されており、文書はほとんどありません)

私がやろうとしていること:返されたカメラストリームから中心ピクセルの温度を取得します

問題:私はセットアップを構築しているアプリにすべてを持っており、この熱データの取得を除いて期待どおりに動作しています。カメラから返されたストリームから温度を取得できましたが、取得できるのは 0,0 (左上) ピクセルのみです。ストリームがフィードする画像ビューの中心に十字線があり、この中心点 (画像の正確な中心) でピクセルを取得したいと考えています。私はこれに2日間取り組んできましたが、これを行う方法がわかりません。SDK では、オンラインで読んだものから読み取るピクセルを指定することはできません。各ピクセルをループして、中央のピクセルで停止する必要があります。

以下のコードは、ピクセル 0,0 から温度を取得し、正しく表示します。代わりに温度を取得して中央のピクセルを読み取りたいです。(少なくとも私が理解していることから)正しいケルビン値を提供するには、温度を UInt16 にする必要がありますが、データから放射データを受け取ります。UInt8として。注: NSData! これらのデリゲートでは機能しません。これを使用しようとすると (Swift 2.3 であっても)、デリゲートが起動しなくなります。データを使用する必要があります。デリゲートを実行することさえできます。NSData しかないため、swift 2.3 を使用できないのは非常に奇妙に感じました。これが私が何かを台無しにしたためである場合は、お知らせください。

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
    }
4

1 に答える 1

1

Swift のデータからいくつかの 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

値を読み取るためのデータの正しいオフセットは何ですか? あなたの質問で提供した情報からは言いにくいです。

于 2016-11-09T18:34:23.647 に答える