Improvements/fixes for unsigned type handling in Swift/Kotlin
authorGiles Payne <gilespayne@gmail.com>
Sun, 27 Jun 2021 12:08:25 +0000 (21:08 +0900)
committerGiles Payne <gilespayne@gmail.com>
Sun, 27 Jun 2021 12:08:25 +0000 (21:08 +0900)
modules/core/misc/java/src/java/core+MatAt.kt
modules/core/misc/objc/common/Mat.mm
modules/core/misc/objc/common/MatExt.swift
modules/core/misc/objc/test/MatTest.swift

index f48a3deaedf90e0d0368fbcfcef926a63ceee50a..c81e21057f272c9d516b418bcc6d2697b325c1f9 100644 (file)
@@ -3,6 +3,16 @@ package org.opencv.core
 import org.opencv.core.Mat.*
 import java.lang.RuntimeException
 
+fun Mat.get(row: Int, col: Int, data: UByteArray)  = this.get(row, col, data.asByteArray())
+fun Mat.get(indices: IntArray, data: UByteArray)  = this.get(indices, data.asByteArray())
+fun Mat.put(row: Int, col: Int, data: UByteArray)  = this.put(row, col, data.asByteArray())
+fun Mat.put(indices: IntArray, data: UByteArray)  = this.put(indices, data.asByteArray())
+
+fun Mat.get(row: Int, col: Int, data: UShortArray)  = this.get(row, col, data.asShortArray())
+fun Mat.get(indices: IntArray, data: UShortArray)  = this.get(indices, data.asShortArray())
+fun Mat.put(row: Int, col: Int, data: UShortArray)  = this.put(row, col, data.asShortArray())
+fun Mat.put(indices: IntArray, data: UShortArray)  = this.put(indices, data.asShortArray())
+
 /***
  *  Example use:
  *
@@ -19,6 +29,7 @@ inline fun <reified T> Mat.at(row: Int, col: Int) : Atable<T> =
             col
         )
         UByte::class -> AtableUByte(this, row, col) as Atable<T>
+        UShort::class -> AtableUShort(this, row, col) as Atable<T>
         else -> throw RuntimeException("Unsupported class type")
     }
 
@@ -30,6 +41,7 @@ inline fun <reified T> Mat.at(idx: IntArray) : Atable<T> =
             idx
         )
         UByte::class -> AtableUByte(this, idx) as Atable<T>
+        UShort::class -> AtableUShort(this, idx) as Atable<T>
         else -> throw RuntimeException("Unsupported class type")
     }
 
@@ -38,46 +50,95 @@ class AtableUByte(val mat: Mat, val indices: IntArray): Atable<UByte> {
     constructor(mat: Mat, row: Int, col: Int) : this(mat, intArrayOf(row, col))
 
     override fun getV(): UByte {
-        val data = ByteArray(1)
-        mat[indices, data]
-        return data[0].toUByte()
+        val data = UByteArray(1)
+        mat.get(indices, data)
+        return data[0]
     }
 
     override fun setV(v: UByte) {
-        val data = byteArrayOf(v.toByte())
+        val data = ubyteArrayOf(v)
         mat.put(indices, data)
     }
 
     override fun getV2c(): Tuple2<UByte> {
-        val data = ByteArray(2)
-        mat[indices, data]
-        return Tuple2(data[0].toUByte(), data[1].toUByte())
+        val data = UByteArray(2)
+        mat.get(indices, data)
+        return Tuple2(data[0], data[1])
     }
 
     override fun setV2c(v: Tuple2<UByte>) {
-        val data = byteArrayOf(v._0.toByte(), v._1.toByte())
+        val data = ubyteArrayOf(v._0, v._1)
         mat.put(indices, data)
     }
 
     override fun getV3c(): Tuple3<UByte> {
-        val data = ByteArray(3)
-        mat[indices, data]
-        return Tuple3(data[0].toUByte(), data[1].toUByte(), data[2].toUByte())
+        val data = UByteArray(3)
+        mat.get(indices, data)
+        return Tuple3(data[0], data[1], data[2])
     }
 
     override fun setV3c(v: Tuple3<UByte>) {
-        val data = byteArrayOf(v._0.toByte(), v._1.toByte(), v._2.toByte())
+        val data = ubyteArrayOf(v._0, v._1, v._2)
         mat.put(indices, data)
     }
 
     override fun getV4c(): Tuple4<UByte> {
-        val data = ByteArray(4)
-        mat[indices, data]
-        return Tuple4(data[0].toUByte(), data[1].toUByte(), data[2].toUByte(), data[3].toUByte())
+        val data = UByteArray(4)
+        mat.get(indices, data)
+        return Tuple4(data[0], data[1], data[2], data[3])
     }
 
     override fun setV4c(v: Tuple4<UByte>) {
-        val data = byteArrayOf(v._0.toByte(), v._1.toByte(), v._2.toByte(), v._3.toByte())
+        val data = ubyteArrayOf(v._0, v._1, v._2, v._3)
+        mat.put(indices, data)
+    }
+}
+
+class AtableUShort(val mat: Mat, val indices: IntArray): Atable<UShort> {
+
+    constructor(mat: Mat, row: Int, col: Int) : this(mat, intArrayOf(row, col))
+
+    override fun getV(): UShort {
+        val data = UShortArray(1)
+        mat.get(indices, data)
+        return data[0]
+    }
+
+    override fun setV(v: UShort) {
+        val data = ushortArrayOf(v)
+        mat.put(indices, data)
+    }
+
+    override fun getV2c(): Tuple2<UShort> {
+        val data = UShortArray(2)
+        mat.get(indices, data)
+        return Tuple2(data[0], data[1])
+    }
+
+    override fun setV2c(v: Tuple2<UShort>) {
+        val data = ushortArrayOf(v._0, v._1)
+        mat.put(indices, data)
+    }
+
+    override fun getV3c(): Tuple3<UShort> {
+        val data = UShortArray(3)
+        mat.get(indices, data)
+        return Tuple3(data[0], data[1], data[2])
+    }
+
+    override fun setV3c(v: Tuple3<UShort>) {
+        val data = ushortArrayOf(v._0, v._1, v._2)
+        mat.put(indices, data)
+    }
+
+    override fun getV4c(): Tuple4<UShort> {
+        val data = UShortArray(4)
+        mat.get(indices, data)
+        return Tuple4(data[0], data[1], data[2], data[3])
+    }
+
+    override fun setV4c(v: Tuple4<UShort>) {
+        val data = ushortArrayOf(v._0, v._1, v._2, v._3)
         mat.put(indices, data)
     }
 }
index 5d41a3622e719a135ad6d6c0e86787dbc40d7dcf..045bd8393ea39961fbbd6ef51a23378c16b8f9e2 100644 (file)
@@ -548,7 +548,7 @@ template<typename T> void putData(uchar* dataDest, int count, T (^readData)(int)
     if (depth == CV_8U) {
         putData(dest, count, ^uchar (int index) { return cv::saturate_cast<uchar>(data[offset + index].doubleValue);} );
     } else if (depth == CV_8S) {
-        putData(dest, count, ^char (int index) { return cv::saturate_cast<char>(data[offset + index].doubleValue);} );
+        putData(dest, count, ^schar (int index) { return cv::saturate_cast<schar>(data[offset + index].doubleValue);} );
     } else if (depth == CV_16U) {
         putData(dest, count, ^ushort (int index) { return cv::saturate_cast<ushort>(data[offset + index].doubleValue);} );
     } else if (depth == CV_16S) {
index 5ce3a5e6fb566ca270e42532813d28555da8fc16..a6ba548599d80d6c2908799de08badaa65321186 100644 (file)
@@ -62,6 +62,21 @@ public extension Mat {
         }
     }
 
+    @discardableResult func get(indices:[Int32], data:inout [UInt8]) throws -> Int32 {
+        let channels = CvType.channels(Int32(type()))
+        if Int32(data.count) % channels != 0 {
+            try throwIncompatibleBufferSize(count: data.count, channels: channels)
+        } else if depth() != CvType.CV_8U {
+            try throwIncompatibleDataType(typeName: CvType.type(toString: type()))
+        }
+        let count = Int32(data.count)
+        return data.withUnsafeMutableBufferPointer { body in
+            body.withMemoryRebound(to: Int8.self) { reboundBody in
+                return __get(indices as [NSNumber], count: count, byteBuffer: reboundBody.baseAddress!)
+            }
+        }
+    }
+
     @discardableResult func get(indices:[Int32], data:inout [Double]) throws -> Int32 {
         let channels = CvType.channels(Int32(type()))
         if Int32(data.count) % channels != 0 {
@@ -114,10 +129,29 @@ public extension Mat {
         }
     }
 
+    @discardableResult func get(indices:[Int32], data:inout [UInt16]) throws -> Int32 {
+        let channels = CvType.channels(Int32(type()))
+        if Int32(data.count) % channels != 0 {
+            try throwIncompatibleBufferSize(count: data.count, channels: channels)
+        } else if depth() != CvType.CV_16U {
+            try throwIncompatibleDataType(typeName: CvType.type(toString: type()))
+        }
+        let count = Int32(data.count)
+        return data.withUnsafeMutableBufferPointer { body in
+            body.withMemoryRebound(to: Int16.self) { reboundBody in
+                return __get(indices as [NSNumber], count: count, shortBuffer: reboundBody.baseAddress!)
+            }
+        }
+    }
+
     @discardableResult func get(row: Int32, col: Int32, data:inout [Int8]) throws -> Int32 {
         return try get(indices: [row, col], data: &data)
     }
 
+    @discardableResult func get(row: Int32, col: Int32, data:inout [UInt8]) throws -> Int32 {
+        return try get(indices: [row, col], data: &data)
+    }
+
     @discardableResult func get(row: Int32, col: Int32, data:inout [Double]) throws -> Int32 {
         return try get(indices: [row, col], data: &data)
     }
@@ -134,6 +168,10 @@ public extension Mat {
         return try get(indices: [row, col], data: &data)
     }
 
+    @discardableResult func get(row: Int32, col: Int32, data:inout [UInt16]) throws -> Int32 {
+        return try get(indices: [row, col], data: &data)
+    }
+
     @discardableResult func put(indices:[Int32], data:[Int8]) throws -> Int32 {
         let channels = CvType.channels(Int32(type()))
         if Int32(data.count) % channels != 0 {
@@ -147,6 +185,21 @@ public extension Mat {
         }
     }
 
+    @discardableResult func put(indices:[Int32], data:[UInt8]) throws -> Int32 {
+        let channels = CvType.channels(Int32(type()))
+        if Int32(data.count) % channels != 0 {
+            try throwIncompatibleBufferSize(count: data.count, channels: channels)
+        } else if depth() != CvType.CV_8U {
+            try throwIncompatibleDataType(typeName: CvType.type(toString: type()))
+        }
+        let count = Int32(data.count)
+        return data.withUnsafeBufferPointer { body in
+            body.withMemoryRebound(to: Int8.self) { reboundBody in
+                return __put(indices as [NSNumber], count: count, byteBuffer: reboundBody.baseAddress!)
+            }
+        }
+    }
+
     @discardableResult func put(indices:[Int32], data:[Int8], offset: Int, length: Int32) throws -> Int32 {
         let channels = CvType.channels(Int32(type()))
         if Int32(data.count) % channels != 0 {
@@ -214,10 +267,29 @@ public extension Mat {
         }
     }
 
+    @discardableResult func put(indices:[Int32], data:[UInt16]) throws -> Int32 {
+        let channels = CvType.channels(Int32(type()))
+        if Int32(data.count) % channels != 0 {
+            try throwIncompatibleBufferSize(count: data.count, channels: channels)
+        } else if depth() != CvType.CV_16U {
+            try throwIncompatibleDataType(typeName: CvType.type(toString: type()))
+        }
+        let count = Int32(data.count)
+        return data.withUnsafeBufferPointer { body in
+            body.withMemoryRebound(to: Int16.self) { reboundBody in
+                return __put(indices as [NSNumber], count: count, shortBuffer: reboundBody.baseAddress!)
+            }
+        }
+    }
+
     @discardableResult func put(row: Int32, col: Int32, data:[Int8]) throws -> Int32 {
         return try put(indices: [row, col], data: data)
     }
 
+    @discardableResult func put(row: Int32, col: Int32, data:[UInt8]) throws -> Int32 {
+        return try put(indices: [row, col], data: data)
+    }
+
     @discardableResult func put(row: Int32, col: Int32, data: [Int8], offset: Int, length: Int32) throws -> Int32 {
         return try put(indices: [row, col], data: data, offset: offset, length: length)
     }
@@ -238,6 +310,10 @@ public extension Mat {
         return try put(indices: [row, col], data: data)
     }
 
+    @discardableResult func put(row: Int32, col: Int32, data: [UInt16]) throws -> Int32 {
+        return try put(indices: [row, col], data: data)
+    }
+
     @discardableResult func get(row: Int32, col: Int32) -> [Double] {
         return get(indices: [row, col])
     }
@@ -303,46 +379,46 @@ public class MatAt<N: Atable> {
 
 extension UInt8: Atable {
     public static func getAt(m: Mat, indices:[Int32]) -> UInt8 {
-        var tmp = [Int8](repeating: 0, count: 1)
+        var tmp = [UInt8](repeating: 0, count: 1)
         try! m.get(indices: indices, data: &tmp)
-        return UInt8(bitPattern: tmp[0])
+        return tmp[0]
     }
 
     public static func putAt(m: Mat, indices: [Int32], v: UInt8) {
-        let tmp = [Int8(bitPattern: v)]
+        let tmp = [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)
+        var tmp = [UInt8](repeating: 0, count: 2)
         try! m.get(indices: indices, data: &tmp)
-        return (UInt8(bitPattern: tmp[0]), UInt8(bitPattern: tmp[1]))
+        return (tmp[0], tmp[1])
     }
 
     public static func putAt2c(m: Mat, indices: [Int32], v: (UInt8, UInt8)) {
-        let tmp = [Int8(bitPattern: v.0), Int8(bitPattern: v.1)]
+        let tmp = [v.0, 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)
+        var tmp = [UInt8](repeating: 0, count: 3)
         try! m.get(indices: indices, data: &tmp)
-        return (UInt8(bitPattern: tmp[0]), UInt8(bitPattern: tmp[1]), UInt8(bitPattern: tmp[2]))
+        return (tmp[0], tmp[1], 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)]
+        let tmp = [v.0, v.1, 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)
+        var tmp = [UInt8](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]))
+        return (tmp[0], tmp[1], tmp[2], 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)]
+        let tmp = [v.0, v.1, v.2, v.3]
         try! m.put(indices: indices, data: tmp)
     }
 }
@@ -531,6 +607,52 @@ extension Int32: Atable {
     }
 }
 
+extension UInt16: Atable {
+    public static func getAt(m: Mat, indices:[Int32]) -> UInt16 {
+        var tmp = [UInt16](repeating: 0, count: 1)
+        try! m.get(indices: indices, data: &tmp)
+        return tmp[0]
+    }
+
+    public static func putAt(m: Mat, indices: [Int32], v: UInt16) {
+        let tmp = [v]
+        try! m.put(indices: indices, data: tmp)
+    }
+
+    public static func getAt2c(m: Mat, indices:[Int32]) -> (UInt16, UInt16) {
+        var tmp = [UInt16](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: (UInt16, UInt16)) {
+        let tmp = [v.0, v.1]
+        try! m.put(indices: indices, data: tmp)
+    }
+
+    public static func getAt3c(m: Mat, indices:[Int32]) -> (UInt16, UInt16, UInt16) {
+        var tmp = [UInt16](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: (UInt16, UInt16, UInt16)) {
+        let tmp = [v.0, v.1, v.2]
+        try! m.put(indices: indices, data: tmp)
+    }
+
+    public static func getAt4c(m: Mat, indices:[Int32]) -> (UInt16, UInt16, UInt16, UInt16) {
+        var tmp = [UInt16](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: (UInt16, UInt16, UInt16, UInt16)) {
+        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)
index 14c440b5eb889e81600a977ad2058ee81c77c626..8a513505cc14ea778e9c5a8456b61c1f4f05257e 100644 (file)
@@ -308,15 +308,15 @@ class MatTests: OpenCVTestCase {
         XCTAssert([340] == sm.get(row: 1, col: 1))
     }
 
-    func testGetIntIntByteArray() throws {
-        let m = try getTestMat(size: 5, type: CvType.CV_8UC3)
+    func testGetIntIntInt8Array() throws {
+        let m = try getTestMat(size: 5, type: CvType.CV_8SC3)
         var goodData = [Int8](repeating: 0, count: 9)
 
         // whole Mat
         var bytesNum = try m.get(row: 1, col: 1, data: &goodData)
 
         XCTAssertEqual(9, bytesNum)
-        XCTAssert([110, 111, 112, 120, 121, 122, -126, -125, -124] == goodData)
+        XCTAssert([110, 111, 112, 120, 121, 122, 127, 127, 127] == goodData)
 
         var badData = [Int8](repeating: 0, count: 7)
         XCTAssertThrowsError(bytesNum = try m.get(row: 0, col: 0, data: &badData))
@@ -326,11 +326,36 @@ class MatTests: OpenCVTestCase {
         var buff00 = [Int8](repeating: 0, count: 3)
         bytesNum = try sm.get(row: 0, col: 0, data: &buff00)
         XCTAssertEqual(3, bytesNum)
-        XCTAssert(buff00 == [-26, -25, -24])
+        XCTAssert(buff00 == [127, 127, 127])
         var buff11 = [Int8](repeating: 0, count: 3)
         bytesNum = try sm.get(row: 1, col: 1, data: &buff11)
         XCTAssertEqual(3, bytesNum)
-        XCTAssert(buff11 == [-1, -1, -1])
+        XCTAssert(buff11 == [127, 127, 127])
+    }
+
+    func testGetIntIntUInt8Array() throws {
+        let m = try getTestMat(size: 5, type: CvType.CV_8UC3)
+        var goodData = [UInt8](repeating: 0, count: 9)
+
+        // whole Mat
+        var bytesNum = try m.get(row: 1, col: 1, data: &goodData)
+
+        XCTAssertEqual(9, bytesNum)
+        XCTAssert([110, 111, 112, 120, 121, 122, 130, 131, 132] == goodData)
+
+        var badData = [UInt8](repeating: 0, count: 7)
+        XCTAssertThrowsError(bytesNum = try m.get(row: 0, col: 0, data: &badData))
+
+        // sub-Mat
+        let sm = m.submat(rowStart: 2, rowEnd: 4, colStart: 3, colEnd: 5)
+        var buff00 = [UInt8](repeating: 0, count: 3)
+        bytesNum = try sm.get(row: 0, col: 0, data: &buff00)
+        XCTAssertEqual(3, bytesNum)
+        XCTAssert(buff00 == [230, 231, 232])
+        var buff11 = [UInt8](repeating: 0, count: 3)
+        bytesNum = try sm.get(row: 1, col: 1, data: &buff11)
+        XCTAssertEqual(3, bytesNum)
+        XCTAssert(buff11 == [255, 255, 255])
     }
 
     func testGetIntIntDoubleArray() throws {
@@ -399,7 +424,7 @@ class MatTests: OpenCVTestCase {
         XCTAssert(buff11 == [340, 341, 0, 0])
     }
 
-    func testGetIntIntShortArray() throws {
+    func testGetIntIntInt16Array() throws {
         let m = try getTestMat(size: 5, type: CvType.CV_16SC2)
         var buff = [Int16](repeating: 0, count: 6)
 
@@ -421,6 +446,28 @@ class MatTests: OpenCVTestCase {
         XCTAssert(buff11 == [340, 341, 0, 0])
     }
 
+    func testGetIntIntUInt16Array() throws {
+        let m = try getTestMat(size: 5, type: CvType.CV_16UC2)
+        var buff = [UInt16](repeating: 0, count: 6)
+
+        // whole Mat
+        var bytesNum = try m.get(row: 1, col: 1, data: &buff)
+
+        XCTAssertEqual(12, bytesNum);
+        XCTAssert(buff == [110, 111, 120, 121, 130, 131])
+
+        // sub-Mat
+        let sm = m.submat(rowStart: 2, rowEnd: 4, colStart: 3, colEnd: 5)
+        var buff00 = [UInt16](repeating: 0, count: 4)
+        bytesNum = try sm.get(row: 0, col: 0, data: &buff00)
+        XCTAssertEqual(8, bytesNum)
+        XCTAssert(buff00 == [230, 231, 240, 241])
+        var buff11 = [UInt16](repeating: 0, count: 4)
+        bytesNum = try sm.get(row: 1, col: 1, data: &buff11)
+        XCTAssertEqual(4, bytesNum);
+        XCTAssert(buff11 == [340, 341, 0, 0])
+    }
+
     func testHeight() {
         XCTAssertEqual(gray0.rows(), gray0.height())
         XCTAssertEqual(rgbLena.rows(), rgbLena.height())
@@ -653,7 +700,7 @@ class MatTests: OpenCVTestCase {
         try assertMatEqual(truth!, m1, OpenCVTestCase.EPS)
     }
 
-    func testPutIntIntByteArray() throws {
+    func testPutIntIntInt8Array() throws {
         let m = Mat(rows: 5, cols: 5, type: CvType.CV_8SC3, scalar: Scalar(1, 2, 3))
         let sm = m.submat(rowStart: 2, rowEnd: 4, colStart: 3, colEnd: 5)
         var buff = [Int8](repeating: 0, count: 6)
@@ -683,7 +730,37 @@ class MatTests: OpenCVTestCase {
         XCTAssert(buff == buff0)
     }
 
-    func testPutIntArrayByteArray() throws {
+    func testPutIntIntUInt8Array() throws {
+        let m = Mat(rows: 5, cols: 5, type: CvType.CV_8UC3, scalar: Scalar(1, 2, 3))
+        let sm = m.submat(rowStart: 2, rowEnd: 4, colStart: 3, colEnd: 5)
+        var buff = [UInt8](repeating: 0, count: 6)
+        let buff0:[UInt8] = [10, 20, 30, 40, 50, 60]
+        let buff1:[UInt8] = [255, 254, 253, 252, 251, 250]
+
+        var bytesNum = try m.put(row:1, col:2, data:buff0)
+
+        XCTAssertEqual(6, bytesNum)
+        bytesNum = try m.get(row: 1, col: 2, data: &buff)
+        XCTAssertEqual(6, bytesNum)
+        XCTAssert(buff == buff0)
+
+        bytesNum = try sm.put(row:0, col:0, data:buff1)
+
+        XCTAssertEqual(6, bytesNum)
+        bytesNum = try sm.get(row: 0, col: 0, data: &buff)
+        XCTAssertEqual(6, bytesNum)
+        XCTAssert(buff == buff1)
+        bytesNum = try m.get(row: 2, col: 3, data: &buff)
+        XCTAssertEqual(6, bytesNum);
+        XCTAssert(buff == buff1)
+
+        let m1 = m.row(1)
+        bytesNum = try m1.get(row: 0, col: 2, data: &buff)
+        XCTAssertEqual(6, bytesNum)
+        XCTAssert(buff == buff0)
+    }
+
+    func testPutIntArrayInt8Array() throws {
         let m = Mat(sizes: [5, 5, 5], type: CvType.CV_8SC3, scalar: Scalar(1, 2, 3))
         let sm = m.submat(ranges: [Range(start: 0, end: 2), Range(start: 1, end: 3), Range(start: 2, end: 4)])
         var buff = [Int8](repeating: 0, count: 6)
@@ -714,10 +791,41 @@ class MatTests: OpenCVTestCase {
         XCTAssert(buff == buff0)
     }
 
+    func testPutIntArrayUInt8Array() throws {
+        let m = Mat(sizes: [5, 5, 5], type: CvType.CV_8UC3, scalar: Scalar(1, 2, 3))
+        let sm = m.submat(ranges: [Range(start: 0, end: 2), Range(start: 1, end: 3), Range(start: 2, end: 4)])
+        var buff = [UInt8](repeating: 0, count: 6)
+        let buff0:[UInt8] = [10, 20, 30, 40, 50, 60]
+        let buff1:[UInt8] = [255, 254, 253, 252, 251, 250]
+
+        var bytesNum = try m.put(indices:[1, 2, 0], data:buff0)
+
+        XCTAssertEqual(6, bytesNum)
+        bytesNum = try m.get(indices: [1, 2, 0], data: &buff)
+        XCTAssertEqual(6, bytesNum)
+        XCTAssert(buff == buff0)
+
+        bytesNum = try sm.put(indices: [0, 0, 0], data: buff1)
+
+        XCTAssertEqual(6, bytesNum)
+        bytesNum = try sm.get(indices: [0, 0, 0], data: &buff)
+        XCTAssertEqual(6, bytesNum)
+        XCTAssert(buff == buff1)
+
+        bytesNum = try m.get(indices: [0, 1, 2], data: &buff)
+        XCTAssertEqual(6, bytesNum)
+        XCTAssert(buff == buff1)
+
+        let m1 = m.submat(ranges: [Range(start: 1,end: 2), Range.all(), Range.all()])
+        bytesNum = try m1.get(indices: [0, 2, 0], data: &buff)
+        XCTAssertEqual(6, bytesNum)
+        XCTAssert(buff == buff0)
+    }
+
     func testPutIntIntDoubleArray() throws {
-        let m = Mat(rows: 5, cols: 5, type: CvType.CV_8SC3, scalar: Scalar(1, 2, 3))
+        let m = Mat(rows: 5, cols: 5, type: CvType.CV_8UC3, scalar: Scalar(1, 2, 3))
         let sm = m.submat(rowStart: 2, rowEnd: 4, colStart: 3, colEnd: 5)
-        var buff = [Int8](repeating: 0, count: 6)
+        var buff = [UInt8](repeating: 0, count: 6)
 
         var bytesNum = try m.put(row: 1, col: 2, data: [10, 20, 30, 40, 50, 60] as [Double])
 
@@ -731,16 +839,16 @@ class MatTests: OpenCVTestCase {
         XCTAssertEqual(6, bytesNum)
         bytesNum = try sm.get(row: 0, col: 0, data: &buff)
         XCTAssertEqual(6, bytesNum);
-        XCTAssert(buff == [-1, -2, -3, -4, -5, -6])
+        XCTAssert(buff == [255, 254, 253, 252, 251, 250])
         bytesNum = try m.get(row: 2, col: 3, data: &buff)
         XCTAssertEqual(6, bytesNum);
-        XCTAssert(buff == [-1, -2, -3, -4, -5, -6])
+        XCTAssert(buff == [255, 254, 253, 252, 251, 250])
     }
 
     func testPutIntArrayDoubleArray() throws {
-        let m = Mat(sizes: [5, 5, 5], type: CvType.CV_8SC3, scalar: Scalar(1, 2, 3))
+        let m = Mat(sizes: [5, 5, 5], type: CvType.CV_8UC3, scalar: Scalar(1, 2, 3))
         let sm = m.submat(ranges: [Range(start: 0, end: 2), Range(start: 1, end: 3), Range(start: 2, end: 4)])
-        var buff = [Int8](repeating: 0, count: 6)
+        var buff = [UInt8](repeating: 0, count: 6)
 
         var bytesNum = try m.put(indices: [1, 2, 0], data: [10, 20, 30, 40, 50, 60] as [Double])
 
@@ -754,10 +862,10 @@ class MatTests: OpenCVTestCase {
         XCTAssertEqual(6, bytesNum);
         bytesNum = try sm.get(indices: [0, 0, 0], data: &buff)
         XCTAssertEqual(6, bytesNum);
-        XCTAssert(buff == [-1, -2, -3, -4, -5, -6])
+        XCTAssert(buff == [255, 254, 253, 252, 251, 250])
         bytesNum = try m.get(indices: [0, 1, 2], data: &buff)
         XCTAssertEqual(6, bytesNum)
-        XCTAssert(buff == [-1, -2, -3, -4, -5, -6])
+        XCTAssert(buff == [255, 254, 253, 252, 251, 250])
     }
 
     func testPutIntIntFloatArray() throws {
@@ -820,7 +928,7 @@ class MatTests: OpenCVTestCase {
         XCTAssert([40, 50, 60] == m.get(indices: [0, 1, 0]))
     }
 
-    func testPutIntIntShortArray() throws {
+    func testPutIntIntInt16Array() throws {
         let m = Mat(rows: 5, cols: 5, type: CvType.CV_16SC3, scalar: Scalar(-1, -2, -3))
         let elements: [Int16] = [ 10, 20, 30, 40, 50, 60]
 
@@ -834,7 +942,21 @@ class MatTests: OpenCVTestCase {
         XCTAssert([40, 50, 60] == m.get(row: 2, col: 4))
     }
 
-    func testPutIntArrayShortArray() throws {
+    func testPutIntIntUInt16Array() throws {
+        let m = Mat(rows: 5, cols: 5, type: CvType.CV_16UC3, scalar: Scalar(-1, -2, -3))
+        let elements: [UInt16] = [ 10, 20, 30, 40, 50, 60]
+
+        var bytesNum = try m.put(row: 2, col: 3, data: elements)
+
+        XCTAssertEqual(Int32(elements.count * 2), bytesNum)
+        let m1 = m.col(3)
+        var buff = [UInt16](repeating: 0, count: 3)
+        bytesNum = try m1.get(row: 2, col: 0, data: &buff)
+        XCTAssert(buff == [10, 20, 30])
+        XCTAssert([40, 50, 60] == m.get(row: 2, col: 4))
+    }
+
+    func testPutIntArrayInt16Array() throws {
         let m = Mat(sizes: [5, 5, 5], type: CvType.CV_16SC3, scalar: Scalar(-1, -2, -3))
         let elements: [Int16] = [ 10, 20, 30, 40, 50, 60]
 
@@ -848,6 +970,20 @@ class MatTests: OpenCVTestCase {
         XCTAssert([40, 50, 60] == m.get(indices: [0, 2, 4]))
     }
 
+    func testPutIntArrayUInt16Array() throws {
+        let m = Mat(sizes: [5, 5, 5], type: CvType.CV_16UC3, scalar: Scalar(-1, -2, -3))
+        let elements: [UInt16] = [ 10, 20, 30, 40, 50, 60]
+
+        var bytesNum = try m.put(indices: [0, 2, 3], data: elements)
+
+        XCTAssertEqual(Int32(elements.count * 2), bytesNum)
+        let m1 = m.submat(ranges: [Range.all(), Range.all(), Range(start: 3, end: 4)])
+        var buff = [UInt16](repeating: 0, count: 3)
+        bytesNum = try m1.get(indices: [0, 2, 0], data: &buff)
+        XCTAssert(buff == [10, 20, 30])
+        XCTAssert([40, 50, 60] == m.get(indices: [0, 2, 4]))
+    }
+
     func testReshapeInt() throws {
         let src = Mat(rows: 4, cols: 4, type: CvType.CV_8U, scalar: Scalar(0))
         dst = src.reshape(channels: 4)