diff --git a/cpp/OalprLicensePlateTextDetection/plugin-files/descriptor/descriptor.json b/cpp/OalprLicensePlateTextDetection/plugin-files/descriptor/descriptor.json index 07a08b4d..bdd8f83e 100644 --- a/cpp/OalprLicensePlateTextDetection/plugin-files/descriptor/descriptor.json +++ b/cpp/OalprLicensePlateTextDetection/plugin-files/descriptor/descriptor.json @@ -34,12 +34,7 @@ "name": "OALPR LICENSE PLATE TEXT DETECTION ACTION", "description": "Executes the OALPR license plate text detection algorithm using the default parameters.", "algorithm": "OALPR", - "properties": [ - { - "name": "CONFIDENCE_THRESHOLD", - "value": "80" - } - ] + "properties": [] } ], "tasks": [ diff --git a/cpp/OcvDnnDetection/OcvDnnDetection.cpp b/cpp/OcvDnnDetection/OcvDnnDetection.cpp index c43bba85..78560d3b 100644 --- a/cpp/OcvDnnDetection/OcvDnnDetection.cpp +++ b/cpp/OcvDnnDetection/OcvDnnDetection.cpp @@ -669,7 +669,11 @@ OcvDnnDetection::OcvDnnJobConfig::OcvDnnJobConfig(const Properties &props, } number_of_classifications = GetProperty(props, "NUMBER_OF_CLASSIFICATIONS", 1); - confidence_threshold = GetProperty(props, "CONFIDENCE_THRESHOLD", 0.0); + std::string quality_property = GetProperty(props, "QUALITY_SELECTION_PROPERTY", "CONFIDENCE"); + if (quality_property != "CONFIDENCE") { + throw MPFInvalidPropertyException("QUALITY_SELECTION_PROPERTY", "Unrecognized quality selection property \"" + quality_property + "\". Only CONFIDENCE is supported for quality selection."); + } + confidence_threshold = GetProperty(props, "QUALITY_SELECTION_THRESHOLD", 0.0); classification_type = GetProperty(props, "CLASSIFICATION_TYPE", "CLASSIFICATION"); } diff --git a/cpp/OcvDnnDetection/plugin-files/descriptor/descriptor.json b/cpp/OcvDnnDetection/plugin-files/descriptor/descriptor.json index 7e473ae0..4145a999 100644 --- a/cpp/OcvDnnDetection/plugin-files/descriptor/descriptor.json +++ b/cpp/OcvDnnDetection/plugin-files/descriptor/descriptor.json @@ -127,6 +127,19 @@ "type": "STRING", "defaultValue": "" }, + { + "name": "QUALITY_SELECTION_PROPERTY", + "description": "The detection property to be used to determine its quality. Currently supports only a value of CONFIDENCE. Other values will result in an error.", + "type": "STRING", + "defaultValue": "CONFIDENCE" + }, + { + "name": "QUALITY_SELECTION_THRESHOLD", + "description": "Minimum value of the QUALITY_SELECTION_PROPERTY needed to keep detection and start a track.", + "type": "DOUBLE", + "propertiesKey": "detection.quality.selection.threshold" + }, + { "name": "FEED_FORWARD_EXCLUDE_BEHAVIOR", "description": "When FEED_FORWARD_TYPE is provided and not set to NONE, and FEED_FORWARD_ALLOW_LIST_FILE is provided, this value determines what to do with feed-forward detections with class names not contained in the FEED_FORWARD_ALLOW_LIST_FILE. Acceptable values are PASS_THROUGH and DROP.", diff --git a/cpp/OcvDnnDetection/sample_ocv_dnn_classifier.cpp b/cpp/OcvDnnDetection/sample_ocv_dnn_classifier.cpp index 6f5da1b0..749fd58d 100644 --- a/cpp/OcvDnnDetection/sample_ocv_dnn_classifier.cpp +++ b/cpp/OcvDnnDetection/sample_ocv_dnn_classifier.cpp @@ -112,8 +112,8 @@ int main(int argc, char* argv[]) { if (argc > 4) { // read the confidence threshold std::string threshold(argv[4]); - algorithm_properties["CONFIDENCE_THRESHOLD"] = threshold; - std::cout << " Confidence threshold: " << threshold << std::endl; + algorithm_properties["QUALITY_SELECTION_THRESHOLD"] = threshold; + std::cout << " Quality selection threshold: " << threshold << std::endl; } if (argc > 5) { diff --git a/cpp/OcvYoloDetection/Config.cpp b/cpp/OcvYoloDetection/Config.cpp index c4807b2a..8830f8b8 100644 --- a/cpp/OcvYoloDetection/Config.cpp +++ b/cpp/OcvYoloDetection/Config.cpp @@ -27,6 +27,7 @@ #include "Config.h" #include +#include #include "util.h" @@ -52,7 +53,7 @@ namespace { } Config::Config(const Properties &jobProps) - : confidenceThreshold(std::max(GetProperty(jobProps, "CONFIDENCE_THRESHOLD", 0.5), 0.0)) + : confidenceThreshold(std::max(GetProperty(jobProps, "QUALITY_SELECTION_THRESHOLD", 0.5), 0.0)) , nmsThresh(GetProperty(jobProps, "DETECTION_NMS_THRESHOLD", 0.3)) , numClassPerRegion(GetProperty(jobProps, "NUMBER_OF_CLASSIFICATIONS_PER_REGION", 5)) , netInputImageSize(GetProperty(jobProps, "NET_INPUT_IMAGE_SIZE", 416)) @@ -91,6 +92,10 @@ Config::Config(const Properties &jobProps) , tritonVerboseClient(GetProperty(jobProps, "TRITON_VERBOSE_CLIENT", false)) , tritonUseSSL(GetProperty(jobProps, "TRITON_USE_SSL", false)) , tritonUseShm(GetProperty(jobProps, "TRITON_USE_SHM", false)) { + std::string quality_property = GetProperty(jobProps, "QUALITY_SELECTION_PROPERTY", "CONFIDENCE"); + if (quality_property != "CONFIDENCE") { + throw MPFInvalidPropertyException("QUALITY_SELECTION_PROPERTY", "Unsupported quality selection property \"" + quality_property + "\". Only CONFIDENCE is supported for quality selection."); + } } diff --git a/cpp/OcvYoloDetection/plugin-files/descriptor/descriptor.json b/cpp/OcvYoloDetection/plugin-files/descriptor/descriptor.json index ab0bdb5d..d6c787e6 100644 --- a/cpp/OcvYoloDetection/plugin-files/descriptor/descriptor.json +++ b/cpp/OcvYoloDetection/plugin-files/descriptor/descriptor.json @@ -27,9 +27,15 @@ ], "properties": [ { - "name": "CONFIDENCE_THRESHOLD", - "description": "Minimum detection confidence value [0...1] needed to keep detection and start a track.", - "type": "FLOAT", + "name": "QUALITY_SELECTION_PROPERTY", + "description": "The detection property to be used to determine its quality. Only CONFIDENCE is spupported. Any other value will result in an error.", + "type": "STRING", + "defaultValue": "CONFIDENCE" + }, + { + "name": "QUALITY_SELECTION_THRESHOLD", + "description": "Minimum value of the QUALITY_SELECTION_PROPERTY needed to keep detection and start a track.", + "type": "DOUBLE", "defaultValue": "0.5" }, { diff --git a/cpp/OcvYoloDetection/test/TestUtils.cpp b/cpp/OcvYoloDetection/test/TestUtils.cpp index c91a310d..f9855fd3 100644 --- a/cpp/OcvYoloDetection/test/TestUtils.cpp +++ b/cpp/OcvYoloDetection/test/TestUtils.cpp @@ -70,7 +70,7 @@ Properties getTinyYoloConfig(float confidenceThreshold) { return { {"MODEL_NAME", "tiny yolo"}, {"NET_INPUT_IMAGE_SIZE", "416"}, - {"CONFIDENCE_THRESHOLD", std::to_string(confidenceThreshold)}, + {"QUALITY_SELECTION_THRESHOLD", std::to_string(confidenceThreshold)}, {"FRAME_QUEUE_CAPACITY", "16"} }; } @@ -80,7 +80,7 @@ Properties getYoloConfig(float confidenceThreshold) { return { {"MODEL_NAME", "yolo"}, {"NET_INPUT_IMAGE_SIZE", "416"}, - {"CONFIDENCE_THRESHOLD", std::to_string(confidenceThreshold)}, + {"QUALITY_SELECTION_THRESHOLD", std::to_string(confidenceThreshold)}, {"FRAME_QUEUE_CAPACITY", "16"} }; } @@ -90,7 +90,7 @@ Properties getTritonYoloConfig(const std::string &tritonServer, float confidence return { {"MODEL_NAME", "yolo"}, {"NET_INPUT_IMAGE_SIZE", "608"}, - {"CONFIDENCE_THRESHOLD", std::to_string(confidenceThreshold)}, + {"QUALITY_SELECTION_THRESHOLD", std::to_string(confidenceThreshold)}, {"CUDA_DEVICE_ID", "-1"}, {"TRACKING_MAX_FRAME_GAP", "10"}, {"ENABLE_TRITON", "true"}, diff --git a/cpp/TesseractOCRTextDetection/plugin-files/descriptor/descriptor.json b/cpp/TesseractOCRTextDetection/plugin-files/descriptor/descriptor.json index 0d914608..506ef516 100755 --- a/cpp/TesseractOCRTextDetection/plugin-files/descriptor/descriptor.json +++ b/cpp/TesseractOCRTextDetection/plugin-files/descriptor/descriptor.json @@ -27,12 +27,6 @@ "DETECTION_TEXT_TESSERACT" ], "properties": [ - { - "name": "CONFIDENCE_THRESHOLD", - "description": "The minimum confidence score which must be met or exceeded. Detections below this threshold are silently discarded. Confidence value represents the average OCR confidence reported by Tesseract for a given TESSERACT_LANGUAGE setting. When PSM 0 (OSD only) is run, this value is set to default value of -1, as no OCR confidence score is available.", - "type": "DOUBLE", - "propertiesKey": "detection.confidence.threshold" - }, { "name": "MODELS_DIR_PATH", "description": "Path to models directory", diff --git a/java/TikaImageDetection/plugin-files/descriptor/descriptor.json b/java/TikaImageDetection/plugin-files/descriptor/descriptor.json index 0160e49f..f3b9ad0f 100755 --- a/java/TikaImageDetection/plugin-files/descriptor/descriptor.json +++ b/java/TikaImageDetection/plugin-files/descriptor/descriptor.json @@ -21,12 +21,6 @@ "DETECTION_MEDIA_TIKA" ], "properties": [ - { - "name": "CONFIDENCE_THRESHOLD", - "description": "The minimum confidence score which must be met or exceeded. Detections below this threshold are silently discarded.", - "type": "DOUBLE", - "defaultValue": "-2" - }, { "name": "SAVE_PATH", "description": "Specifies main directory for storing extracted images.", diff --git a/java/TikaTextDetection/plugin-files/descriptor/descriptor.json b/java/TikaTextDetection/plugin-files/descriptor/descriptor.json index 1dd4ae1b..c5bcc2ce 100755 --- a/java/TikaTextDetection/plugin-files/descriptor/descriptor.json +++ b/java/TikaTextDetection/plugin-files/descriptor/descriptor.json @@ -21,12 +21,6 @@ "DETECTION_TEXT_TIKA" ], "properties": [ - { - "name": "CONFIDENCE_THRESHOLD", - "description": "The minimum confidence score which must be met or exceeded. Detections below this threshold are silently discarded.", - "type": "DOUBLE", - "defaultValue": "-2" - }, { "name": "STORE_METADATA", "description": "Specifies whether or not to store metadata as a separate track detection.", diff --git a/python/EastTextDetection/README.md b/python/EastTextDetection/README.md index ab2aa864..05e70df0 100644 --- a/python/EastTextDetection/README.md +++ b/python/EastTextDetection/README.md @@ -12,13 +12,13 @@ By default, images and videos are processed at full resolution. However, users c When handling video, the component processes frames in batches. Users can control the size of these batches by setting the `BATCH_SIZE` parameter. Larger values (e.g. 32 or 64) will improve processing speed at the cost of a larger memory footprint. By default, `BATCH_SIZE` is set to 1. -Users can control how frequently text is detected with the `CONFIDENCE_THRESHOLD` property, which is the threshold value for filtering detections by bounding box confidence. By raising this parameter, fewer detections will be reported, but those detections will tend to be of higher quality. Lowering it will have the opposite effect; many bounding boxes will be returned, but many of them may represent false positives, and contain no text in truth. By default, this property is set to 0.8, which works well for Latin script (used in most western European languages). +Users can control how frequently text is detected with the `QUALITY_SELECTION_THRESHOLD` property, which is the threshold value for filtering detections by bounding box confidence. By raising this parameter, fewer detections will be reported, but those detections will tend to be of higher quality. Lowering it will have the opposite effect; many bounding boxes will be returned, but many of them may represent false positives, and contain no text in truth. By default, this property is set to 0.8, which works well for Latin script (used in most western European languages). The EAST model naturally prefers horizontal text, as text at high degrees of rotation is rare in unstructured reading datasets. If the user anticipates a large amount of rotated text, they can indicate with the `ROTATE_AND_DETECT` parameter that the input should be processed a second time after rotating 90 degrees. The `SUPPRESS_VERTICAL` property controls whether to discard detections which are taller than they are wide. When dealing with English text, such detections are usually incorrect, and when `ROTATE_AND_DETECT` is `TRUE`, these spurious bounding boxes will often interfere with correct detections. -Note that `SUPPRESS_VERTICAL=TRUE` will result in missed detections for language read from top to bottom, as is common in some styles of East Asian scripts. If vertical text is expected, it is recommended to set this property to `FALSE`, in addition to lowering the `CONFIDENCE_THRESHOLD` property to small values like `0.001`, as EAST does not handle this type of text well natively. +Note that `SUPPRESS_VERTICAL=TRUE` will result in missed detections for language read from top to bottom, as is common in some styles of East Asian scripts. If vertical text is expected, it is recommended to set this property to `FALSE`, in addition to lowering the `QUALITY_SELECTION_THRESHOLD` property to small values like `0.001`, as EAST does not handle this type of text well natively. The `MERGE_REGIONS` property dictates how detections are filtered and/or combined. When set to `FALSE`, standard non-maximum suppression is used with `NMS_MIN_OVERLAP` as a threshold value. In this case, when the ratio between the areas of intersection and union of two regions is greater than or equal to `NMS_MIN_OVERLAP`, the detection with the lower confidence score is dropped. diff --git a/python/EastTextDetection/east_component/east_component.py b/python/EastTextDetection/east_component/east_component.py index 18af8618..d062b7cb 100644 --- a/python/EastTextDetection/east_component/east_component.py +++ b/python/EastTextDetection/east_component/east_component.py @@ -55,7 +55,10 @@ def _parse_properties(props): batch_size = int(props.get('BATCH_SIZE','1')) # Get the threshold values for filtering bounding boxes - min_confidence = float(props.get('CONFIDENCE_THRESHOLD','0.8')) + quality_property = props.get('QUALITY_SELECTION_PROPERTY', 'CONFIDENCE') + if quality_property != "CONFIDENCE": + raise mpf.DetectionError.INVALID_PROPERTY.exception('Unsupported quality selection property \"' + quality_property + '\". Only CONFIDENCE is supported.') + min_confidence = float(props.get('QUALITY_SELECTION_THRESHOLD','0.8')) overlap_threshold = float(props.get('MERGE_OVERLAP_THRESHOLD','0.0')) min_nms_overlap = float(props.get('NMS_MIN_OVERLAP','0.1')) max_height_delta = float(props.get('MERGE_MAX_TEXT_HEIGHT_DIFFERENCE','0.3')) diff --git a/python/EastTextDetection/plugin-files/descriptor/descriptor.json b/python/EastTextDetection/plugin-files/descriptor/descriptor.json index ab96208e..b7a987fb 100644 --- a/python/EastTextDetection/plugin-files/descriptor/descriptor.json +++ b/python/EastTextDetection/plugin-files/descriptor/descriptor.json @@ -22,9 +22,15 @@ ], "properties": [ { - "name": "CONFIDENCE_THRESHOLD", - "description": "Threshold value for filtering detections by bounding box confidence, between 0.0 and 1.0. Detections with scores lower than this value are dropped prior to non-maximum suppression.", - "type": "FLOAT", + "name": "QUALITY_SELECTION_PROPERTY", + "description": "The detection property to be used to filter out low quality detections. Only CONFIDENCE is supported. Other values will result in an error.", + "type": "STRING", + "defaultValue": "CONFIDENCE" + }, + { + "name": "QUALITY_SELECTION_THRESHOLD", + "description": "Threshold value for filtering detections by quality selection property. Detections with scores lower than this value are dropped prior to non-maximum suppression.", + "type": "DOUBLE", "defaultValue": "0.8" }, { @@ -41,7 +47,7 @@ }, { "name": "NMS_MIN_OVERLAP", - "description": "Threshold value used during non-maximum suppression, between 0.0 and 1.0, only used when MERGE_REGIONS is false. When the ratio between the areas of intersection and union between two regions is greater than or equal to this value, the lower-confidence detection will be dropped.", + "description": "Threshold value used during non-maximum suppression, between 0.0 and 1.0, only used when MERGE_REGIONS is false. When the ratio between the areas of intersection and union between two regions is greater than or equal to this value, the lower-quality detection will be dropped.", "type": "FLOAT", "defaultValue": "0.1" }, diff --git a/python/EastTextDetection/tests/sample_east_text_detector.py b/python/EastTextDetection/tests/sample_east_text_detector.py index 668a7585..9899d343 100644 --- a/python/EastTextDetection/tests/sample_east_text_detector.py +++ b/python/EastTextDetection/tests/sample_east_text_detector.py @@ -97,7 +97,7 @@ def __exit__(self, *args): properties = dict( MAX_SIDE_LENGTH=str(args.max_side_length), - CONFIDENCE_THRESHOLD=str(args.confidence_threshold), + QUALITY_SELECTION_THRESHOLD=str(args.confidence_threshold), MERGE_OVERLAP_THRESHOLD=str(args.merge_overlap_threshold), NMS_MIN_OVERLAP=str(args.nms_min_overlap), MERGE_MAX_TEXT_HEIGHT_DIFFERENCE=str(args.merge_max_text_height_difference),