diff --git a/lib/src/core/mat.dart b/lib/src/core/mat.dart index 438ce07a..ec5d9898 100644 --- a/lib/src/core/mat.dart +++ b/lib/src/core/mat.dart @@ -29,7 +29,7 @@ class Mat extends CvStruct { /// Mat (Size size, int type, void *data, size_t step=AUTO_STEP) /// /// https://docs.opencv.org/4.x/d3/d63/classcv_1_1Mat.html#a9fa74fb14362d87cb183453d2441948f - factory Mat.fromList(int rows, int cols, MatType type, List data, [int step = 0]) { + factory Mat.fromList(int rows, int cols, MatType type, List data, [int step = 0]) { assert(data is List || data is List, "Only support List or List"); final p = calloc(); // 1 copy @@ -425,7 +425,7 @@ class Mat extends CvStruct { /// /// 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) { + if (T == int || T == double || T == num) { return atNum(row, col, i2) as T; } else if (isSubtype()) { return atVec(row, col); @@ -1282,21 +1282,21 @@ class Mat extends CvStruct { void release() => cvRun(() => CFFI.Mat_Release(ptr)); /// This Method converts single-channel Mat to 2D List - List> toList() { - switch (type.depth) { - case MatType.CV_8U: - case MatType.CV_8S: - case MatType.CV_16U: - case MatType.CV_16S: - case MatType.CV_32S: - return List.generate(rows, (row) => List.generate(cols, (col) => at(row, col))); - case MatType.CV_32F: - case MatType.CV_64F: - return List.generate(rows, (row) => List.generate(cols, (col) => at(row, col))); - default: - throw UnsupportedError("toList() for $type is not supported!"); - } - } + List> toList() => switch (type.depth) { + MatType.CV_8U => List.generate(rows, (row) => List.generate(cols, (col) => atU8(row, col))), + MatType.CV_8S => List.generate(rows, (row) => List.generate(cols, (col) => atI8(row, col))), + MatType.CV_16U => + List.generate(rows, (row) => List.generate(cols, (col) => atU16(row, col))), + MatType.CV_16S => + List.generate(rows, (row) => List.generate(cols, (col) => atI16(row, col))), + MatType.CV_32S => + List.generate(rows, (row) => List.generate(cols, (col) => atI32(row, col))), + MatType.CV_32F => + List.generate(rows, (row) => List.generate(cols, (col) => atF32(row, col))), + MatType.CV_64F => + List.generate(rows, (row) => List.generate(cols, (col) => atF64(row, col))), + _ => throw UnsupportedError("toList() for $type is not supported!") + }; /// Returns a 3D list of the mat, only for multi-channel mats. /// The list is ordered as [row][col][channel]. @@ -1310,10 +1310,10 @@ class Mat extends CvStruct { /// final list = mat.toList3D(); /// print(list); // [[[0, 1, 2], [3, 4, 5], [6, 7, 8]]] /// ``` - List>> toList3D() { + List>> toList3D() { assert(channels >= 2, "toList3D() only for channels >= 2, but this.channels=$channels"); return List.generate( - rows, (row) => List.generate(cols, (col) => at(row, col).val as List

)); + rows, (row) => List.generate(cols, (col) => at(row, col).val)); } /// Get the data pointer of the Mat, this getter will reture a view of native diff --git a/test/core/core_test.dart b/test/core/core_test.dart index 2bb20b9a..17af5c33 100644 --- a/test/core/core_test.dart +++ b/test/core/core_test.dart @@ -339,7 +339,7 @@ void main() async { for (int channel in [1, 2, 3, 4]) { for (var depth in depthSrc) { final srcType = cv.MatType.makeType(depth, channel); - final src = cv.Mat.zeros(3, 3, srcType); + final src = cv.Mat.randu(3, 3, srcType, low: cv.Scalar.all(0), high: cv.Scalar.all(255)); final lutSize = switch (depth) { cv.MatType.CV_8U || cv.MatType.CV_8S => 256, cv.MatType.CV_16U || cv.MatType.CV_16S => 65536, @@ -347,13 +347,30 @@ void main() async { }; for (var lutDepth in depthLut) { final lutType = cv.MatType.makeType(lutDepth, channel); - final lut = cv.Mat.fromScalar(1, lutSize, lutType, cv.Scalar(255, 241, 21, 0)); - testOneLUT(src, lut); + // 0-1: 65536-1-0 2-3: 65536-1-1 3-4: 65536-1-2 + final lutData = switch (lutDepth) { + cv.MatType.CV_32F || cv.MatType.CV_64F => List.generate( + lutSize * lutType.channels, (i) => (lutSize - (i ~/ channel) - 1).toDouble()), + _ => List.generate(lutSize * lutType.channels, (i) => lutSize - (i ~/ channel) - 1), + }; + final lutInverse = cv.Mat.fromList(1, lutSize, lutType, lutData); + testOneLUT(src, lutInverse); } } } }); + test('cv.LUT 1', () { + final mat = cv.imread("test/images/lenna.png", flags: cv.IMREAD_COLOR); + final src = mat.convertTo(cv.MatType.CV_16UC3, alpha: 65536.0/255.0); + final lutData = List.generate(65536 * 3, (i) => 65536 - (i ~/ 3) - 1); + final lut = cv.Mat.fromList(1, 65536, cv.MatType.CV_16UC3, lutData); + final dst = cv.LUT(src, lut); + expect(dst.isEmpty, equals(false)); + expect(dst.shape, src.shape); + // cv.imwrite("lut.png", dst.convertTo(cv.MatType.CV_8UC3, alpha: 255.0/65536.0)); + }); + test('cv.magnitude', () { final src1 = cv.Mat.randu(4, 4, cv.MatType.CV_32FC1); final src2 = cv.Mat.randu(4, 4, cv.MatType.CV_32FC1); diff --git a/test/core/mat_test.dart b/test/core/mat_test.dart index b6a605a9..86e5ffba 100644 --- a/test/core/mat_test.dart +++ b/test/core/mat_test.dart @@ -32,7 +32,7 @@ void main() async { mat3.rows, (row) => List.generate( mat3.cols, (col) => List.generate(mat3.channels, (c) => row == col && c == 0 ? 1 : 0))); - expect(mat3.toList3D(), expected3); + expect(mat3.toList3D(), expected3); final mat4 = cv.Mat.ones(100, 100, cv.MatType.CV_8UC3); expect((mat4.width, mat4.height, mat4.channels), (100, 100, 3));