diff --git a/modules/calib3d/misc/js/gen_dict.json b/modules/calib3d/misc/js/gen_dict.json new file mode 100644 index 0000000000..407ddf1e48 --- /dev/null +++ b/modules/calib3d/misc/js/gen_dict.json @@ -0,0 +1,21 @@ +{ + "whitelist": + { + "": [ + "findHomography", + "calibrateCameraExtended", + "drawFrameAxes", + "estimateAffine2D", + "getDefaultNewCameraMatrix", + "initUndistortRectifyMap", + "Rodrigues", + "solvePnP", + "solvePnPRansac", + "solvePnPRefineLM", + "projectPoints", + "undistort", + "fisheye_initUndistortRectifyMap", + "fisheye_projectPoints" + ] + } +} diff --git a/modules/core/misc/js/gen_dict.json b/modules/core/misc/js/gen_dict.json new file mode 100644 index 0000000000..f1e892d86b --- /dev/null +++ b/modules/core/misc/js/gen_dict.json @@ -0,0 +1,15 @@ +{ + "whitelist": + { + "": [ + "absdiff", "add", "addWeighted", "bitwise_and", "bitwise_not", "bitwise_or", "bitwise_xor", "cartToPolar", + "compare", "convertScaleAbs", "copyMakeBorder", "countNonZero", "determinant", "dft", "divide", "eigen", + "exp", "flip", "getOptimalDFTSize","gemm", "hconcat", "inRange", "invert", "kmeans", "log", "magnitude", + "max", "mean", "meanStdDev", "merge", "min", "minMaxLoc", "mixChannels", "multiply", "norm", "normalize", + "perspectiveTransform", "polarToCart", "pow", "randn", "randu", "reduce", "repeat", "rotate", "setIdentity", "setRNGSeed", + "solve", "solvePoly", "split", "sqrt", "subtract", "trace", "transform", "transpose", "vconcat", + "setLogLevel", "getLogLevel", "LUT" + ], + "Algorithm": [] + } +} diff --git a/modules/dnn/misc/js/gen_dict.json b/modules/dnn/misc/js/gen_dict.json new file mode 100644 index 0000000000..4b83a0e102 --- /dev/null +++ b/modules/dnn/misc/js/gen_dict.json @@ -0,0 +1,12 @@ +{ + "whitelist": + { + "dnn_Net": ["setInput", "forward", "setPreferableBackend","getUnconnectedOutLayersNames"], + "": ["readNetFromCaffe", "readNetFromTensorflow", "readNetFromTorch", "readNetFromDarknet", + "readNetFromONNX", "readNetFromTFLite", "readNet", "blobFromImage"] + }, + "namespace_prefix_override": + { + "dnn": "" + } +} diff --git a/modules/features2d/misc/js/gen_dict.json b/modules/features2d/misc/js/gen_dict.json new file mode 100644 index 0000000000..6d79e42ac8 --- /dev/null +++ b/modules/features2d/misc/js/gen_dict.json @@ -0,0 +1,19 @@ +{ + "whitelist": + { + "Feature2D": ["detect", "compute", "detectAndCompute", "descriptorSize", "descriptorType", "defaultNorm", "empty", "getDefaultName"], + "BRISK": ["create", "getDefaultName"], + "ORB": ["create", "setMaxFeatures", "setScaleFactor", "setNLevels", "setEdgeThreshold", "setFastThreshold", "setFirstLevel", "setWTA_K", "setScoreType", "setPatchSize", "getFastThreshold", "getDefaultName"], + "MSER": ["create", "detectRegions", "setDelta", "getDelta", "setMinArea", "getMinArea", "setMaxArea", "getMaxArea", "setPass2Only", "getPass2Only", "getDefaultName"], + "FastFeatureDetector": ["create", "setThreshold", "getThreshold", "setNonmaxSuppression", "getNonmaxSuppression", "setType", "getType", "getDefaultName"], + "AgastFeatureDetector": ["create", "setThreshold", "getThreshold", "setNonmaxSuppression", "getNonmaxSuppression", "setType", "getType", "getDefaultName"], + "GFTTDetector": ["create", "setMaxFeatures", "getMaxFeatures", "setQualityLevel", "getQualityLevel", "setMinDistance", "getMinDistance", "setBlockSize", "getBlockSize", "setHarrisDetector", "getHarrisDetector", "setK", "getK", "getDefaultName"], + "SimpleBlobDetector": ["create", "setParams", "getParams", "getDefaultName"], + "SimpleBlobDetector_Params": [], + "KAZE": ["create", "setExtended", "getExtended", "setUpright", "getUpright", "setThreshold", "getThreshold", "setNOctaves", "getNOctaves", "setNOctaveLayers", "getNOctaveLayers", "setDiffusivity", "getDiffusivity", "getDefaultName"], + "AKAZE": ["create", "setDescriptorType", "getDescriptorType", "setDescriptorSize", "getDescriptorSize", "setDescriptorChannels", "getDescriptorChannels", "setThreshold", "getThreshold", "setNOctaves", "getNOctaves", "setNOctaveLayers", "getNOctaveLayers", "setDiffusivity", "getDiffusivity", "getDefaultName"], + "DescriptorMatcher": ["add", "clear", "empty", "isMaskSupported", "train", "match", "knnMatch", "radiusMatch", "clone", "create"], + "BFMatcher": ["isMaskSupported", "create"], + "": ["drawKeypoints", "drawMatches", "drawMatchesKnn"] + } +} diff --git a/modules/imgproc/misc/js/gen_dict.json b/modules/imgproc/misc/js/gen_dict.json new file mode 100644 index 0000000000..7b8c959fdd --- /dev/null +++ b/modules/imgproc/misc/js/gen_dict.json @@ -0,0 +1,95 @@ +{ + "whitelist": + { + "": [ + "Canny", + "GaussianBlur", + "Laplacian", + "HoughLines", + "HoughLinesP", + "HoughCircles", + "Scharr", + "Sobel", + "adaptiveThreshold", + "approxPolyDP", + "arcLength", + "bilateralFilter", + "blur", + "boundingRect", + "boxFilter", + "calcBackProject", + "calcHist", + "circle", + "compareHist", + "connectedComponents", + "connectedComponentsWithStats", + "contourArea", + "convexHull", + "convexityDefects", + "cornerHarris", + "cornerMinEigenVal", + "createCLAHE", + "createLineSegmentDetector", + "cvtColor", + "demosaicing", + "dilate", + "distanceTransform", + "distanceTransformWithLabels", + "drawContours", + "ellipse", + "ellipse2Poly", + "equalizeHist", + "erode", + "filter2D", + "findContours", + "fitEllipse", + "fitLine", + "floodFill", + "getAffineTransform", + "getPerspectiveTransform", + "getRotationMatrix2D", + "getStructuringElement", + "goodFeaturesToTrack", + "grabCut", + "integral", + "integral2", + "isContourConvex", + "line", + "matchShapes", + "matchTemplate", + "medianBlur", + "minAreaRect", + "minEnclosingCircle", + "moments", + "morphologyEx", + "pointPolygonTest", + "putText", + "pyrDown", + "pyrUp", + "rectangle", + "remap", + "resize", + "sepFilter2D", + "threshold", + "warpAffine", + "warpPerspective", + "warpPolar", + "watershed", + "fillPoly", + "fillConvexPoly", + "polylines" + ], + "CLAHE": ["apply", "collectGarbage", "getClipLimit", "getTilesGridSize", "setClipLimit", "setTilesGridSize"], + "segmentation_IntelligentScissorsMB": [ + "IntelligentScissorsMB", + "setWeights", + "setGradientMagnitudeMaxLimit", + "setEdgeFeatureZeroCrossingParameters", + "setEdgeFeatureCannyParameters", + "applyImage", + "applyImageFeatures", + "buildMap", + "getContour" + ] + } +} diff --git a/modules/js/generator/CMakeLists.txt b/modules/js/generator/CMakeLists.txt index 3d66df154f..c66608e917 100644 --- a/modules/js/generator/CMakeLists.txt +++ b/modules/js/generator/CMakeLists.txt @@ -38,8 +38,21 @@ set(scripts_hdr_parser "${JS_SOURCE_DIR}/../python/src2/hdr_parser.py") if(DEFINED ENV{OPENCV_JS_WHITELIST}) set(OPENCV_JS_WHITELIST_FILE "$ENV{OPENCV_JS_WHITELIST}") + message(STATUS "Use white list from environment ${OPENCV_JS_WHITELIST_FILE}") else() - set(OPENCV_JS_WHITELIST_FILE "${OpenCV_SOURCE_DIR}/platforms/js/opencv_js.config.py") + #generate white list from modules//misc/js/whitelist.json + set(OPENCV_JS_WHITELIST_FILE "${CMAKE_CURRENT_BINARY_DIR}/whitelist.json") + foreach(m in ${OPENCV_JS_MODULES}) + set(js_whitelist "${OPENCV_MODULE_${m}_LOCATION}/misc/js/gen_dict.json") + if (EXISTS "${js_whitelist}") + file(READ "${js_whitelist}" whitelist_content) + list(APPEND OPENCV_JS_WHITELIST_CONTENT "\"${m}\": ${whitelist_content}") + endif() + endforeach(m) + string(REPLACE ";" ", \n" OPENCV_JS_WHITELIST_CONTENT_STRING "${OPENCV_JS_WHITELIST_CONTENT}") + set(OPENCV_JS_WHITELIST_CONTENT_STRING "{\n${OPENCV_JS_WHITELIST_CONTENT_STRING}}\n") + ocv_update_file("${OPENCV_JS_WHITELIST_FILE}" "${OPENCV_JS_WHITELIST_CONTENT_STRING}") + message(STATUS "Use autogenerated whitelist ${OPENCV_JS_WHITELIST_FILE}") endif() add_custom_command( diff --git a/modules/js/generator/embindgen.py b/modules/js/generator/embindgen.py index 005ac9f175..00d2406046 100644 --- a/modules/js/generator/embindgen.py +++ b/modules/js/generator/embindgen.py @@ -76,6 +76,7 @@ if sys.version_info[0] >= 3: else: from cStringIO import StringIO +import json func_table = {} @@ -103,11 +104,32 @@ def makeWhiteList(module_list): wl[k] = m[k] return wl +def makeWhiteListJson(module_list): + wl = {} + for n, gen_dict in module_list.items(): + m = gen_dict["whitelist"] + for k in m.keys(): + if k in wl: + wl[k] += m[k] + else: + wl[k] = m[k] + return wl + +def makeNamespacePrefixOverride(module_list): + wl = {} + for n, gen_dict in module_list.items(): + if "namespace_prefix_override" in gen_dict: + m = gen_dict["namespace_prefix_override"] + for k in m.keys(): + if k in wl: + wl[k] += m[k] + else: + wl[k] = m[k] + return wl + + white_list = None -namespace_prefix_override = { - 'dnn' : '', - 'aruco' : '', -} +namespace_prefix_override = None # Features to be exported export_enums = False @@ -834,6 +856,7 @@ class JSWrapperGenerator(object): if method.cname in ignore_list: continue if not method.name in white_list[method.class_name]: + #print('Not in whitelist: "{}"'.format(method.name)) continue if method.is_constructor: for variant in method.variants: @@ -938,9 +961,9 @@ if __name__ == "__main__": if len(sys.argv) < 5: print("Usage:\n", \ os.path.basename(sys.argv[0]), \ - " ") + " ") print("Current args are: ", ", ".join(["'"+a+"'" for a in sys.argv])) - exit(0) + exit(1) dstdir = "." hdr_parser_path = os.path.abspath(sys.argv[1]) @@ -953,8 +976,23 @@ if __name__ == "__main__": headers = open(sys.argv[3], 'r').read().split(';') coreBindings = sys.argv[4] whiteListFile = sys.argv[5] - exec(open(whiteListFile).read()) - assert(white_list) + + if whiteListFile.endswith(".json") or whiteListFile.endswith(".JSON"): + with open(whiteListFile) as f: + gen_dict = json.load(f) + f.close() + white_list = makeWhiteListJson(gen_dict) + namespace_prefix_override = makeNamespacePrefixOverride(gen_dict) + elif whiteListFile.endswith(".py") or whiteListFile.endswith(".PY"): + exec(open(whiteListFile).read()) + assert(white_list) + namespace_prefix_override = { + 'dnn' : '', + 'aruco' : '', + } + else: + print("Unexpected format of OpenCV config file", whiteListFile) + exit(1) generator = JSWrapperGenerator() generator.gen(bindingsCpp, headers, coreBindings) diff --git a/modules/objdetect/misc/js/gen_dict.json b/modules/objdetect/misc/js/gen_dict.json new file mode 100644 index 0000000000..dee3e4c93a --- /dev/null +++ b/modules/objdetect/misc/js/gen_dict.json @@ -0,0 +1,28 @@ +{ + "whitelist": + { + "": ["groupRectangles", "getPredefinedDictionary", "extendDictionary", "drawDetectedMarkers", "generateImageMarker", "drawDetectedCornersCharuco", "drawDetectedDiamonds"], + "HOGDescriptor": ["load", "HOGDescriptor", "getDefaultPeopleDetector", "getDaimlerPeopleDetector", "setSVMDetector", "detectMultiScale"], + "CascadeClassifier": ["load", "detectMultiScale2", "CascadeClassifier", "detectMultiScale3", "empty", "detectMultiScale"], + "GraphicalCodeDetector": ["decode", "detect", "detectAndDecode", "detectMulti", "decodeMulti", "detectAndDecodeMulti"], + "QRCodeDetector": ["QRCodeDetector", "decode", "detect", "detectAndDecode", "detectMulti", "decodeMulti", "detectAndDecodeMulti", "decodeCurved", "detectAndDecodeCurved", "setEpsX", "setEpsY"], + "aruco_PredefinedDictionaryType": [], + "aruco_Dictionary": ["Dictionary", "getDistanceToId", "generateImageMarker", "getByteListFromBits", "getBitsFromByteList"], + "aruco_Board": ["Board", "matchImagePoints", "generateImage"], + "aruco_GridBoard": ["GridBoard", "generateImage", "getGridSize", "getMarkerLength", "getMarkerSeparation", "matchImagePoints"], + "aruco_CharucoParameters": ["CharucoParameters"], + "aruco_CharucoBoard": ["CharucoBoard", "generateImage", "getChessboardCorners", "getNearestMarkerCorners", "checkCharucoCornersCollinear", "matchImagePoints", "getLegacyPattern", "setLegacyPattern"], + "aruco_DetectorParameters": ["DetectorParameters"], + "aruco_RefineParameters": ["RefineParameters"], + "aruco_ArucoDetector": ["ArucoDetector", "detectMarkers", "refineDetectedMarkers", "setDictionary", "setDetectorParameters", "setRefineParameters"], + "aruco_CharucoDetector": ["CharucoDetector", "setBoard", "setCharucoParameters", "setDetectorParameters", "setRefineParameters", "detectBoard", "detectDiamonds"], + "QRCodeDetectorAruco_Params": ["Params"], + "QRCodeDetectorAruco": ["QRCodeDetectorAruco", "decode", "detect", "detectAndDecode", "detectMulti", "decodeMulti", "detectAndDecodeMulti", "setDetectorParameters", "setArucoParameters"], + "barcode_BarcodeDetector": ["BarcodeDetector", "decode", "detect", "detectAndDecode", "detectMulti", "decodeMulti", "detectAndDecodeMulti", "decodeWithType", "detectAndDecodeWithType"], + "FaceDetectorYN": ["setInputSize", "getInputSize", "setScoreThreshold", "getScoreThreshold", "setNMSThreshold", "getNMSThreshold", "setTopK", "getTopK", "detect", "create"] + }, + "namespace_prefix_override": + { + "aruco": "" + } +} diff --git a/modules/photo/misc/js/gen_dict.json b/modules/photo/misc/js/gen_dict.json new file mode 100644 index 0000000000..d8a6db100a --- /dev/null +++ b/modules/photo/misc/js/gen_dict.json @@ -0,0 +1,25 @@ +{ + "whitelist": + { + "": [ + "createAlignMTB", "createCalibrateDebevec", "createCalibrateRobertson", + "createMergeDebevec", "createMergeMertens", "createMergeRobertson", + "createTonemapDrago", "createTonemapMantiuk", "createTonemapReinhard", "inpaint"], + "CalibrateCRF": ["process"], + "AlignMTB" : ["calculateShift", "shiftMat", "computeBitmaps", "getMaxBits", "setMaxBits", + "getExcludeRange", "setExcludeRange", "getCut", "setCut"], + "CalibrateDebevec" : ["getLambda", "setLambda", "getSamples", "setSamples", "getRandom", "setRandom"], + "CalibrateRobertson" : ["getMaxIter", "setMaxIter", "getThreshold", "setThreshold", "getRadiance"], + "MergeExposures" : ["process"], + "MergeDebevec" : ["process"], + "MergeMertens" : ["process", "getContrastWeight", "setContrastWeight", "getSaturationWeight", + "setSaturationWeight", "getExposureWeight", "setExposureWeight"], + "MergeRobertson" : ["process"], + "Tonemap" : ["process" , "getGamma", "setGamma"], + "TonemapDrago" : ["getSaturation", "setSaturation", "getBias", "setBias", + "getSigmaColor", "setSigmaColor", "getSigmaSpace","setSigmaSpace"], + "TonemapMantiuk" : ["getScale", "setScale", "getSaturation", "setSaturation"], + "TonemapReinhard" : ["getIntensity", "setIntensity", "getLightAdaptation", "setLightAdaptation", + "getColorAdaptation", "setColorAdaptation"] + } +} diff --git a/modules/video/misc/js/gen_dict.json b/modules/video/misc/js/gen_dict.json new file mode 100644 index 0000000000..f04aae740f --- /dev/null +++ b/modules/video/misc/js/gen_dict.json @@ -0,0 +1,17 @@ +{ + "whitelist": + { + "": [ + "CamShift", + "calcOpticalFlowFarneback", + "calcOpticalFlowPyrLK", + "createBackgroundSubtractorMOG2", + "findTransformECC", + "meanShift" + ], + "BackgroundSubtractorMOG2": ["BackgroundSubtractorMOG2", "apply"], + "BackgroundSubtractor": ["apply", "getBackgroundImage"], + "TrackerMIL": ["create"], + "TrackerMIL_Params": [] + } +} diff --git a/platforms/js/build_js.py b/platforms/js/build_js.py index d1c15a9c76..69cabb0ed7 100644 --- a/platforms/js/build_js.py +++ b/platforms/js/build_js.py @@ -256,8 +256,7 @@ if __name__ == "__main__": parser.add_argument('--build_flags', help="Append Emscripten build options") parser.add_argument('--build_wasm_intrin_test', default=False, action="store_true", help="Build WASM intrin tests") # Write a path to modify file like argument of this flag - parser.add_argument('--config', default=os.path.join(os.path.dirname(os.path.abspath(__file__)), 'opencv_js.config.py'), - help="Specify configuration file with own list of exported into JS functions") + parser.add_argument('--config', help="Specify configuration file with own list of exported into JS functions") parser.add_argument('--webnn', action="store_true", help="Enable WebNN Backend") transformed_args = ["--cmake_option=%s".format(arg) if arg[:2] == "-D" else arg for arg in sys.argv[1:]] @@ -265,7 +264,8 @@ if __name__ == "__main__": log.debug("Args: %s", args) - os.environ["OPENCV_JS_WHITELIST"] = os.path.abspath(args.config) + if args.config is not None: + os.environ["OPENCV_JS_WHITELIST"] = os.path.abspath(args.config) if 'EMMAKEN_JUST_CONFIGURE' in os.environ: del os.environ['EMMAKEN_JUST_CONFIGURE'] # avoid linker errors with NODERAWFS message then using 'emcmake' launcher