Skip to content

Commit dc2d637

Browse files
committed
improve docstrings
1 parent 6128948 commit dc2d637

File tree

1 file changed

+59
-32
lines changed

1 file changed

+59
-32
lines changed

MTM/__init__.py

Lines changed: 59 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
"""Main code for Multi-Template-Matching (MTM)."""
12
import cv2
23
import numpy as np
34
import pandas as pd
@@ -11,10 +12,7 @@
1112
__all__ = ['NMS']
1213

1314
def _findLocalMax_(corrMap, score_threshold=0.6):
14-
'''
15-
Get coordinates of the local maximas with values above a threshold in the image of the correlation map
16-
'''
17-
15+
"""Get coordinates of the local maximas with values above a threshold in the image of the correlation map."""
1816
# IF depending on the shape of the correlation map
1917
if corrMap.shape == (1,1): ## Template size = Image size -> Correlation map is a single digit')
2018

@@ -43,16 +41,18 @@ def _findLocalMax_(corrMap, score_threshold=0.6):
4341

4442

4543
def _findLocalMin_(corrMap, score_threshold=0.4):
46-
'''Find coordinates of local minimas with values below a threshold in the image of the correlation map'''
44+
"""Find coordinates of local minimas with values below a threshold in the image of the correlation map."""
4745
return _findLocalMax_(-corrMap, -score_threshold)
4846

4947

5048
def computeScoreMap(template, image, method=cv2.TM_CCOEFF_NORMED, mask=None):
51-
'''
52-
Compute score map provided numpy array for template and image.
53-
Automatically converts images if necessary
54-
return score map as numpy as array
55-
'''
49+
"""
50+
Compute score map provided numpy array for template and image (automatically converts images if necessary).
51+
52+
Return
53+
------
54+
score map as numpy array
55+
"""
5656
if template.dtype == "float64" or image.dtype == "float64":
5757
raise ValueError("64-bit images not supported, max 32-bit")
5858

@@ -82,30 +82,36 @@ def computeScoreMap(template, image, method=cv2.TM_CCOEFF_NORMED, mask=None):
8282

8383

