diff --git a/modules/js/src/core_bindings.cpp b/modules/js/src/core_bindings.cpp index ecb8579504..1e52541dde 100644 --- a/modules/js/src/core_bindings.cpp +++ b/modules/js/src/core_bindings.cpp @@ -285,6 +285,40 @@ namespace binding_utils cv::minEnclosingCircle(points, circle.center, circle.radius); return circle; } + + int floodFill_withRect_helper(cv::Mat& arg1, cv::Mat& arg2, Point arg3, Scalar arg4, emscripten::val arg5, Scalar arg6 = Scalar(), Scalar arg7 = Scalar(), int arg8 = 4) + { + cv::Rect rect; + + int rc = cv::floodFill(arg1, arg2, arg3, arg4, &rect, arg6, arg7, arg8); + + arg5.set("x", emscripten::val(rect.x)); + arg5.set("y", emscripten::val(rect.y)); + arg5.set("width", emscripten::val(rect.width)); + arg5.set("height", emscripten::val(rect.height)); + + return rc; + } + + int floodFill_wrapper(cv::Mat& arg1, cv::Mat& arg2, Point arg3, Scalar arg4, emscripten::val arg5, Scalar arg6, Scalar arg7, int arg8) { + return floodFill_withRect_helper(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } + + int floodFill_wrapper_1(cv::Mat& arg1, cv::Mat& arg2, Point arg3, Scalar arg4, emscripten::val arg5, Scalar arg6, Scalar arg7) { + return floodFill_withRect_helper(arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + + int floodFill_wrapper_2(cv::Mat& arg1, cv::Mat& arg2, Point arg3, Scalar arg4, emscripten::val arg5, Scalar arg6) { + return floodFill_withRect_helper(arg1, arg2, arg3, arg4, arg5, arg6); + } + + int floodFill_wrapper_3(cv::Mat& arg1, cv::Mat& arg2, Point arg3, Scalar arg4, emscripten::val arg5) { + return floodFill_withRect_helper(arg1, arg2, arg3, arg4, arg5); + } + + int floodFill_wrapper_4(cv::Mat& arg1, cv::Mat& arg2, Point arg3, Scalar arg4) { + return cv::floodFill(arg1, arg2, arg3, arg4); + } #endif #ifdef HAVE_OPENCV_VIDEO @@ -546,6 +580,16 @@ EMSCRIPTEN_BINDINGS(binding_utils) #ifdef HAVE_OPENCV_IMGPROC function("minEnclosingCircle", select_overload(&binding_utils::minEnclosingCircle)); + + function("floodFill", select_overload(&binding_utils::floodFill_wrapper)); + + function("floodFill", select_overload(&binding_utils::floodFill_wrapper_1)); + + function("floodFill", select_overload(&binding_utils::floodFill_wrapper_2)); + + function("floodFill", select_overload(&binding_utils::floodFill_wrapper_3)); + + function("floodFill", select_overload(&binding_utils::floodFill_wrapper_4)); #endif function("minMaxLoc", select_overload(&binding_utils::minMaxLoc)); diff --git a/modules/js/src/embindgen.py b/modules/js/src/embindgen.py index ec62bc86d0..9319e5f2a4 100644 --- a/modules/js/src/embindgen.py +++ b/modules/js/src/embindgen.py @@ -84,7 +84,7 @@ ignore_list = ['locate', #int& 'minEnclosingCircle', #float& 'checkRange', 'minMaxLoc', #double* - 'floodFill', + 'floodFill', # special case, implemented in core_bindings.cpp 'phaseCorrelate', 'randShuffle', 'calibrationMatrixValues', #double& diff --git a/modules/js/test/test_imgproc.js b/modules/js/test/test_imgproc.js index b2180c3b87..15bc56c65c 100644 --- a/modules/js/test/test_imgproc.js +++ b/modules/js/test/test_imgproc.js @@ -147,6 +147,60 @@ QUnit.test('test_imgProc', function(assert) { dest.delete(); source.delete(); } + + // floodFill + { + let center = new cv.Point(5, 5); + let rect = new cv.Rect(0, 0, 0, 0); + let img = new cv.Mat.zeros(10, 10, cv.CV_8UC1); + let color = new cv.Scalar (255); + cv.circle(img, center, 3, color, 1); + + let edge = new cv.Mat(); + cv.Canny(img, edge, 100, 255); + cv.copyMakeBorder(edge, edge, 1, 1, 1, 1, cv.BORDER_REPLICATE); + + let expected_img_data = new Uint8Array([ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, + 0, 0, 0, 255, 255, 255, 255, 255, 0, 0, + 0, 0, 0, 255, 0, 255, 0, 255, 0, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 255, 0, + 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, + 0, 0, 0, 255, 255, 0, 255, 255, 0, 0, + 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + + let img_elem = 10*10*1; + let expected_img_data_ptr = cv._malloc(img_elem); + let expected_img_data_heap = new Uint8Array(cv.HEAPU8.buffer, + expected_img_data_ptr, + img_elem); + expected_img_data_heap.set(new Uint8Array(expected_img_data.buffer)); + + let expected_img = new cv.Mat( 10, 10, cv.CV_8UC1, expected_img_data_ptr, 0); + + let expected_rect = new cv.Rect(3,3,3,3); + + let compare_result = new cv.Mat(10, 10, cv.CV_8UC1); + + cv.floodFill(img, edge, center, color, rect); + + cv.compare (img, expected_img, compare_result, cv.CMP_EQ); + + // expect every pixels are the same. + assert.equal (cv.countNonZero(compare_result), img.total()); + assert.equal (rect.x, expected_rect.x); + assert.equal (rect.y, expected_rect.y); + assert.equal (rect.width, expected_rect.width); + assert.equal (rect.height, expected_rect.height); + + img.delete(); + edge.delete(); + expected_img.delete(); + compare_result.delete(); + } }); QUnit.test('test_segmentation', function(assert) {