某マリオゲームにて,スターを取得した時,無敵の曲が流れます.その曲が作業時のみ流れたら,俺最強感を味わえ無敵になれます.作業もガーーーっと進むでしょう.
仕組み
それはどういう仕組みかをザッと説明すると,
- webカメラで顔を検出(opencv)
- 顔を検出している間,音楽を流し続ける
以上です.作業時は画面をみているので,顔検出が可能となり,それを情報として使えます.
ロジックはシンプル.
プログラム
とりあえず実行するプログラムを以下に示します.一応pythonで記述されています.
実行する時は,引数として,無敵スター状態のmp3ファイルパスを指定します.(別に他の音楽ファイルでもいいのですけれど...)
python3 segcam.py smb_star.mp3
import sys
import numpy as np
import cv2
import pygame
if __name__ == '__main__':
    # 定数定義
    ESC_KEY = 27     # Escキー
    INTERVAL= 33     # 待ち時間
    FRAME_RATE = 30  # fps
    ORG_WINDOW_NAME = "org"
    # GAUSSIAN_WINDOW_NAME = "gaussian"
    DEVICE_ID = 0
    # 分類器の指定
    cascade_file = "./haarcascade_frontalface_alt2.xml"
    cascade = cv2.CascadeClassifier(cascade_file)
    # カメラ映像取得
    cap = cv2.VideoCapture(DEVICE_ID)
    # 初期フレームの読込
    end_flag, c_frame = cap.read()
    height, width, channels = c_frame.shape
    # ウィンドウの準備
    cv2.namedWindow(ORG_WINDOW_NAME)
    # cv2.namedWindow(GAUSSIAN_WINDOW_NAME)
    # 連続して検出しているか
    flag = 0
    # 変換処理ループ
    while end_flag == True:
        # 画像の取得と顔の検出
        img = c_frame
        img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        face_list = cascade.detectMultiScale(img_gray, minSize=(100, 100))
        # 顔を検出した場合
        if len(face_list) != 0:
            if flag == 0:
                # 音楽流す
                # mixerモジュールの初期化
                pygame.mixer.init(frequency = 48000)
                # 音楽ファイルの読み込み
                pygame.mixer.music.load(sys.argv[1])
                # 音楽再生、および再生回数の設定(-1はループ再生)
                pygame.mixer.music.play(-1)
            # 検出した顔に印を付ける
            for (x, y, w, h) in face_list:
                color = (0, 0, 225)
                pen_w = 3
                # cv2.rectangle(img_gray, (x, y), (x+w, y+h), color, thickness = pen_w)
                cv2.rectangle(c_frame, (x, y), (x+w, y+h), color, thickness = pen_w)
            
            flag = 1
        
        else:
            if flag == 1:
                pygame.mixer.music.stop()
            flag = 0
        # フレーム表示
        cv2.imshow(ORG_WINDOW_NAME, c_frame)
        # cv2.imshow(GAUSSIAN_WINDOW_NAME, img_gray)
        # Escキーで終了
        key = cv2.waitKey(INTERVAL)
        if key == ESC_KEY:
            break
        # 次のフレーム読み込み
        end_flag, c_frame = cap.read()
    # 終了処理
    cv2.destroyAllWindows()
    cap.release()
これは,顔を検出するサンプルプログラムを元にしています(9割以上コピペ).このソースを参考しましたよと書きたいのですが,そもそもこれを製作したのが半年以上前なので,いま参考にしたページを慌てて探しましたが,でてきませんでした.すみません.
最後に
これは,私が学生時代の研究室でサクッと作ったものですが,事の発端は節電でした.
 昨年大きな地震があり,おおきな停電もありました.そこで地域全体,学校全体で節電しましょうというようになりましたので,研究室内でも節電できる部分を探しました.
 すると,ずっと画面が点いているタスク管理などが表示されている共有のディスプレイを目にしました.これをみる人は画面の情報を見るためにある程度近く必要があります.
 そこで,画面に近づけば,ディスプレイがONになり,それ以外がOFFになる物を作れば良いとなりました.画面を見るためには必ず顔を画面に向ける必要がありますので,顔を検出すれば良いことになります.
 そして実際に,顔を検出している間ディスプレイがON,それ以外はOFFになるものを作りましたが,ハードウェアとの接続のせいか,時間が経つにつれて処理が重くなってきました.
 結局,このディスプレイONOFF節電作戦は諦めて,今回の無敵になれるやつに繋がったという経緯です.
何が言いたいかというと,課題解決のための手法が飽和したとき,エンタメになる可能性があるということです.
以上.