diff --git a/lib/src/core/mat.dart b/lib/src/core/mat.dart index 72494315..8fa4eaf9 100644 --- a/lib/src/core/mat.dart +++ b/lib/src/core/mat.dart @@ -237,72 +237,81 @@ class Mat extends CvStruct { }); } - T _atNum(int row, int col, [int? cn]) { - return cvRunArena((arena) { - switch (type.depth) { - case MatType.CV_8U: - final p = arena(); - if (type.channels == 1 || cn == null) { - cvRun(() => CFFI.Mat_GetUChar(ref, row, col, p)); - } else { - cvRun(() => CFFI.Mat_GetUChar3(ref, row, col, cn, p)); - } - return p.value as T; - case MatType.CV_8S: - final p = arena(); - if (type.channels == 1 || cn == null) { - cvRun(() => CFFI.Mat_GetSChar(ref, row, col, p)); - } else { - cvRun(() => CFFI.Mat_GetSChar3(ref, row, col, cn, p)); - } - return p.value as T; - case MatType.CV_16U: - final p = arena(); - if (type.channels == 1 || cn == null) { - cvRun(() => CFFI.Mat_GetUShort(ref, row, col, p)); - } else { - cvRun(() => CFFI.Mat_GetUShort3(ref, row, col, cn, p)); - } - return p.value as T; - case MatType.CV_16S: - final p = arena(); - if (type.channels == 1 || cn == null) { - cvRun(() => CFFI.Mat_GetShort(ref, row, col, p)); - } else { - cvRun(() => CFFI.Mat_GetShort3(ref, row, col, cn, p)); - } - return p.value as T; - case MatType.CV_32S: - final p = arena(); - if (type.channels == 1 || cn == null) { - cvRun(() => CFFI.Mat_GetInt(ref, row, col, p)); - } else { - cvRun(() => CFFI.Mat_GetInt3(ref, row, col, cn, p)); - } - return p.value as T; - case MatType.CV_32F: - final p = arena(); - if (type.channels == 1 || cn == null) { - cvRun(() => CFFI.Mat_GetFloat(ref, row, col, p)); - } else { - cvRun(() => CFFI.Mat_GetFloat3(ref, row, col, cn, p)); - } - return p.value as T; - case MatType.CV_64F: - final p = arena(); - if (type.channels == 1 || cn == null) { - cvRun(() => CFFI.Mat_GetDouble(ref, row, col, p)); - } else { - cvRun(() => CFFI.Mat_GetDouble3(ref, row, col, cn, p)); - } - return p.value as T; - default: - throw UnsupportedError("at() for $type is not supported!"); - } + int atU8(int row, int col, [int? i2]) => using((arena) { + final p = arena(); + i2 == null + ? cvRun(() => CFFI.Mat_GetUChar(ref, row, col, p)) + : cvRun(() => CFFI.Mat_GetUChar3(ref, row, col, i2, p)); + return p.value; + }); + + int atI8(int row, int col, [int? i2]) => using((arena) { + final p = arena(); + i2 == null + ? cvRun(() => CFFI.Mat_GetSChar(ref, row, col, p)) + : cvRun(() => CFFI.Mat_GetSChar3(ref, row, col, i2, p)); + return p.value; + }); + + int atU16(int row, int col, [int? i2]) => using((arena) { + final p = arena(); + i2 == null + ? cvRun(() => CFFI.Mat_GetUShort(ref, row, col, p)) + : cvRun(() => CFFI.Mat_GetUShort3(ref, row, col, i2, p)); + return p.value; + }); + + int atI16(int row, int col, [int? i2]) => using((arena) { + final p = arena(); + i2 == null + ? cvRun(() => CFFI.Mat_GetShort(ref, row, col, p)) + : cvRun(() => CFFI.Mat_GetShort3(ref, row, col, i2, p)); + return p.value; + }); + + int atI32(int row, int col, [int? i2]) => using((arena) { + final p = arena(); + i2 == null + ? cvRun(() => CFFI.Mat_GetInt(ref, row, col, p)) + : cvRun(() => CFFI.Mat_GetInt3(ref, row, col, i2, p)); + return p.value; + }); + + double atF32(int row, int col, [int? i2]) => using((arena) { + final p = arena(); + i2 == null + ? cvRun(() => CFFI.Mat_GetFloat(ref, row, col, p)) + : cvRun(() => CFFI.Mat_GetFloat3(ref, row, col, i2, p)); + return p.value; + }); + + double atF64(int row, int col, [int? i2]) => using((arena) { + final p = arena(); + i2 == null + ? cvRun(() => CFFI.Mat_GetDouble(ref, row, col, p)) + : cvRun(() => CFFI.Mat_GetDouble3(ref, row, col, i2, p)); + return p.value; + }); + + num atNum(int row, int col, [int? i2]) { + return using((arena) { + final p = arena(); + cvRun(() => CFFI.Mat_Type(ref, p)); + final depth = p.value & (MatType.CV_DEPTH_MAX - 1); + return switch (depth) { + MatType.CV_8U => atU8(row, col, i2), + MatType.CV_8S => atI8(row, col, i2), + MatType.CV_16U => atU16(row, col, i2), + MatType.CV_16S => atI16(row, col, i2), + MatType.CV_32S => atI32(row, col, i2), + MatType.CV_32F => atF32(row, col, i2), + MatType.CV_64F => atF64(row, col, i2), + _ => throw UnsupportedError("Unsupported type: $type") + }; }); } - T _atVec(int row, int col) { + T atVec(int row, int col) { final v = cvRunArena((arena) { // Vec2b, Vec3b, Vec4b if (T == Vec2b) { @@ -412,76 +421,25 @@ class Mat extends CvStruct { /// cv::Mat::at\(i0, i1, i2) of cv::Mat /// - /// - /// - If matrix is of type [MatType.CV_8U] then use Mat.at\(y,x). - /// - If matrix is of type [MatType.CV_8S] then use Mat.at\(y,x). - /// - If matrix is of type [MatType.CV_16U] then use Mat.at\(y,x). - /// - If matrix is of type [MatType.CV_16S] then use Mat.at\(y,x). - /// - If matrix is of type [MatType.CV_32S] then use Mat.at\(y,x). - /// - If matrix is of type [MatType.CV_32F] then use Mat.at\(y,x). - /// - If matrix is of type [MatType.CV_64F] then use Mat.at\(y,x). - /// /// example: /// ```dart /// var m = cv.Mat.fromScalar(cv.Scalar(2, 4, 1, 0), cv.MatType.CV_32FC3); - /// m.at(0, 0); // 2 + /// m.at(0, 0); // 2.0 /// m.at(0, 0); // cv.Vec3f(2, 4, 1) /// ``` /// /// https://docs.opencv.org/4.x/d3/d63/classcv_1_1Mat.html#a7a6d7e3696b8b19b9dfac3f209118c40 T at(int row, int col, [int? i2]) { if (T == int || T == double) { - return _atNum(row, col, i2); + return atNum(row, col, i2) as T; } else if (isSubtype()) { - return _atVec(row, col); + return atVec(row, col); } else { throw UnsupportedError("T must be num or CvVec(e.g., Vec3b), but got $T"); } } - void _setNum(row, col, T val, [int? i2]) { - switch (type.depth) { - case MatType.CV_8U: - assert(T == int, "$type only support int"); - type.channels == 1 || i2 == null - ? cvRun(() => CFFI.Mat_SetUChar(ref, row, col, val as int)) - : cvRun(() => CFFI.Mat_SetUChar3(ref, row, col, i2, val as int)); - case MatType.CV_8S: - assert(T == int, "$type only support int"); - type.channels == 1 || i2 == null - ? cvRun(() => CFFI.Mat_SetSChar(ref, row, col, val as int)) - : cvRun(() => CFFI.Mat_SetSChar3(ref, row, col, i2, val as int)); - case MatType.CV_16U: - assert(T == int, "$type only support int"); - type.channels == 1 || i2 == null - ? cvRun(() => CFFI.Mat_SetUShort(ref, row, col, val as int)) - : cvRun(() => CFFI.Mat_SetUShort3(ref, row, col, i2, val as int)); - case MatType.CV_16S: - assert(T == int, "$type only support int"); - type.channels == 1 || i2 == null - ? cvRun(() => CFFI.Mat_SetShort(ref, row, col, val as int)) - : cvRun(() => CFFI.Mat_SetShort3(ref, row, col, i2, val as int)); - case MatType.CV_32S: - assert(T == int, "$type only support int"); - type.channels == 1 || i2 == null - ? cvRun(() => CFFI.Mat_SetInt(ref, row, col, val as int)) - : cvRun(() => CFFI.Mat_SetInt3(ref, row, col, i2, val as int)); - case MatType.CV_32F: - assert(T == double, "$type only support double"); - type.channels == 1 || i2 == null - ? cvRun(() => CFFI.Mat_SetFloat(ref, row, col, val as double)) - : cvRun(() => CFFI.Mat_SetFloat3(ref, row, col, i2, val as double)); - case MatType.CV_64F: - assert(T == double, "$type only support double"); - type.channels == 1 || i2 == null - ? cvRun(() => CFFI.Mat_SetDouble(ref, row, col, val as double)) - : cvRun(() => CFFI.Mat_SetDouble3(ref, row, col, i2, val as double)); - default: - throw UnsupportedError("setValue() for $type is not supported!"); - } - } - - void _setVec(int row, int col, T val) { + void setVec(int row, int col, T val) { cvRunArena((arena) { // Vec2b, Vec3b, Vec4b if (val is Vec2b) { @@ -544,8 +502,54 @@ class Mat extends CvStruct { }); } + void setU8(int row, int col, int val, [int? i2]) => i2 == null + ? cvRun(() => CFFI.Mat_SetUChar(ref, row, col, val)) + : cvRun(() => CFFI.Mat_SetUChar3(ref, row, col, i2, val)); + + void setI8(int row, int col, int val, [int? i2]) => i2 == null + ? cvRun(() => CFFI.Mat_SetSChar(ref, row, col, val)) + : cvRun(() => CFFI.Mat_SetSChar3(ref, row, col, i2, val)); + + void setU16(int row, int col, int val, [int? i2]) => i2 == null + ? cvRun(() => CFFI.Mat_SetUShort(ref, row, col, val)) + : cvRun(() => CFFI.Mat_SetUShort3(ref, row, col, i2, val)); + + void setI16(int row, int col, int val, [int? i2]) => i2 == null + ? cvRun(() => CFFI.Mat_SetShort(ref, row, col, val)) + : cvRun(() => CFFI.Mat_SetShort3(ref, row, col, i2, val)); + + void setI32(int row, int col, int val, [int? i2]) => i2 == null + ? cvRun(() => CFFI.Mat_SetInt(ref, row, col, val)) + : cvRun(() => CFFI.Mat_SetInt3(ref, row, col, i2, val)); + + void setF32(int row, int col, double val, [int? i2]) => i2 == null + ? cvRun(() => CFFI.Mat_SetFloat(ref, row, col, val)) + : cvRun(() => CFFI.Mat_SetFloat3(ref, row, col, i2, val)); + + void setF64(int row, int col, double val, [int? i2]) => i2 == null + ? cvRun(() => CFFI.Mat_SetDouble(ref, row, col, val)) + : cvRun(() => CFFI.Mat_SetDouble3(ref, row, col, i2, val)); + + void setNum(int row, int col, T val, [int? i2]) { + using((arena) { + final p = arena(); + cvRun(() => CFFI.Mat_Type(ref, p)); + final depth = p.value & (MatType.CV_DEPTH_MAX - 1); + return switch (depth) { + MatType.CV_8U => setU8(row, col, val as int, i2), + MatType.CV_8S => setI8(row, col, val as int, i2), + MatType.CV_16U => setU16(row, col, val as int, i2), + MatType.CV_16S => setI16(row, col, val as int, i2), + MatType.CV_32S => setI32(row, col, val as int, i2), + MatType.CV_32F => setF32(row, col, val as double, i2), + MatType.CV_64F => setF64(row, col, val as double, i2), + _ => throw UnsupportedError("Unsupported type: $type") + }; + }); + } + /// equivalent to Mat::at\(i0, i1, i2) = val; - /// where T might be int, double. + /// where T might be int, double, [U8], [I8], [U16], [I16], [I32], [F32], [F64]. /// or cv::Vec<> like cv::Vec3b /// /// example @@ -555,13 +559,27 @@ class Mat extends CvStruct { /// m.set(0, 0, cv.Vec3f(9, 9, 9)); /// m.at(0, 0); // cv.Vec3f(9, 9, 9) /// ``` - void set(int row, int col, T val, [int? i2]) { + void set(int row, int col, Object val, [int? i2]) { if (T == int || T == double) { - _setNum(row, col, val, i2); + setNum(row, col, val as num, i2); } else if (isSubtype()) { - _setVec(row, col, val); + setVec(row, col, val as T); + } else if (T == U8) { + setU8(row, col, val as int); + } else if (T == I8) { + setI8(row, col, val as int); + } else if (T == U16) { + setU16(row, col, val as int); + } else if (T == I16) { + setI16(row, col, val as int); + } else if (T == I32) { + setI32(row, col, val as int); + } else if (T == F32) { + setF32(row, col, val as double); + } else if (T == F64) { + setF64(row, col, val as double); } else { - throw UnsupportedError("T must be num or CvVec(e.g., Vec3b), but got $T"); + throw UnsupportedError("Unsupported type $T"); } } diff --git a/lib/src/core/mat_type.dart b/lib/src/core/mat_type.dart index 28a65d6d..4b639725 100644 --- a/lib/src/core/mat_type.dart +++ b/lib/src/core/mat_type.dart @@ -102,7 +102,7 @@ class MatType extends Equatable { CV_64FC4 = CV_64FC(4); /* - static const int + static const int CV_8UC1 = 0, CV_8SC1 = 1, CV_16UC1 = 2, diff --git a/test/calib3d_test.dart b/test/calib3d_test.dart index 7a8bfd29..636ba95d 100644 --- a/test/calib3d_test.dart +++ b/test/calib3d_test.dart @@ -8,16 +8,16 @@ void main() async { expect(img.isEmpty, false); final k = cv.Mat.zeros(3, 3, cv.MatType.CV_64FC1); k.set(0, 0, 689.21); - k.set(0, 1, 0); + k.set(0, 1, 0.0); k.set(0, 2, 1295.56); - k.set(1, 0, 0); + k.set(1, 0, 0.0); k.set(1, 1, 690.48); k.set(1, 2, 942.17); - k.set(2, 0, 0); - k.set(2, 1, 0); - k.set(2, 2, 1); + k.set(2, 0, 0.0); + k.set(2, 1, 0.0); + k.set(2, 2, 1.0); final d = cv.Mat.zeros(1, 4, cv.MatType.CV_64FC1); @@ -28,16 +28,16 @@ void main() async { test('cv.undistortPoints', () { final k = cv.Mat.zeros(3, 3, cv.MatType.CV_64FC1); k.set(0, 0, 1094.7249578198823); - k.set(0, 1, 0); + k.set(0, 1, 0.0); k.set(0, 2, 1094.7249578198823); - k.set(1, 0, 0); + k.set(1, 0, 0.0); k.set(1, 1, 1094.9945708128778); k.set(1, 2, 536.4566143451868); - k.set(2, 0, 0); - k.set(2, 1, 0); - k.set(2, 2, 1); + k.set(2, 0, 0.0); + k.set(2, 1, 0.0); + k.set(2, 2, 1.0); final d = cv.Mat.zeros(1, 4, cv.MatType.CV_64FC1); d.set(0, 0, -0.05207412392075069); @@ -57,14 +57,14 @@ void main() async { // (0 * 2) + channelNumber // so col = 0 is the x coordinate and col = 1 is the y coordinate - src.set(0, 0, 480); - src.set(0, 1, 270); + src.set(0, 0, 480.0); + src.set(0, 1, 270.0); - src.set(1, 0, 960); - src.set(1, 1, 540); + src.set(1, 0, 960.0); + src.set(1, 1, 540.0); - src.set(2, 0, 1920); - src.set(2, 1, 1080); + src.set(2, 0, 1920.0); + src.set(2, 1, 1080.0); cv.undistortPoints(src, k, d); final dst = cv.undistortPoints(src, k, d, R: r, P: k); @@ -76,16 +76,16 @@ void main() async { test('cv.Fisheye.undistortPoints', () { final k = cv.Mat.zeros(3, 3, cv.MatType.CV_64FC1); k.set(0, 0, 1094.7249578198823); - k.set(0, 1, 0); + k.set(0, 1, 0.0); k.set(0, 2, 959.4907612030962); - k.set(1, 0, 0); + k.set(1, 0, 0.0); k.set(1, 1, 1094.9945708128778); k.set(1, 2, 536.4566143451868); - k.set(2, 0, 0); - k.set(2, 1, 0); - k.set(2, 2, 1); + k.set(2, 0, 0.0); + k.set(2, 1, 0.0); + k.set(2, 2, 1.0); final d = cv.Mat.zeros(1, 4, cv.MatType.CV_64FC1); d.set(0, 0, -0.05207412392075069); @@ -97,14 +97,14 @@ void main() async { final src = cv.Mat.zeros(3, 1, cv.MatType.CV_64FC2); final dst = cv.Mat.zeros(3, 1, cv.MatType.CV_64FC2); - src.set(0, 0, 480); - src.set(0, 1, 270); + src.set(0, 0, 480.0); + src.set(0, 1, 270.0); - src.set(1, 0, 960); - src.set(1, 1, 540); + src.set(1, 0, 960.0); + src.set(1, 1, 540.0); - src.set(2, 0, 1440); - src.set(2, 1, 810); + src.set(2, 0, 1440.0); + src.set(2, 1, 810.0); final knew = k.clone(); knew.set(0, 0, 0.4 * k.at(0, 0)); @@ -133,16 +133,16 @@ void main() async { final k = cv.Mat.zeros(3, 3, cv.MatType.CV_64FC1); k.set(0, 0, 842.0261028); - k.set(0, 1, 0); + k.set(0, 1, 0.0); k.set(0, 2, 667.7569792); - k.set(1, 0, 0); + k.set(1, 0, 0.0); k.set(1, 1, 707.3668897); k.set(1, 2, 385.56476464); - k.set(2, 0, 0); - k.set(2, 1, 0); - k.set(2, 2, 1); + k.set(2, 0, 0.0); + k.set(2, 1, 0.0); + k.set(2, 2, 1.0); final d = cv.Mat.zeros(1, 5, cv.MatType.CV_64FC1); d.set(0, 0, -3.65584802e-01); diff --git a/test/contrib/img_hash_test.dart b/test/contrib/img_hash_test.dart index b70ce95f..5da07988 100644 --- a/test/contrib/img_hash_test.dart +++ b/test/contrib/img_hash_test.dart @@ -44,7 +44,7 @@ void main() async { final img = cv.Mat.ones(256, 256, cv.MatType.CV_8UC1); for (var i = 0; i < img.rows; i++) { for (var j = 0; j < img.cols; j++) { - img.set(i, j, i + j); + img.set(i, j, i + j); } } bmh.compute(img, hash); diff --git a/test/core/mat_test.dart b/test/core/mat_test.dart index 7abef70e..6b759511 100644 --- a/test/core/mat_test.dart +++ b/test/core/mat_test.dart @@ -1,3 +1,5 @@ +// ignore_for_file: avoid_print + import 'dart:ffi' as ffi; import 'package:test/test.dart'; @@ -21,7 +23,7 @@ void main() async { final mat2 = cv.Mat.zeros(3, 3, cv.MatType.CV_8UC1); expect((mat2.width, mat2.height, mat2.channels), (3, 3, 1)); expect(mat2.countNoneZero, equals(0)); - mat2.set(0, 0, 241); + mat2.setU8(0, 0, 241); expect(mat2.toList()[0][0], 241); final mat3 = cv.Mat.eye(3, 3, cv.MatType.CV_8UC3); @@ -242,6 +244,55 @@ void main() async { expect((mat1.height, mat1.width, mat1.channels), (200, 100, 3)); }); + test('cv.Mat.data', () { + { + final mat = cv.Mat.zeros(3, 3, cv.MatType.CV_8UC3); + final data = mat.data; + expect(data.length, mat.rows * mat.cols * mat.channels); + expect(data[0], 0); + data[0] = 2; + data[1] = 4; + data[2] = 1; + expect(mat.at(0, 0), cv.Vec3b(2, 4, 1)); + } + + { + final src = cv.Mat.zeros(3840, 2160, cv.MatType.CV_16UC3); + final lut = List.generate(65536, (i) => 65535 - i); + final dst = src.clone(); + final pSrc = src.data; + final pDst = dst.data; + final cn = src.channels; + final sw = Stopwatch(); + sw.start(); + for (int r = 0; r < src.rows; r++) { + for (int c = 0; c < src.cols; c++) { + for (int i = 0; i < cn; i++) { + final value = lut[pSrc[r + c * cn + i]]; + pDst[r + c * cn + i] = value; + } + } + } + sw.stop(); + // print('mat.data (${src.rows}x${src.cols}): ${sw.elapsedMilliseconds}ms'); + expect(dst.at(0, 0), cv.Vec3w(65535, 65535, 65535)); + } + + { + final src = cv.Mat.zeros(3840, 2160, cv.MatType.CV_16UC3); + final dataList = List.generate(65536, (i) => 65535 - i); + final lut = cv.Mat.fromList(1, dataList.length, cv.MatType.CV_16UC1, dataList); + final sw = Stopwatch(); + sw.start(); + final dst = cv.LUT(src, lut); + sw.stop(); + // print('mat.data LUT (${src.rows}x${src.cols}): ${sw.elapsedMilliseconds}ms'); + expect(dst.isEmpty, false); + expect(dst.shape, src.shape); + expect(dst.at(0, 0), cv.Vec3w(65535, 65535, 65535)); + } + }); + test('Mat test others', () { final mat0 = cv.Mat.fromScalar(200, 100, cv.MatType.CV_8UC3, cv.Scalar(1, 1, 1, 1)); expect(mat0.props, equals([mat0.ptr.address])); @@ -297,13 +348,16 @@ void main() async { expect(ptr0.address, greaterThan(0)); expect(ptr0[0], 1); ptr0[0] = 21; - expect(mat.at(0, 0), 21); + expect(mat.atI8(0, 0), 21); expect(ptr0[0], 21); final ptr1 = mat.ptrAt(0, 0); expect(ptr1.address, greaterThan(0)); expect(ptr1[0], 21); expect(List.generate(mat.cols, (i) => ptr1[i]), [21, 1, 1]); + + mat.set(0, 0, 2); + expect(mat.atI8(0, 0), 2); }); test('Mat.ptrAt.U16', () { @@ -390,7 +444,7 @@ void main() async { expect(mat.at(0, 0), 2); expect(mat.at(0, 0), cv.Vec2b(2, 4)); - mat.set(0, 0, 99); + mat.set(0, 0, 99); expect(mat.at(0, 0), 99); mat.set(0, 0, cv.Vec2b(99, 99)); @@ -400,7 +454,7 @@ void main() async { expect(mat.at(0, 0), 2); expect(mat.at(0, 0), cv.Vec3b(2, 4, 1)); - mat.set(0, 0, 99); + mat.setU8(0, 0, 99); expect(mat.at(0, 0), 99); mat.set(0, 0, cv.Vec3b(99, 99, 99)); @@ -410,7 +464,7 @@ void main() async { expect(mat.at(0, 0), 2); expect(mat.at(0, 0), cv.Vec4b(2, 4, 1, 0)); - mat.set(0, 0, 99); + mat.setU8(0, 0, 99); expect(mat.at(0, 0), 99); mat.set(0, 0, cv.Vec4b(99, 99, 99, 99)); @@ -422,7 +476,7 @@ void main() async { expect(mat.at(0, 0), 2); expect(mat.at(0, 0), cv.Vec2w(2, 4)); - mat.set(0, 0, 99); + mat.set(0, 0, 99); expect(mat.at(0, 0), 99); mat.set(0, 0, cv.Vec2w(99, 99)); @@ -432,7 +486,7 @@ void main() async { expect(mat.at(0, 0), 2); expect(mat.at(0, 0), cv.Vec3w(2, 4, 1)); - mat.set(0, 0, 99); + mat.setU16(0, 0, 99); expect(mat.at(0, 0), 99); mat.set(0, 0, cv.Vec3w(99, 99, 99)); @@ -442,7 +496,7 @@ void main() async { expect(mat.at(0, 0), 2); expect(mat.at(0, 0), cv.Vec4w(2, 4, 1, 0)); - mat.set(0, 0, 99); + mat.setU16(0, 0, 99); expect(mat.at(0, 0), 99); mat.set(0, 0, cv.Vec4w(99, 99, 99, 99)); @@ -454,7 +508,7 @@ void main() async { expect(mat.at(0, 0), 2); expect(mat.at(0, 0), cv.Vec2s(2, 4)); - mat.set(0, 0, 99); + mat.set(0, 0, 99); expect(mat.at(0, 0), 99); mat.set(0, 0, cv.Vec2s(99, 99)); @@ -464,7 +518,7 @@ void main() async { expect(mat.at(0, 0), 2); expect(mat.at(0, 0), cv.Vec3s(2, 4, 1)); - mat.set(0, 0, 99); + mat.setI16(0, 0, 99); expect(mat.at(0, 0), 99); mat.set(0, 0, cv.Vec3s(99, 99, 99)); @@ -474,7 +528,7 @@ void main() async { expect(mat.at(0, 0), 2); expect(mat.at(0, 0), cv.Vec4s(2, 4, 1, 0)); - mat.set(0, 0, 99); + mat.setI16(0, 0, 99); expect(mat.at(0, 0), 99); mat.set(0, 0, cv.Vec4s(99, 99, 99, 99)); @@ -486,7 +540,7 @@ void main() async { expect(mat.at(0, 0), 2); expect(mat.at(0, 0), cv.Vec2i(2, 4)); - mat.set(0, 0, 99); + mat.set(0, 0, 99); expect(mat.at(0, 0), 99); mat.set(0, 0, cv.Vec2i(99, 99)); @@ -496,7 +550,7 @@ void main() async { expect(mat.at(0, 0), 2); expect(mat.at(0, 0), cv.Vec3i(2, 4, 1)); - mat.set(0, 0, 99); + mat.setI32(0, 0, 99); expect(mat.at(0, 0), 99); mat.set(0, 0, cv.Vec3i(99, 99, 99)); @@ -506,7 +560,7 @@ void main() async { expect(mat.at(0, 0), 2); expect(mat.at(0, 0), cv.Vec4i(2, 4, 1, 0)); - mat.set(0, 0, 99); + mat.setI32(0, 0, 99); expect(mat.at(0, 0), 99); mat.set(0, 0, cv.Vec4i(99, 99, 99, 99)); @@ -518,8 +572,8 @@ void main() async { expect(mat.at(0, 0), closeTo(2, 1e-3)); expect(mat.at(0, 0), cv.Vec2f(2, 4)); - mat.set(0, 0, 99); - expect(mat.at(0, 0), 99); + mat.set(0, 0, 99.0); + expect(mat.at(0, 0), closeTo(99.0, 1e-6)); mat.set(0, 0, cv.Vec2f(99, 99)); expect(mat.at(0, 0), cv.Vec2f(99, 99)); @@ -528,8 +582,8 @@ void main() async { expect(mat.at(0, 0), closeTo(2, 1e-3)); expect(mat.at(0, 0), cv.Vec3f(2, 4, 1)); - mat.set(0, 0, 99); - expect(mat.at(0, 0), 99); + mat.setF32(0, 0, 99.0); + expect(mat.at(0, 0), closeTo(99.0, 1e-6)); mat.set(0, 0, cv.Vec3f(99, 99, 99)); expect(mat.at(0, 0), cv.Vec3f(99, 99, 99)); @@ -538,8 +592,8 @@ void main() async { expect(mat.at(0, 0), closeTo(2, 1e-3)); expect(mat.at(0, 0), cv.Vec4f(2, 4, 1, 0)); - mat.set(0, 0, 99); - expect(mat.at(0, 0), 99); + mat.setF32(0, 0, 99.0); + expect(mat.at(0, 0), closeTo(99.0, 1e-6)); mat.set(0, 0, cv.Vec4f(99, 99, 99, 99)); expect(mat.at(0, 0), cv.Vec4f(99, 99, 99, 99)); @@ -550,8 +604,8 @@ void main() async { expect(mat.at(0, 0), closeTo(2, 1e-3)); expect(mat.at(0, 0), cv.Vec2d(2, 4)); - mat.set(0, 0, 99); - expect(mat.at(0, 0), 99); + mat.set(0, 0, 99.0); + expect(mat.at(0, 0), closeTo(99.0, 1e-6)); mat.set(0, 0, cv.Vec2d(99, 99)); expect(mat.at(0, 0), cv.Vec2d(99, 99)); @@ -560,8 +614,8 @@ void main() async { expect(mat.at(0, 0), closeTo(2, 1e-3)); expect(mat.at(0, 0), cv.Vec3d(2, 4, 1)); - mat.set(0, 0, 99); - expect(mat.at(0, 0), 99); + mat.setF64(0, 0, 99.0); + expect(mat.at(0, 0), closeTo(99.0, 1e-6)); mat.set(0, 0, cv.Vec3d(99, 99, 99)); expect(mat.at(0, 0), cv.Vec3d(99, 99, 99)); @@ -570,10 +624,63 @@ void main() async { expect(mat.at(0, 0), closeTo(2, 1e-3)); expect(mat.at(0, 0), cv.Vec4d(2, 4, 1, 0)); - mat.set(0, 0, 99); - expect(mat.at(0, 0), 99); + mat.setF64(0, 0, 99.0); + expect(mat.at(0, 0), closeTo(99.0, 1e-6)); mat.set(0, 0, cv.Vec4d(99, 99, 99, 99)); expect(mat.at(0, 0), cv.Vec4d(99, 99, 99, 99)); }); + + test('Mat at set perf', () { + final mat = cv.Mat.zeros(3840, 2160, cv.MatType.CV_8UC1); + final sw = Stopwatch(); + + { + sw.reset(); + sw.start(); + for (var row = 0; row < mat.rows; row++) { + for (var col = 0; col < mat.cols; col++) { + mat.at(row, col); + } + } + sw.stop(); + print('Mat(${mat.rows}, ${mat.cols}, ${mat.type}).at: ${sw.elapsedMilliseconds}ms'); + } + + { + sw.reset(); + sw.start(); + for (var row = 0; row < mat.rows; row++) { + for (var col = 0; col < mat.cols; col++) { + mat.atU8(row, col); + } + } + sw.stop(); + print('Mat(${mat.rows}, ${mat.cols}, ${mat.type}).atU8: ${sw.elapsedMilliseconds}ms'); + } + + { + sw.reset(); + sw.start(); + for (var row = 0; row < mat.rows; row++) { + for (var col = 0; col < mat.cols; col++) { + mat.set(row, col, 1); + } + } + sw.stop(); + print('Mat(${mat.rows}, ${mat.cols}, ${mat.type}).set: ${sw.elapsedMilliseconds}ms'); + } + + { + sw.reset(); + sw.start(); + for (var row = 0; row < mat.rows; row++) { + for (var col = 0; col < mat.cols; col++) { + mat.setU8(row, col, 1); + } + } + sw.stop(); + print('Mat(${mat.rows}, ${mat.cols}, ${mat.type}).setU8: ${sw.elapsedMilliseconds}ms'); + } + }); } diff --git a/test/video_test.dart b/test/video_test.dart index 8bfc4efc..4886c3bc 100644 --- a/test/video_test.dart +++ b/test/video_test.dart @@ -64,8 +64,8 @@ void main() async { expect(img.isEmpty, false); final testImg = cv.resize(img, (216, 216)); final translationGround = cv.Mat.eye(2, 3, cv.MatType.CV_32FC1); - translationGround.set(0, 2, 11.4159); - translationGround.set(1, 2, 17.1828); + translationGround.set(0, 2, 11.4159); + translationGround.setF64(1, 2, 17.1828); final wrappedImage = cv.warpAffine( testImg,