8484
def findMatches(listTemplates, image, method=cv2.TM_CCOEFF_NORMED, N_object=float("inf"), score_threshold=0.5, searchBox=None):
85-
'''
86-
Find all possible templates locations provided a list of template to search and an image
85+
"""
86+
Find all possible templates locations provided a list of templates to search and an image.
87+
8788
Parameters
8889
----------
8990
- listTemplates : list of tuples (LabelString, template, mask (optional))
9091
templates to search in each image, associated to a label
9192
labelstring : string
9293
template : numpy array (grayscale or RGB)
93-
mask (optional): numpy array, should have the same dimensions and type than the template)
94+
mask (optional): numpy array, should have the same dimensions and type than the template
95+
9496
- image : Grayscale or RGB numpy array
9597
image in which to perform the search, it should be the same bitDepth and number of channels than the templates
98+
9699
- method : int
97100
one of OpenCV template matching method (0 to 5), default 5=0-mean cross-correlation
98-
- N_object: int
99-
expected number of objects in the image, -1 if unknown
101+
102+
- N_object: int or float("inf")
103+
expected number of objects in the image, default to infinity if unknown
104+
100105
- score_threshold: float in range [0,1]
101-
if N>1, returns local minima/maxima respectively below/above the score_threshold
106+
if N_object>1, returns local minima/maxima respectively below/above the score_threshold
107+
102108
- searchBox : tuple (X, Y, Width, Height) in pixel unit
103109
optional rectangular search region as a tuple
104110
105111
Returns
106112
-------
107113
- Pandas DataFrame with 1 row per hit and column "TemplateName"(string), "BBox":(X, Y, Width, Height), "Score":float
108-
'''
114+
"""
109115
if N_object!=float("inf") and type(N_object)!=int:
110116
raise TypeError("N_object must be an integer")
111117

@@ -175,34 +181,44 @@ def findMatches(listTemplates, image, method=cv2.TM_CCOEFF_NORMED, N_object=floa
175181

176182

177183
def matchTemplates(listTemplates, image, method=cv2.TM_CCOEFF_NORMED, N_object=float("inf"), score_threshold=0.5, maxOverlap=0.25, searchBox=None):
178-
'''
179-
Search each template in the image, and return the best N_object location which offer the best score and which do not overlap
184+
"""
185+
Search each template in the image, and return the best N_object locations which offer the best score and which do not overlap above the maxOverlap threshold.
186+
180187
Parameters
181188
----------
182-
- listTemplates : list of tuples (LabelString, Grayscale or RGB numpy array)
183-
templates to search in each image, associated to a label
189+
- listTemplates : list of tuples (LabelString, template, mask (optional))
190+
templates to search in each image, associated to a label
191+
labelstring : string
192+
template : numpy array (grayscale or RGB)
193+
mask (optional): numpy array, should have the same dimensions and type than the template
194+
184195
- image : Grayscale or RGB numpy array
185196
image in which to perform the search, it should be the same bitDepth and number of channels than the templates
197+
186198
- method : int
187-
one of OpenCV template matching method (1 to 5), default 5=0-mean cross-correlation
188-
method 0 is not supported (no NMS implemented for non-bound difference score), use 1 instead
189-
- N_object: int
190-
expected number of objects in the image
199+
one of OpenCV template matching method (1 to 5), default 5=0-mean cross-correlation
200+
method 0 is not supported (no NMS implemented for non-bound difference score), use 1 instead
201+
202+
- N_object: int or foat("inf")
203+
expected number of objects in the image, default to infinity if unknown
204+
191205
- score_threshold: float in range [0,1]
192206
if N>1, returns local minima/maxima respectively below/above the score_threshold
207+
193208
- maxOverlap: float in range [0,1]
194209
This is the maximal value for the ratio of the Intersection Over Union (IoU) area between a pair of bounding boxes.
195210
If the ratio is over the maxOverlap, the lower score bounding box is discarded.
211+
196212
- searchBox : tuple (X, Y, Width, Height) in pixel unit
197213
optional rectangular search region as a tuple
198214
199215
Returns
200216
-------
201217
Pandas DataFrame with 1 row per hit and column "TemplateName"(string), "BBox":(X, Y, Width, Height), "Score":float
202218
if N=1, return the best matches independently of the score_threshold
203-
if N<inf, returns up to N best matches that passed the score_threshold
204-
if N=inf, returns all matches that passed the score_threshold
205-
'''
219+
if N<inf, returns up to N best matches that passed the NMS
220+
if N=inf, returns all matches that passed the NMS
221+
"""
206222
if maxOverlap<0 or maxOverlap>1:
207223
raise ValueError("Maximal overlap between bounding box is in range [0-1]")
208224

@@ -216,27 +232,32 @@ def matchTemplates(listTemplates, image, method=cv2.TM_CCOEFF_NORMED, N_object=f
216232

217233

218234
def drawBoxesOnRGB(image, tableHit, boxThickness=2, boxColor=(255, 255, 00), showLabel=False, labelColor=(255, 255, 0), labelScale=0.5 ):
219-
'''
235+
"""
220236
Return a copy of the image with predicted template locations as bounding boxes overlaid on the image
221237
The name of the template can also be displayed on top of the bounding box with showLabel=True
238+
222239
Parameters
223240
----------
224241
- image : image in which the search was performed
242+
225243
- tableHit: list of hit as returned by matchTemplates or findMatches
244+
226245
- boxThickness: int
227246
thickness of bounding box contour in pixels
228247
- boxColor: (int, int, int)
229248
RGB color for the bounding box
249+
230250
- showLabel: Boolean
231251
Display label of the bounding box (field TemplateName)
252+
232253
- labelColor: (int, int, int)
233254
RGB color for the label
234255
235256
Returns
236257
-------
237258
outImage: RGB image
238259
original image with predicted template locations depicted as bounding boxes
239-
'''
260+
"""
240261
# Convert Grayscale to RGB to be able to see the color bboxes
241262
if image.ndim == 2: outImage = cv2.cvtColor(image, cv2.COLOR_GRAY2RGB) # convert to RGB to be able to show detections as color box on grayscale image
242263
else: outImage = image.copy()
@@ -250,27 +271,33 @@ def drawBoxesOnRGB(image, tableHit, boxThickness=2, boxColor=(255, 255, 00), sho
250271

251272

252273
def drawBoxesOnGray(image, tableHit, boxThickness=2, boxColor=255, showLabel=False, labelColor=255, labelScale=0.5):
253-
'''
274+
"""
254275
Same as drawBoxesOnRGB but with Graylevel.
255276
If a RGB image is provided, the output image will be a grayscale image
277+
256278
Parameters
257279
----------
258280
- image : image in which the search was performed
281+
259282
- tableHit: list of hit as returned by matchTemplates or findMatches
283+
260284
- boxThickness: int
261285
thickness of bounding box contour in pixels
286+
262287
- boxColor: int
263288
Gray level for the bounding box
289+
264290
- showLabel: Boolean
265291
Display label of the bounding box (field TemplateName)
292+
266293
- labelColor: int
267294
Gray level for the label
268295
269296
Returns
270297
-------
271298
outImage: Single channel grayscale image
272299
original image with predicted template locations depicted as bounding boxes
273-
'''
300+
"""
274301
# Convert RGB to grayscale
275302
if image.ndim == 3: outImage = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) # convert to RGB to be able to show detections as color box on grayscale image
276303
else: outImage = image.copy()

0 commit comments

Comments
 (0)