Skip to content

Commit

Permalink
add cv.invertAffineTransform, remove net.forwardAsync, add ios versio…
Browse files Browse the repository at this point in the history
…n info
  • Loading branch information
rainyl committed Mar 21, 2024
1 parent 8d989c0 commit 2362331
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 48 deletions.
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ if(IOS)
set_target_properties(${library_name} PROPERTIES
FRAMEWORK TRUE
FRAMEWORK_VERSION CXX
MACOSX_FRAMEWORK_IDENTIFIER dev.rainyl.opencv_dart
MACOSX_FRAMEWORK_IDENTIFIER dev.rainyl.opencvDart
MACOSX_FRAMEWORK_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_FRAMEWORK_SHORT_VERSION_STRING ${PROJECT_VERSION}
)
endif(IOS)

Expand Down
41 changes: 20 additions & 21 deletions lib/src/core/mat.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ final _bindings = cvg.CvNative(loadNativeLibrary());

class Mat with EquatableMixin implements ffi.Finalizable {
Mat._(this.ptr) {
_finalizer.attach(this, ptr);
finalizer.attach(this, ptr);
}
factory Mat.fromCMat(cvg.Mat mat) => Mat._(mat);

Expand All @@ -25,8 +25,8 @@ class Mat with EquatableMixin implements ffi.Finalizable {
}

factory Mat.fromScalar(Scalar s, MatType type, {int rows = 1, int cols = 1}) {
final _ptr = _bindings.Mat_NewWithSizeFromScalar(s.ref, rows, cols, type.toInt32());
return Mat._(_ptr);
final ptr = _bindings.Mat_NewWithSizeFromScalar(s.ref, rows, cols, type.toInt32());
return Mat._(ptr);
}

factory Mat.create({
Expand All @@ -39,24 +39,24 @@ class Mat with EquatableMixin implements ffi.Finalizable {
}) {
type = type ?? MatType.CV_8UC3;
final scalar = Scalar(b.toDouble(), g.toDouble(), r.toDouble(), 0);
final _ptr = _bindings.Mat_NewWithSizeFromScalar(scalar.ref, rows, cols, type.toInt32());
final ptr = _bindings.Mat_NewWithSizeFromScalar(scalar.ref, rows, cols, type.toInt32());

return Mat._(_ptr);
return Mat._(ptr);
}

factory Mat.eye(int rows, int cols, MatType type) {
final _ptr = _bindings.Eye(rows, cols, type.toInt32());
return Mat._(_ptr);
final ptr = _bindings.Eye(rows, cols, type.toInt32());
return Mat._(ptr);
}

factory Mat.zeros(int rows, int cols, MatType type) {
final _ptr = _bindings.Zeros(rows, cols, type.toInt32());
return Mat._(_ptr);
final ptr = _bindings.Zeros(rows, cols, type.toInt32());
return Mat._(ptr);
}

factory Mat.ones(int rows, int cols, MatType type) {
final _ptr = _bindings.Ones(rows, cols, type.toInt32());
return Mat._(_ptr);
final ptr = _bindings.Ones(rows, cols, type.toInt32());
return Mat._(ptr);
}

factory Mat.randn(int rows, int cols, MatType type, {Scalar? mean, Scalar? std}) {
Expand All @@ -83,11 +83,11 @@ class Mat with EquatableMixin implements ffi.Finalizable {
int prows,
int pcols,
) {
final _ptr = _bindings.Mat_FromPtr(m, rows, cols, type, prows, pcols);
return Mat._(_ptr);
final ptr = _bindings.Mat_FromPtr(m, rows, cols, type, prows, pcols);
return Mat._(ptr);
}

static final _finalizer = ffi.NativeFinalizer(_bindings.addresses.Mat_Close);
static final finalizer = ffi.NativeFinalizer(_bindings.addresses.Mat_Close);
cvg.Mat ptr;
MatType get _type => MatType(_bindings.Mat_Type(ptr));
int get width => _bindings.Mat_Cols(ptr);
Expand Down Expand Up @@ -660,17 +660,16 @@ class Mat with EquatableMixin implements ffi.Finalizable {
}

Uint8List get data {
final _data = _bindings.Mat_DataPtr(ptr);
return _data.data.cast<ffi.Uint8>().asTypedList(_data.length);
final data = _bindings.Mat_DataPtr(ptr);
return data.data.cast<ffi.Uint8>().asTypedList(data.length);
}

MatType get type => _type;

// @override
// Future<Null> onDispose() {
// _bindings.Mat_Close(_ptr);
// return super.onDispose();
// }
@override
String toString() {
return "Mat(address=${ptr.address}, type=$type rows=$rows, cols=$cols, channels=$channels)";
}

@override
List<Object?> get props => [ptr.address];
Expand Down
2 changes: 2 additions & 0 deletions lib/src/core/scalar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,6 @@ class Scalar with EquatableMixin implements ffi.Finalizable {
static final Scalar blue = Scalar.fromRgb(0, 0, 255);
static final Scalar black = Scalar.fromRgb(0, 0, 0);
static final Scalar white = Scalar.fromRgb(255, 255, 255);
static final Scalar zeros = Scalar.fromRgb(0, 0, 0);
static final Scalar max = Scalar(double.maxFinite, double.maxFinite, double.maxFinite, double.maxFinite);
}
22 changes: 11 additions & 11 deletions lib/src/dnn/dnn.dart
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ class Net implements ffi.Finalizable {
/// For further details, please see:
/// https://docs.opencv.org/4.x/db/d30/classcv_1_1dnn_1_1Net.html#a5e74adacffd6aa53d56046581de7fcbd
void setInput(InputArray blob, {String name = "", double scalefactor = 1.0, Scalar? mean}) {
mean ??= Scalar.default_();
// mean ??= Scalar.default_(); not supported yet
using((arena) {
final cname = name.toNativeUtf8(allocator: arena);
_bindings.Net_SetInput(ptr, blob.ptr, cname.cast());
Expand All @@ -233,18 +233,18 @@ class Net implements ffi.Finalizable {
);
}

/// OpenVINO not supported yet, this is not available
/// ForwardAsync runs forward pass to compute output of layer with name outputName.
///
/// For further details, please see:
/// https://docs.opencv.org/4.x/db/d30/classcv_1_1dnn_1_1Net.html#a814890154ea9e10b132fec00b6f6ba30
AsyncArray forwardAsync({String outputName = ""}) {
return using<AsyncArray>((arena) {
final cname = outputName.toNativeUtf8(allocator: arena);
return AsyncArray.fromPointer(
_bindings.Net_forwardAsync(ptr, cname.cast()),
);
});
}
// AsyncArray forwardAsync({String outputName = ""}) {
// return using<AsyncArray>((arena) {
// final cname = outputName.toNativeUtf8(allocator: arena);
// final p = _bindings.Net_forwardAsync(ptr, cname.cast());
// return AsyncArray.fromPointer(p);
// });
// }

/// ForwardLayers forward pass to compute outputs of layers listed in outBlobNames.
///
Expand Down Expand Up @@ -352,7 +352,7 @@ Mat blobFromImage(
}) {
return using<Mat>((arena) {
size ??= (0, 0);
mean ??= Scalar.default_();
mean ??= Scalar.zeros;
final _ptr = _bindings.Net_BlobFromImage(
image.ptr,
scalefactor,
Expand Down Expand Up @@ -384,7 +384,7 @@ Mat blobFromImages(
return using<Mat>((arena) {
blob ??= Mat.empty();
size ??= (0, 0);
mean ??= Scalar.default_();
mean ??= Scalar.zeros;
_bindings.Net_BlobFromImages(
images.toMats(arena).ref,
blob!.ptr,
Expand Down
12 changes: 12 additions & 0 deletions lib/src/imgproc/imgproc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1570,6 +1570,18 @@ double matchShapes(
return r;
}

/// Inverts an affine transformation.
/// The function computes an inverse affine transformation represented by 2×3 matrix M:
/// The result is also a 2×3 matrix of the same type as M.
///
/// For further details, please see:
/// https://docs.opencv.org/4.x/da/d54/group__imgproc__transform.html#ga57d3505a878a7e1a636645727ca08f51
Mat invertAffineTransform(InputArray M, {OutputArray? iM}) {
iM ??= Mat.empty();
_bindings.InvertAffineTransform(M.ptr, iM.ptr);
return iM;
}

/// NewCLAHE returns a new CLAHE algorithm
///
/// For further details, please see:
Expand Down
29 changes: 14 additions & 15 deletions test/dnn_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ bool checkCaffeNet(cv.Net net) {
final img = cv.imread("test/images/space_shuttle.jpg", flags: cv.IMREAD_COLOR);
expect(img.isEmpty, false);

final blob = cv.blobFromImage(img,
scalefactor: 1.0, size: (224, 224), mean: cv.Scalar.all(0), swapRB: false, crop: false);
final blob =
cv.blobFromImage(img, scalefactor: 1.0, size: (224, 224), mean: cv.Scalar.all(0), swapRB: false, crop: false);
expect(blob.isEmpty, false);

net.setInput(blob, name: "data");
Expand Down Expand Up @@ -51,8 +51,8 @@ bool checkTensorflow(cv.Net net) {
final img = cv.imread("test/images/space_shuttle.jpg", flags: cv.IMREAD_COLOR);
expect(img.isEmpty, false);

final blob = cv.blobFromImage(img,
scalefactor: 1.0, size: (224, 224), mean: cv.Scalar.all(0), swapRB: true, crop: false);
final blob =
cv.blobFromImage(img, scalefactor: 1.0, size: (224, 224), mean: cv.Scalar.all(0), swapRB: true, crop: false);
expect(blob.isEmpty, false);

net.setInput(blob, name: "input");
Expand All @@ -76,8 +76,8 @@ bool checkOnnx(cv.Net net) {
final img = cv.imread("test/images/space_shuttle.jpg", flags: cv.IMREAD_COLOR);
expect(img.isEmpty, false);

final blob = cv.blobFromImage(img,
scalefactor: 1.0, size: (224, 224), mean: cv.Scalar.all(0), swapRB: true, crop: false);
final blob =
cv.blobFromImage(img, scalefactor: 1.0, size: (224, 224), mean: cv.Scalar.all(0), swapRB: true, crop: false);
expect(blob.isEmpty, false);

net.setInput(blob, name: "data_0");
Expand All @@ -90,9 +90,9 @@ bool checkOnnx(cv.Net net) {
expect((minLoc.x, minLoc.y), (955, 0));
expect((maxLoc.x, maxLoc.y), (812, 0));

final probAsync = net.forwardAsync(outputName: "prob_1");
final probMatAsync = probAsync.get();
expect(probMatAsync.isEmpty, false);
// final probAsync = net.forwardAsync(outputName: "prob_1");
// final probMatAsync = probAsync.get();
// expect(probMatAsync.isEmpty, false);

final perf = net.getPerfProfile();
expect(perf, greaterThan(0));
Expand All @@ -104,8 +104,8 @@ bool checkTflite(cv.Net net) {
final img = cv.imread("test/images/space_shuttle.jpg", flags: cv.IMREAD_COLOR);
expect(img.isEmpty, false);

final blob = cv.blobFromImage(img,
scalefactor: 1.0, size: (224, 224), mean: cv.Scalar.all(0), swapRB: true, crop: false);
final blob =
cv.blobFromImage(img, scalefactor: 1.0, size: (224, 224), mean: cv.Scalar.all(0), swapRB: true, crop: false);
expect(blob.isEmpty, false);

// TODO: TFLite support of opencv is not complete
Expand All @@ -121,8 +121,8 @@ void main() async {
final net = cv.Net.empty();
expect(net.isEmpty, true);

final model = cv.Net.fromFile("test/models/bvlc_googlenet.caffemodel",
config: "test/models/bvlc_googlenet.prototxt");
final model =
cv.Net.fromFile("test/models/bvlc_googlenet.caffemodel", config: "test/models/bvlc_googlenet.prototxt");
checkCaffeNet(model);
});

Expand All @@ -134,8 +134,7 @@ void main() async {
});

test('cv.Net.fromCaffe', () {
final model =
cv.Net.fromCaffe("test/models/bvlc_googlenet.prototxt", "test/models/bvlc_googlenet.caffemodel");
final model = cv.Net.fromCaffe("test/models/bvlc_googlenet.prototxt", "test/models/bvlc_googlenet.caffemodel");
checkCaffeNet(model);
});

Expand Down
18 changes: 18 additions & 0 deletions test/imgproc_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -882,6 +882,24 @@ void main() async {
expect(2.0 <= similarity && similarity <= 3.0, true);
});

test('cv.invertAffineTransform', () {
final src = [
cv.Point(0, 0),
cv.Point(10, 5),
cv.Point(10, 10),
];

final dst = [
cv.Point(0, 0),
cv.Point(10, 0),
cv.Point(10, 10),
];
final m = cv.getAffineTransform(src, dst);
final inv = cv.invertAffineTransform(m);
expect(inv.isEmpty, false);
expect((inv.rows, inv.cols), (2, 3));
});

// accumulate
test('cv.accumulate', () {
final src = cv.imread("test/images/lenna.png", flags: cv.IMREAD_COLOR);
Expand Down

0 comments on commit 2362331

Please sign in to comment.