-
-
Notifications
You must be signed in to change notification settings - Fork 56.5k
Make BarcodeDetector resolution invariant #24902
Description
Describe the feature and motivation
The cv::barcode::BarcodeDetector relies on hardcoded parameters in bardetect.cpp.
The barcode localisation algorithm is very good, but it has some limitations in terms of high-res and small barcode inputs that make it both resolution and barcode scale dependent.
I had managed to figure out four values that impact this:
- the input image is downsampled to 512px by default (a workaround is to use
np.lib.stride_tricks.sliding_window_viewto process the image in patches, and NMS the resulting boxes afterwards which is inefficient). - the gradient magnitude threshold is permanently set to 64.
- window sizes for filters have been empirically determined with respect to input size and is not possible to adjust them
{0.01f, 0.03f, 0.06f, 0.08f}for other scenarios. - the NMS Box threshold is calculated and set for a 512px wide image
There are a lot more parameters in bardetect.cpp but these are the most relevant ones which need to be tuned to improve the barcode localisation performance.
This is what the stock detector returns for a 2048x1536 input image.

Obviously this is very poor performance. But after manually adjusting these parameters, I am able to successfully localise each barcode in the image.
Additional context
Proposal on how to set detector parameters, and reference values used for the test pattern.
detector = cv2.barcode.BarcodeDetector()
div = float(np.max(frame.shape)) / 512.
detector.setDownSampleThresh( div * 512 ) # prevent downsample
detector.setDetectorScales( [ 0.01/div, 0.03/div, 0.06/div, 0.08/div ] )
detector.setGradientThresh( 256 )
This should keep compatibility and maintain the current behaviour of the standard barcode detector.
LE: Updated proposal to set detector parameters per 24903

