diff --git a/modules/core/misc/objc/common/MatExt.swift b/modules/core/misc/objc/common/MatExt.swift index f6b3072345..5ce3a5e6fb 100644 --- a/modules/core/misc/objc/common/MatExt.swift +++ b/modules/core/misc/objc/common/MatExt.swift @@ -33,6 +33,10 @@ func throwIncompatibleBufferSize(count: Int, channels: Int32) throws { ) } +public typealias T2 = (T, T) +public typealias T3 = (T, T, T) +public typealias T4 = (T, T, T, T) + public extension Mat { convenience init(rows:Int32, cols:Int32, type:Int32, data:[Int8]) { @@ -242,3 +246,350 @@ public extension Mat { return __get(indices as [NSNumber]) as! [Double] } } + +public protocol Atable { + static func getAt(m: Mat, indices:[Int32]) -> Self + static func putAt(m: Mat, indices:[Int32], v: Self) + static func getAt2c(m: Mat, indices:[Int32]) -> (Self, Self) + static func putAt2c(m: Mat, indices:[Int32], v: (Self, Self)) + static func getAt3c(m: Mat, indices:[Int32]) -> (Self, Self, Self) + static func putAt3c(m: Mat, indices:[Int32], v: (Self, Self, Self)) + static func getAt4c(m: Mat, indices:[Int32]) -> (Self, Self, Self, Self) + static func putAt4c(m: Mat, indices:[Int32], v: (Self, Self, Self, Self)) +} + +public class MatAt { + + init(mat: Mat, indices: [Int32]) { + self.mat = mat + self.indices = indices + } + + private let mat: Mat + private let indices: [Int32] + public var v: N { + get { + return N.getAt(m: mat, indices: indices) + } + set(value) { + N.putAt(m: mat, indices: indices, v: value) + } + } + public var v2c: (N, N) { + get { + return N.getAt2c(m: mat, indices: indices) + } + set(value) { + N.putAt2c(m: mat, indices: indices, v: value) + } + } + public var v3c: (N, N, N) { + get { + return N.getAt3c(m: mat, indices: indices) + } + set(value) { + N.putAt3c(m: mat, indices: indices, v: value) + } + } + public var v4c: (N, N, N, N) { + get { + return N.getAt4c(m: mat, indices: indices) + } + set(value) { + N.putAt4c(m: mat, indices: indices, v: value) + } + } +} + +extension UInt8: Atable { + public static func getAt(m: Mat, indices:[Int32]) -> UInt8 { + var tmp = [Int8](repeating: 0, count: 1) + try! m.get(indices: indices, data: &tmp) + return UInt8(bitPattern: tmp[0]) + } + + public static func putAt(m: Mat, indices: [Int32], v: UInt8) { + let tmp = [Int8(bitPattern: v)] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt2c(m: Mat, indices:[Int32]) -> (UInt8, UInt8) { + var tmp = [Int8](repeating: 0, count: 2) + try! m.get(indices: indices, data: &tmp) + return (UInt8(bitPattern: tmp[0]), UInt8(bitPattern: tmp[1])) + } + + public static func putAt2c(m: Mat, indices: [Int32], v: (UInt8, UInt8)) { + let tmp = [Int8(bitPattern: v.0), Int8(bitPattern: v.1)] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt3c(m: Mat, indices:[Int32]) -> (UInt8, UInt8, UInt8) { + var tmp = [Int8](repeating: 0, count: 3) + try! m.get(indices: indices, data: &tmp) + return (UInt8(bitPattern: tmp[0]), UInt8(bitPattern: tmp[1]), UInt8(bitPattern: tmp[2])) + } + + public static func putAt3c(m: Mat, indices: [Int32], v: (UInt8, UInt8, UInt8)) { + let tmp = [Int8(bitPattern: v.0), Int8(bitPattern: v.1), Int8(bitPattern: v.2)] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt4c(m: Mat, indices:[Int32]) -> (UInt8, UInt8, UInt8, UInt8) { + var tmp = [Int8](repeating: 0, count: 4) + try! m.get(indices: indices, data: &tmp) + return (UInt8(bitPattern: tmp[0]), UInt8(bitPattern: tmp[1]), UInt8(bitPattern: tmp[2]), UInt8(bitPattern: tmp[3])) + } + + public static func putAt4c(m: Mat, indices: [Int32], v: (UInt8, UInt8, UInt8, UInt8)) { + let tmp = [Int8(bitPattern: v.0), Int8(bitPattern: v.1), Int8(bitPattern: v.2), Int8(bitPattern: v.3)] + try! m.put(indices: indices, data: tmp) + } +} + +extension Int8: Atable { + public static func getAt(m: Mat, indices:[Int32]) -> Int8 { + var tmp = [Int8](repeating: 0, count: 1) + try! m.get(indices: indices, data: &tmp) + return tmp[0] + } + + public static func putAt(m: Mat, indices: [Int32], v: Int8) { + let tmp = [v] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt2c(m: Mat, indices:[Int32]) -> (Int8, Int8) { + var tmp = [Int8](repeating: 0, count: 2) + try! m.get(indices: indices, data: &tmp) + return (tmp[0], tmp[1]) + } + + public static func putAt2c(m: Mat, indices: [Int32], v: (Int8, Int8)) { + let tmp = [v.0, v.1] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt3c(m: Mat, indices:[Int32]) -> (Int8, Int8, Int8) { + var tmp = [Int8](repeating: 0, count: 3) + try! m.get(indices: indices, data: &tmp) + return (tmp[0], tmp[1], tmp[2]) + } + + public static func putAt3c(m: Mat, indices: [Int32], v: (Int8, Int8, Int8)) { + let tmp = [v.0, v.1, v.2] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt4c(m: Mat, indices:[Int32]) -> (Int8, Int8, Int8, Int8) { + var tmp = [Int8](repeating: 0, count: 4) + try! m.get(indices: indices, data: &tmp) + return (tmp[0], tmp[1], tmp[2], tmp[3]) + } + + public static func putAt4c(m: Mat, indices: [Int32], v: (Int8, Int8, Int8, Int8)) { + let tmp = [v.0, v.1, v.2, v.3] + try! m.put(indices: indices, data: tmp) + } +} + +extension Double: Atable { + public static func getAt(m: Mat, indices:[Int32]) -> Double { + var tmp = [Double](repeating: 0, count: 1) + try! m.get(indices: indices, data: &tmp) + return tmp[0] + } + + public static func putAt(m: Mat, indices: [Int32], v: Double) { + let tmp = [v] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt2c(m: Mat, indices:[Int32]) -> (Double, Double) { + var tmp = [Double](repeating: 0, count: 2) + try! m.get(indices: indices, data: &tmp) + return (tmp[0], tmp[1]) + } + + public static func putAt2c(m: Mat, indices: [Int32], v: (Double, Double)) { + let tmp = [v.0, v.1] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt3c(m: Mat, indices:[Int32]) -> (Double, Double, Double) { + var tmp = [Double](repeating: 0, count: 3) + try! m.get(indices: indices, data: &tmp) + return (tmp[0], tmp[1], tmp[2]) + } + + public static func putAt3c(m: Mat, indices: [Int32], v: (Double, Double, Double)) { + let tmp = [v.0, v.1, v.2] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt4c(m: Mat, indices:[Int32]) -> (Double, Double, Double, Double) { + var tmp = [Double](repeating: 0, count: 4) + try! m.get(indices: indices, data: &tmp) + return (tmp[0], tmp[1], tmp[2], tmp[3]) + } + + public static func putAt4c(m: Mat, indices: [Int32], v: (Double, Double, Double, Double)) { + let tmp = [v.0, v.1, v.2, v.3] + try! m.put(indices: indices, data: tmp) + } +} + +extension Float: Atable { + public static func getAt(m: Mat, indices:[Int32]) -> Float { + var tmp = [Float](repeating: 0, count: 1) + try! m.get(indices: indices, data: &tmp) + return tmp[0] + } + + public static func putAt(m: Mat, indices: [Int32], v: Float) { + let tmp = [v] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt2c(m: Mat, indices:[Int32]) -> (Float, Float) { + var tmp = [Float](repeating: 0, count: 2) + try! m.get(indices: indices, data: &tmp) + return (tmp[0], tmp[1]) + } + + public static func putAt2c(m: Mat, indices: [Int32], v: (Float, Float)) { + let tmp = [v.0, v.1] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt3c(m: Mat, indices:[Int32]) -> (Float, Float, Float) { + var tmp = [Float](repeating: 0, count: 3) + try! m.get(indices: indices, data: &tmp) + return (tmp[0], tmp[1], tmp[2]) + } + + public static func putAt3c(m: Mat, indices: [Int32], v: (Float, Float, Float)) { + let tmp = [v.0, v.1, v.2] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt4c(m: Mat, indices:[Int32]) -> (Float, Float, Float, Float) { + var tmp = [Float](repeating: 0, count: 4) + try! m.get(indices: indices, data: &tmp) + return (tmp[0], tmp[1], tmp[2], tmp[3]) + } + + public static func putAt4c(m: Mat, indices: [Int32], v: (Float, Float, Float, Float)) { + let tmp = [v.0, v.1, v.2, v.3] + try! m.put(indices: indices, data: tmp) + } +} + +extension Int32: Atable { + public static func getAt(m: Mat, indices:[Int32]) -> Int32 { + var tmp = [Int32](repeating: 0, count: 1) + try! m.get(indices: indices, data: &tmp) + return tmp[0] + } + + public static func putAt(m: Mat, indices: [Int32], v: Int32) { + let tmp = [v] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt2c(m: Mat, indices:[Int32]) -> (Int32, Int32) { + var tmp = [Int32](repeating: 0, count: 2) + try! m.get(indices: indices, data: &tmp) + return (tmp[0], tmp[1]) + } + + public static func putAt2c(m: Mat, indices: [Int32], v: (Int32, Int32)) { + let tmp = [v.0, v.1] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt3c(m: Mat, indices:[Int32]) -> (Int32, Int32, Int32) { + var tmp = [Int32](repeating: 0, count: 3) + try! m.get(indices: indices, data: &tmp) + return (tmp[0], tmp[1], tmp[2]) + } + + public static func putAt3c(m: Mat, indices: [Int32], v: (Int32, Int32, Int32)) { + let tmp = [v.0, v.1, v.2] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt4c(m: Mat, indices:[Int32]) -> (Int32, Int32, Int32, Int32) { + var tmp = [Int32](repeating: 0, count: 4) + try! m.get(indices: indices, data: &tmp) + return (tmp[0], tmp[1], tmp[2], tmp[3]) + } + + public static func putAt4c(m: Mat, indices: [Int32], v: (Int32, Int32, Int32, Int32)) { + let tmp = [v.0, v.1, v.2, v.3] + try! m.put(indices: indices, data: tmp) + } +} + +extension Int16: Atable { + public static func getAt(m: Mat, indices:[Int32]) -> Int16 { + var tmp = [Int16](repeating: 0, count: 1) + try! m.get(indices: indices, data: &tmp) + return tmp[0] + } + + public static func putAt(m: Mat, indices: [Int32], v: Int16) { + let tmp = [v] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt2c(m: Mat, indices:[Int32]) -> (Int16, Int16) { + var tmp = [Int16](repeating: 0, count: 2) + try! m.get(indices: indices, data: &tmp) + return (tmp[0], tmp[1]) + } + + public static func putAt2c(m: Mat, indices: [Int32], v: (Int16, Int16)) { + let tmp = [v.0, v.1] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt3c(m: Mat, indices:[Int32]) -> (Int16, Int16, Int16) { + var tmp = [Int16](repeating: 0, count: 3) + try! m.get(indices: indices, data: &tmp) + return (tmp[0], tmp[1], tmp[2]) + } + + public static func putAt3c(m: Mat, indices: [Int32], v: (Int16, Int16, Int16)) { + let tmp = [v.0, v.1, v.2] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt4c(m: Mat, indices:[Int32]) -> (Int16, Int16, Int16, Int16) { + var tmp = [Int16](repeating: 0, count: 4) + try! m.get(indices: indices, data: &tmp) + return (tmp[0], tmp[1], tmp[2], tmp[3]) + } + + public static func putAt4c(m: Mat, indices: [Int32], v: (Int16, Int16, Int16, Int16)) { + let tmp = [v.0, v.1, v.2, v.3] + try! m.put(indices: indices, data: tmp) + } +} + +/*** + * Example use: + * + * let elemantVal: UInt8 = mat.at(row: 50, col: 50).v + * mat.at(row: 50, col: 50).v = 245 + * + */ +public extension Mat { + func at(row: Int32, col: Int32) -> MatAt { + return MatAt(mat: self, indices: [row, col]) + } + + func at(indices:[Int32]) -> MatAt { + return MatAt(mat: self, indices: indices) + } +} diff --git a/modules/core/misc/objc/test/MatTest.swift b/modules/core/misc/objc/test/MatTest.swift index af26eb0bdb..14c440b5eb 100644 --- a/modules/core/misc/objc/test/MatTest.swift +++ b/modules/core/misc/objc/test/MatTest.swift @@ -1143,4 +1143,28 @@ class MatTests: OpenCVTestCase { XCTAssertEqual(5, bufferOut[63*80 + 63]) } + func testMatAt() { + let uc1 = Mat(rows: 2, cols: 3, type: CvType.CV_8U) + try! uc1.put(row: 0, col: 0, data: [1, 2, 3, 4, 5, 6] as [Int8]) + XCTAssertEqual(UInt8(1), uc1.at(row: 0, col: 0).v) + XCTAssertEqual(UInt8(2), uc1.at(row: 0, col: 1).v) + XCTAssertEqual(UInt8(3), uc1.at(row: 0, col: 2).v) + XCTAssertEqual(UInt8(4), uc1.at(row: 1, col: 0).v) + XCTAssertEqual(UInt8(5), uc1.at(row: 1, col: 1).v) + XCTAssertEqual(UInt8(6), uc1.at(row: 1, col: 2).v) + uc1.at(row: 0, col: 0).v = UInt8(7) + uc1.at(row: 0, col: 1).v = UInt8(8) + uc1.at(row: 0, col: 2).v = UInt8(9) + uc1.at(row: 1, col: 0).v = UInt8(10) + uc1.at(row: 1, col: 1).v = UInt8(11) + uc1.at(row: 1, col: 2).v = UInt8(12) + var data = [Int8](repeating: 0, count: 6) + try! uc1.get(row: 0, col: 0, data: &data) + XCTAssertEqual(data, [7, 8, 9, 10, 11, 12] as [Int8]) + let (b, g, r): T3 = rgbLena.at(row: 0, col: 0).v3c + XCTAssertEqual(b, UInt8(128)) + XCTAssertEqual(g, UInt8(138)) + XCTAssertEqual(r, UInt8(225)) + } + }