ひきつづき『サイバーセキュリティプログラミング第2版』の読書メモです。
4.3 章まで進みました。記載されているコードをじっくり確認しながら読み進めています。
P86 detect 関数より
python から OpenCV を使って画像データに人の顔が含まれるかを検出する関数です。が、「ある一行」の理解につまづきました。
rects[:,2:] += rects[:,:2] # ⑤
P87 の解説によると、
… rects は (x, y, width, height) という形式であり、x, y は四角形の左下の座標、width, height は四角形の幅と高さを表す。
⑤に示す Python のスライス構文により上記の rects データを (x1, y1, x1+width, y1+width) ― 言い換えると (x1, y1, x2, y2) ― に変換することで、cv2.rectangle の引数として利用しやすくしている。
著者は「Python のスライス構文」と言っていますが、これはどうやら NumPy モジュールの配列演算ということでした。
以下のようにして処理内容を確認してみました。
import numpy
rects = numpy.array([[1,2,10,20],[3,5,30,50],[7,9,70,90]])
print(rects)
rects[:,2:] += rects[:,:2]
print(rects)
このコードを実行すると、
>>> import numpy
>>> rects = numpy.array([[1,2,10,20],[3,5,30,50],[7,9,70,90]])
>>> print(rects)
[[ 1 2 10 20]
[ 3 5 30 50]
[ 7 9 70 90]]
>>> rects[:,2:] += rects[:,:2]
>>> print(rects)
[[ 1 2 11 22]
[ 3 5 33 55]
[ 7 9 77 99]]
>>>
図示すると、青で囲った部分の各要素を赤で囲った部分の各要素でインクリメントしています。
同等の処理を泥臭い書き方をすると次のようになります。
for i in range(len(rects)):
rects[i][2] = rects[i][2] + rects[i][0]
rects[i][3] = rects[i][3] + rects[i][1]
この3行が先ほどの 1行に凝縮されているということでした。