From 19a880bb918122168f656804d43993b81e7b18ae Mon Sep 17 00:00:00 2001 From: Giles Payne Date: Tue, 5 Oct 2021 20:16:06 +0900 Subject: [PATCH] Simple matrix multiplication for Mat in iOS/Android --- modules/core/misc/java/src/java/core+Mat.java | 22 ++++++++++++++-- .../core/misc/java/src/java/core+MatMatMul.kt | 3 +++ modules/core/misc/java/test/MatTest.java | 10 +++++++ modules/core/misc/objc/common/Mat.h | 10 +++++++ modules/core/misc/objc/common/Mat.mm | 5 ++++ modules/core/misc/objc/common/MatExt.swift | 6 +++++ modules/core/misc/objc/test/MatTest.swift | 10 +++++++ modules/java/generator/src/cpp/Mat.cpp | 26 +++++++++++++++++++ 8 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 modules/core/misc/java/src/java/core+MatMatMul.kt diff --git a/modules/core/misc/java/src/java/core+Mat.java b/modules/core/misc/java/src/java/core+Mat.java index 5fcc727738..2d9ee314a3 100644 --- a/modules/core/misc/java/src/java/core+Mat.java +++ b/modules/core/misc/java/src/java/core+Mat.java @@ -466,16 +466,32 @@ public class Mat { // C++: Mat Mat::mul(Mat m, double scale = 1) // - // javadoc: Mat::mul(m, scale) + /** + * Element-wise multiplication with scale factor + * @param m operand with with which to perform element-wise multiplication + * @param scale scale factor + */ public Mat mul(Mat m, double scale) { return new Mat(n_mul(nativeObj, m.nativeObj, scale)); } - // javadoc: Mat::mul(m) + /** + * Element-wise multiplication + * @param m operand with with which to perform element-wise multiplication + */ public Mat mul(Mat m) { return new Mat(n_mul(nativeObj, m.nativeObj)); } + /** + * Matrix multiplication + * @param m operand with with which to perform matrix multiplication + * @see Core#gemm(Mat, Mat, double, Mat, double, Mat, int) + */ + public Mat matMul(Mat m) { + return new Mat(n_matMul(nativeObj, m.nativeObj)); + } + // // C++: static Mat Mat::ones(int rows, int cols, int type) // @@ -1732,6 +1748,8 @@ public class Mat { private static native long n_mul(long nativeObj, long m_nativeObj); + private static native long n_matMul(long nativeObj, long m_nativeObj); + // C++: static Mat Mat::ones(int rows, int cols, int type) private static native long n_ones(int rows, int cols, int type); diff --git a/modules/core/misc/java/src/java/core+MatMatMul.kt b/modules/core/misc/java/src/java/core+MatMatMul.kt new file mode 100644 index 0000000000..3dcb6bde79 --- /dev/null +++ b/modules/core/misc/java/src/java/core+MatMatMul.kt @@ -0,0 +1,3 @@ +package org.opencv.core + +operator fun Mat.times(other: Mat): Mat = this.matMul(other) diff --git a/modules/core/misc/java/test/MatTest.java b/modules/core/misc/java/test/MatTest.java index 3075dba16b..323440b2eb 100644 --- a/modules/core/misc/java/test/MatTest.java +++ b/modules/core/misc/java/test/MatTest.java @@ -686,6 +686,16 @@ public class MatTest extends OpenCVTestCase { assertMatEqual(truth, dst, EPS); } + public void testMatMulMat() { + Mat m1 = new Mat(2, 2, CvType.CV_32F, new Scalar(2)); + Mat m2 = new Mat(2, 2, CvType.CV_32F, new Scalar(3)); + + dst = m1.matMul(m2); + + truth = new Mat(2, 2, CvType.CV_32F, new Scalar(12)); + assertMatEqual(truth, dst, EPS); + } + public void testOnesIntIntInt() { dst = Mat.ones(matSize, matSize, CvType.CV_32F); diff --git a/modules/core/misc/objc/common/Mat.h b/modules/core/misc/objc/common/Mat.h index fd1dce27ba..b5e868306c 100644 --- a/modules/core/misc/objc/common/Mat.h +++ b/modules/core/misc/objc/common/Mat.h @@ -114,7 +114,17 @@ CV_EXPORTS @interface Mat : NSObject - (BOOL)isSubmatrix; - (void)locateROI:(Size2i*)wholeSize ofs:(Point2i*)offset NS_SWIFT_NAME(locateROI(wholeSize:offset:)); - (Mat*)mul:(Mat*)mat scale:(double)scale; +/** + Performs element-wise multiplication + @param mat operand with with which to perform element-wise multiplication +*/ - (Mat*)mul:(Mat*)mat; +/** + Performs matrix multiplication + @param mat operand with with which to perform matrix multiplication + @see `Core.gemm(...)` +*/ +- (Mat*)matMul:(Mat*)mat; + (Mat*)ones:(int)rows cols:(int)cols type:(int)type NS_SWIFT_NAME(ones(rows:cols:type:)); + (Mat*)ones:(Size2i*)size type:(int)type NS_SWIFT_NAME(ones(size:type:)); + (Mat*)onesEx:(NSArray*)sizes type:(int)type NS_SWIFT_NAME(ones(sizes:type:)); diff --git a/modules/core/misc/objc/common/Mat.mm b/modules/core/misc/objc/common/Mat.mm index dc2316c87b..ab5e1de6f9 100644 --- a/modules/core/misc/objc/common/Mat.mm +++ b/modules/core/misc/objc/common/Mat.mm @@ -372,6 +372,11 @@ static bool updateIdx(cv::Mat* mat, std::vector& indices, size_t inc) { return [[Mat alloc] initWithNativeMat:new cv::Mat(_nativePtr->mul(*(cv::Mat*)mat.nativePtr))]; } +- (Mat*)matMul:(Mat*)mat { + cv::Mat temp = self.nativeRef * mat.nativeRef; + return [Mat fromNative:temp]; +} + + (Mat*)ones:(int)rows cols:(int)cols type:(int)type { return [[Mat alloc] initWithNativeMat:new cv::Mat(cv::Mat::ones(rows, cols, type))]; } diff --git a/modules/core/misc/objc/common/MatExt.swift b/modules/core/misc/objc/common/MatExt.swift index a6ba548599..f0f4446682 100644 --- a/modules/core/misc/objc/common/MatExt.swift +++ b/modules/core/misc/objc/common/MatExt.swift @@ -715,3 +715,9 @@ public extension Mat { return MatAt(mat: self, indices: indices) } } + +public extension Mat { + static func *(lhs:Mat, rhs: Mat) -> Mat { + return lhs.matMul(rhs) + } +} diff --git a/modules/core/misc/objc/test/MatTest.swift b/modules/core/misc/objc/test/MatTest.swift index 2dcfedf41f..87f99fb84a 100644 --- a/modules/core/misc/objc/test/MatTest.swift +++ b/modules/core/misc/objc/test/MatTest.swift @@ -683,6 +683,16 @@ class MatTests: OpenCVTestCase { try assertMatEqual(truth!, dst, OpenCVTestCase.EPS) } + func testMatMulMat() throws { + let m1 = Mat(rows: 2, cols: 2, type: CvType.CV_32F, scalar: Scalar(2)) + let m2 = Mat(rows: 2, cols: 2, type: CvType.CV_32F, scalar: Scalar(3)) + + dst = m1.matMul(m2) + + truth = Mat(rows: 2, cols: 2, type: CvType.CV_32F, scalar: Scalar(12)) + try assertMatEqual(truth!, dst, OpenCVTestCase.EPS) + } + func testOnesIntIntInt() throws { dst = Mat.ones(rows: OpenCVTestCase.matSize, cols: OpenCVTestCase.matSize, type: CvType.CV_32F) diff --git a/modules/java/generator/src/cpp/Mat.cpp b/modules/java/generator/src/cpp/Mat.cpp index d59fe4a506..f43a4c6ed5 100644 --- a/modules/java/generator/src/cpp/Mat.cpp +++ b/modules/java/generator/src/cpp/Mat.cpp @@ -1372,6 +1372,32 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1mul__JJ } +// +// Mat Mat Mat::matMul(Mat m) +// + +JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1matMul__JJ + (JNIEnv* env, jclass, jlong self, jlong m_nativeObj); + +JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1matMul__JJ + (JNIEnv* env, jclass, jlong self, jlong m_nativeObj) +{ + static const char method_name[] = "Mat::n_1matMul__JJ()"; + try { + LOGD("%s", method_name); + Mat* me = (Mat*) self; //TODO: check for NULL + Mat& m = *((Mat*)m_nativeObj); + Mat _retval_ = (*me) * m; + return (jlong) new Mat(_retval_); + } catch(const std::exception &e) { + throwJavaException(env, &e, method_name); + } catch (...) { + throwJavaException(env, 0, method_name); + } + + return 0; +} + // // static Mat Mat::ones(int rows, int cols, int type)