gooブログはじめました!

写真付きで日記や趣味を書くならgooブログ

python(carnets)で顔認証し、バドミントンなどで順番決めを行う

2024-03-16 11:37:57 | Python

iPadで顔認証し、人数を数えるpythonスクリプトを作りましたので紹介します。carnetsという無料アプリを使ってpythonを実行しています。

色々制約があるようでなんちゃってpythonですが参考に。

以下はマークダウン形式です。

```python
# ipad+python(carnets)を用いて
# ipadのカメラで
# 顔認証し、人数を数える(カメラマンを含む)
# ただし、顔に手がついていたり、傾いた顔、横顔は認識出来ない
# ipadpro11 ios17.4 carnets with Scipy
# carnets はAppstoreで入手して下さい(いちおう無料)
```


```python
# pip list
```


```python
import cv2
# from cv2 import dnn # deep neural networks
from PIL import Image
import matplotlib.pyplot as plt # carnetsでは画像表示に必須のよう
import time
import numpy as np
import random
```


```python
device = 0 # back camera
# device = 1 # front camera
cap = cv2.VideoCapture(device) # camera shot
```


```python
time.sleep(0.1) # 直ぐには読みこめない
```


```python
# カメラ設定を確認する どういうわけか解像度しか読みこめない
# カメラを横向きにしてもだめ

camera_parameters = ['CAP_PROP_FRAME_WIDTH', # 4 解像度(幅)
                    'CAP_PROP_FRAME_HEIGHT', # 3 解像度(高さ)
                    'CAP_PROP_FOURCC',       # 圧縮フォーマット
                    'CAP_PROP_BRIGHTNESS',   # 明るさ
                    'CAP_PROP_CONTRAST',     # コントラスト
                    'CAP_PROP_SATURATION',   # 彩度
                    'CAP_PROP_HUE',          # 色相
                    'CAP_PROP_GAIN',         # ゲイン
                    'CAP_PROP_EXPOSURE']     # 露出
print('CAP_PROP_FRAME_WIDTH = ', cap.get(4))
print('CAP_PROP_FRAME_HEIGHT= ', cap.get(3))
```

    CAP_PROP_FRAME_WIDTH =  360.0
    CAP_PROP_FRAME_HEIGHT=  480.0

 

```python
cap.set(3, 1080) # どうも設定変更ができないようです
```

 


    True

 


```python
print('CAP_PROP_FRAME_WIDTH = ', cap.get(4))
print('CAP_PROP_FRAME_HEIGHT= ', cap.get(3))
```

    CAP_PROP_FRAME_WIDTH =  360.0
    CAP_PROP_FRAME_HEIGHT=  480.0

 

```python
ret, frame = cap.read()
```


```python
print(ret)
```

    True

 

```python
print(type(frame)) # 正常に読み込めたかの確認 numpy.ndarray形式ならOK
```

    <class 'numpy.ndarray'>

 

```python
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # グレースケール変換
```


```python
rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) # RGB変換
```


```python
# plt.figure(figsize=(6,5)) # 画面サイズが変更できない
```


```python
plt.imshow(gray) # matplotlibの色なのでグレーには見えませんが、気にしないでください
```

 


   

 


    
![png](output_14_1.png)
    

 

```python
# plt.imshow(rgb)
```


```python
# ハール識別器の設定

# 見かけ上ファイル名は...xmlですが、情報を見ると.txtがついていた
# メガネをかけていると検知できないことがあります
# 横顔は検知できません
# clf = cv2.CascadeClassifier("haarcascade_frontalface_default.xml.txt")
# clf = cv2.CascadeClassifier("haarcascade_upperbody.xml")
clf = cv2.CascadeClassifier("haarcascade_frontalface_alt.xml.txt")
```


```python
faces = clf.detectMultiScale(gray,
                             scaleFactor=1.1,
                             minNeighbors=2,
                             minSize=(15,15))
```


```python
faces # 検出した顔の配列を確認のため出力 ex, ey, ew, eh
```

 


    array([[120, 281,  25,  25],
           [ 90, 284,  23,  23],
           [240,  90,  25,  25],
           [289,  87,  26,  26],
           [332,  86,  26,  26],
           [236, 138,  28,  28],
           [286, 238,  26,  26],
           [235, 191,  26,  26],
           [332, 188,  27,  27],
           [ 88, 175,  34,  34],
           [118, 178,  31,  31],
           [150, 176,  32,  32]], dtype=int32)

 


```python
maxid = len(faces)
print(maxid)
```

    12

 

```python
rnd = random.sample(range(1,maxid+2),maxid+1) # カメラマン含む
print(rnd)
```

    [8, 13, 6, 10, 2, 9, 3, 5, 1, 12, 4, 7, 11]

 

```python
id = 0 # detected id
```


```python
# 顔を四角で囲み、ランダムな番号をふる
for (ex,ey,ew,eh) in faces:
    cv2.rectangle(rgb,          # image
                  (ex,ey),       # box
                  (ex+ew,ey+eh),
                  (255,255,255), # color
                  2,             # thickness
#                 cv2.FILLED)    # linetype 塗りつぶし
                  cv2.LINE_AA)
    text = "{0}".format(rnd[id])
    id = id + 1
    # text = "{0}".format(id)
    scale = 0.6
    cv2.putText(rgb,                      # 描画対象のimage
                text,                     # text
                (ex+3,ey-5),              # right bottom
                cv2.FONT_HERSHEY_SIMPLEX, # font style
                scale,                    # fontScale
                (255,255,255),            # color
                2,                        # thickness
                cv2.LINE_AA)              # lineTyp
    cv2.rectangle(rgb,(ex,ey-25),(ex+30,ey),(255,255,255),1) # rectangle on id
```


```python
# cameraman
bg = cv2.rectangle(rgb,(45,475),(300,450),(255,255,255),cv2.FILLED)
cameraman = cv2.putText(rgb,
            'total: '+"{0}".format(maxid+1)+
            '  cameraman: '+"{0}".format(rnd[maxid]),
            (50,470),
            cv2.FONT_HERSHEY_SIMPLEX,
            scale,
            (0,0,0),
            1,
            cv2.LINE_AA)
```


```python
plt.imshow(rgb)
```

 


   

 


    
![png](output_24_1.png)
    

 

```python
cap.release()
```


```python

```


```python

```



最新の画像もっと見る

コメントを投稿