2

In BlackHatPython, Chapter 4 has this function:

def face_detect(path,file_name):
  img = cv2.imread(path)
  cascade = cv2.CascadeClassifier("haarcascade_frontalface_alt.xml")
  rects = cascade.detectMultiScale(img, 1.3, 4, cv2.cv.CV_HAAR_SCALE_IMAGE, (20,20))
  if len(rects) == 0:
    return False
  rects[:, 2:] += rects[:, :2]
  # highlight the faces in the image
  for x1,y1,x2,y2 in rects:
    cv2.rectangle(img,(x1,y1),(x2,y2),(127,255,0),2)
  cv2.imwrite("%s/%s-%s" % (faces_directory,pcap_file,file_name),img)
  return True

What is the meaning of

rect[:, 2:] += rects[:, :2]  
AndyG
  • 39,700
  • 8
  • 109
  • 143
iuqwe
  • 33
  • 1
  • 1
  • 4
  • That syntax is array slicing – code11 Nov 08 '16 at 14:03
  • That is is not any syntax. That would raise a `TypeError` – Farhan.K Nov 08 '16 at 14:05
  • 2
    looks like `numpy` to me. https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html – Patrick Haugh Nov 08 '16 at 14:06
  • @Farhan.K A slice can consist of a comma-separated sequence of *proper* slices, which have the general form `start:step:stop`. Built-in types only accept proper slices; the full form was added to the language for `numpy`. Any user-defined class, though, can accept them. – chepner Nov 08 '16 at 14:10
  • 1
    With `rects[:, :2]`, the argument to `type(rects).__getitem__()` would be a tuple of `slice` objects: `((slice(None, None, None), slice(None, 2, None))`. – chepner Nov 08 '16 at 14:12
  • @Farhan.K since you get a `TypeError` it has passed the parsing, that is it's valid syntax. Then `m` of course must be of a type that supports the operation. – skyking Nov 08 '16 at 14:16
  • @chepner ah right... I think I need some sleep :) – Farhan.K Nov 08 '16 at 14:52
  • 1
    This question is not really a duplicate since it is not just about the syntax but is about what this line of code really does... The answer is that it converts an array of rects like [x, y, w, h] to an array of [x, y, x+w, y+h], which is easier to use afterwards. – Vinicius Jun 15 '18 at 22:53

2 Answers2

4

This is slicing arrays in python, as e.g. explained here: Explain Python's slice notation

In you specific case, you have a numpy array, which is a 2D structure, so there are two dimensions on which you can slice. The individual slices are separated by the comma. Look at this code for a visualization:

In [7]: np.diag([3,4,5])
Out[7]: 
array([[3, 0, 0],
       [0, 4, 0],
       [0, 0, 5]])

In [8]: np.diag([3,4,5])[:2]
Out[8]: 
array([[3, 0, 0],
       [0, 4, 0]])

In [9]: np.diag([3,4,5])[:2, :]
Out[9]: 
array([[3, 0, 0],
       [0, 4, 0]])

In [10]: np.diag([3,4,5])[:2, :1]
Out[10]: 
array([[3],
       [0]])
languitar
  • 6,554
  • 2
  • 37
  • 62
0

To dissect what the expression is you have to consult the Python Language Reference. What it is is that the subexpressions : and 2: are slicings, then the expression :, 2: is two slicings joined by the comma operator (creating a tuple of two slicings). Then that is used to subscribe rect and rects and whatever that results in will be applied to the += operator.

skyking
  • 13,817
  • 1
  • 35
  • 57