1212__version__ = '1.0.1'
1313
1414
15- def findMaximas (corrMap , scoreThreshold = 0.6 , nObjects = float ( "inf" ) ):
15+ def findMaximas (corrMap , scoreThreshold = 0.6 , singleMatch = False ):
1616 """
1717 Maxima detection in correlation map.
1818
19- Get coordinates of the global (nObjects=1)
20- or local maximas with values above a threshold
21- in the image of the correlation map.
19+ Get coordinates of the global (singleMatch=True)
20+ or local maximas with values above the scoreThreshold.
2221 """
2322 # IF depending on the shape of the correlation map
2423 if corrMap .shape == (1 , 1 ): # Template size = Image size -> Correlation map is a single digit representing the score
2524 listPeaks = np .array ([[0 , 0 ]]) if corrMap [0 , 0 ] >= scoreThreshold else []
2625
2726 else : # Correlation map is a 1D or 2D array
28- nPeaks = 1 if nObjects == 1 else float ("inf" ) # global maxima detection if nObject=1 (find best hit of the score map)
27+ nPeaks = 1 if singleMatch else float ("inf" ) # global maxima detection if singleMatch (ie find best hit of the score map)
28+
2929 # otherwise local maxima detection (ie find all peaks), DONT LIMIT to nObjects, more than nObjects detections might be needed for NMS
3030 listPeaks = feature .peak_local_max (corrMap ,
3131 threshold_abs = scoreThreshold ,
3232 exclude_border = False ,
3333 num_peaks = nPeaks ).tolist ()
34-
34+
3535 return listPeaks
3636
3737
3838def findMatches (image ,
3939 listTemplates ,
4040 listLabels = None ,
4141 scoreThreshold = 0.5 ,
42- nObjects = float ( "inf" ) ,
42+ singleMatch = False ,
4343 searchBox = None ,
4444 downscalingFactor = 1 ):
4545 """
46- Find all possible templates locations provided a list of template to search and an image.
46+ Find all possible templates locations above a score-threshold, provided a list of templates to search and an image.
47+ Resulting detections are not filtered by NMS and thus might overlap.
48+ Use matchTemplates to perform the search with NMS.
4749
4850 Parameters
4951 ----------
@@ -55,14 +57,14 @@ def findMatches(image,
5557
5658 - listLabels (optional) : list of string labels associated to the templates (order must match the templates in listTemplates).
5759 these labels can describe categories associated to the templates
58-
60+
5961 - scoreThreshold: float in range [0,1]
60- if N>1 , returns local minima/ maxima respectively below/ above the scoreThreshold
61-
62- - nObjects: 1 or infinity (default)
63- If N=1 use global maxima detection, otherwise use local maxima detection
64-
65-
62+ if singleMatch is False , returns local maxima with score above the scoreThreshold
63+
64+ - singleMatch : boolean
65+ True : return a single top-score detection for each template using global maxima detection. This is suitable for single-object- detection.
66+ False : use local maxima detection to find all possible template locations above the score threshold, suitable for detection of mutliple objects.
67+
6668 - searchBox (optional): tuple (x y, width, height) in pixels
6769 limit the search to a rectangular sub-region of the image
6870
@@ -74,11 +76,6 @@ def findMatches(image,
7476 -------
7577 - List of BoundingBoxes
7678 """
77- if nObjects != float ("inf" ) and type (nObjects ) != int :
78- raise TypeError ("nObjects must be an integer" )
79-
80- if nObjects < 1 :
81- raise ValueError ("At least one object should be expected in the image" )
8279
8380 if (listLabels is not None and
8481 (len (listTemplates ) != len (listLabels ))):
@@ -115,7 +112,7 @@ def findMatches(image,
115112 template = transform .rescale (template , 1 / downscalingFactor , anti_aliasing = False )
116113
117114 corrMap = feature .match_template (image , template )
118- listPeaks = findMaximas (corrMap , scoreThreshold , nObjects )
115+ listPeaks = findMaximas (corrMap , scoreThreshold , singleMatch )
119116
120117 height , width = template .shape [0 :2 ] # slicing make sure it works for RGB too
121118 label = listLabels [index ] if listLabels else ""
@@ -184,8 +181,9 @@ def matchTemplates(image,
184181 """
185182 if maxOverlap < 0 or maxOverlap > 1 :
186183 raise ValueError ("Maximal overlap between bounding box is in range [0-1]" )
187-
188- listHit = findMatches (image , listTemplates , listLabels , scoreThreshold , nObjects , searchBox , downscalingFactor )
184+
185+ singleMatch = nObjects == 1
186+ listHit = findMatches (image , listTemplates , listLabels , scoreThreshold , singleMatch , searchBox , downscalingFactor )
189187 bestHits = nms .runNMS (listHit , maxOverlap , nObjects )
190188
191189 return bestHits
0 commit comments