diff --git a/modules/calib3d/CMakeLists.txt b/modules/calib3d/CMakeLists.txt
index cba3f811b5..a38fdf18d8 100644
--- a/modules/calib3d/CMakeLists.txt
+++ b/modules/calib3d/CMakeLists.txt
@@ -3,4 +3,6 @@ set(debug_modules "")
if(DEBUG_opencv_calib3d)
list(APPEND debug_modules opencv_highgui)
endif()
-ocv_define_module(calib3d opencv_imgproc opencv_features2d ${debug_modules} WRAP java python)
+ocv_define_module(calib3d opencv_imgproc opencv_features2d ${debug_modules}
+ WRAP java python js
+)
diff --git a/modules/js/src/embindgen.py b/modules/js/src/embindgen.py
index 9319e5f2a4..d3ddb138fb 100644
--- a/modules/js/src/embindgen.py
+++ b/modules/js/src/embindgen.py
@@ -142,6 +142,8 @@ features2d = {'Feature2D': ['detect', 'compute', 'detectAndCompute', 'descriptor
'BFMatcher': ['isMaskSupported', 'create'],
'': ['drawKeypoints', 'drawMatches']}
+calib3d = {'': ['findHomography']}
+
def makeWhiteList(module_list):
wl = {}
for m in module_list:
@@ -152,7 +154,7 @@ def makeWhiteList(module_list):
wl[k] = m[k]
return wl
-white_list = makeWhiteList([core, imgproc, objdetect, video, dnn, features2d])
+white_list = makeWhiteList([core, imgproc, objdetect, video, dnn, features2d, calib3d])
# Features to be exported
export_enums = False
diff --git a/modules/js/test/test_calib3d.js b/modules/js/test/test_calib3d.js
new file mode 100644
index 0000000000..1c8e61086e
--- /dev/null
+++ b/modules/js/test/test_calib3d.js
@@ -0,0 +1,43 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+
+if (typeof module !== 'undefined' && module.exports) {
+ // The envrionment is Node.js
+ var cv = require('./opencv.js'); // eslint-disable-line no-var
+}
+
+QUnit.module('Camera Calibration and 3D Reconstruction', {});
+
+QUnit.test('constants', function(assert) {
+ assert.strictEqual(typeof cv.LMEDS, 'number');
+ assert.strictEqual(typeof cv.RANSAC, 'number');
+ assert.strictEqual(typeof cv.RHO, 'number');
+});
+
+QUnit.test('findHomography', function(assert) {
+ let srcPoints = cv.matFromArray(4, 1, cv.CV_32FC2, [
+ 56,
+ 65,
+ 368,
+ 52,
+ 28,
+ 387,
+ 389,
+ 390,
+ ]);
+ let dstPoints = cv.matFromArray(4, 1, cv.CV_32FC2, [
+ 0,
+ 0,
+ 300,
+ 0,
+ 0,
+ 300,
+ 300,
+ 300,
+ ]);
+
+ const mat = cv.findHomography(srcPoints, dstPoints);
+
+ assert.ok(mat instanceof cv.Mat);
+});
diff --git a/modules/js/test/tests.html b/modules/js/test/tests.html
index c476dbb3b2..f2f6ad66c7 100644
--- a/modules/js/test/tests.html
+++ b/modules/js/test/tests.html
@@ -29,6 +29,7 @@
+