24
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ゴルフコンペをAIで盛り上げてみた 〜OCI Data Scienceでつくる『AIベストスマイル賞』〜

Last updated at Posted at 2025-10-27

🎯 はじめに

「AIで遊び心あるイベントをやってみたい」
そんな思いつきから始まった、ベストスマイル賞自動採点システム

恒例の社内ゴルフコンペで、参加者全員写真を撮影。
そこからAIが“最もいい笑顔”をスコア化し、自動で表彰スライドを作る。
──そんな試みを OCI Data Science を使って実現しました。

この記事では、

  • なぜこれをやろうと思ったのか(背景)
  • OCI Data Scienceをどう使ったのか
  • 実際に動かしたコード
  • 結果と得られた知見
    をまとめています。

💡 ベストスマイル賞を作った経緯

毎年のコンペで恒例の表彰は「ベスグロ賞」「ドラコン賞」「ニアピン賞」。
そこに「ちょっとAIっぽい賞を加えたい」と考えたのがきっかけです。

  • テーマ:楽しさ × データ × テクノロジー
  • 狙い
    • イベントを盛り上げる
    • AIを“身近で使える技術”として体験してもらう
    • OCI Data Scienceの実践活用を試す

結果、写真から笑顔をスコアリングして、AIが優勝者を決めるというアイデアに着地しました。
AIでベストスマイルを採点する。

ChatGPTなどに代表される出来上がったツールを使うのも良いのですが、万が一に備えて完全ローカルでやろうと。
なにより、、おもしろそう!!


🧠 使用技術とアーキテクチャ

● 使用サービス

サービス 用途
OCI Data Science Notebook環境の構築・実行
TensorFlow / DeepFace 顔検出と笑顔スコア算出
Matplotlib / Pandas スコアの可視化・集計
python-pptx 表彰スライドの自動生成

● 処理の流れ

  1. 各組の集合写真(例:8組×4名=32名)をアップロード
  2. Notebookで一括実行
  3. DeepFaceで顔と感情(特に“happy”)を検出
  4. スコアをCSV出力
  5. 最高スコアを自動判定し、PowerPointに結果を書き出し

OCI DataScienceプロジェクトを作成(OCI側の準備)

プロジェクトを作成する。

プロジェクトの作成を押下

image.png

プロジェクト名を入れて、作成を押下

image.png

NoteBookを作成する

ノートブック・セッションの作成を押下

image.png

シェイプの選択

image.png

NoteBookの中でPip Installやモデルのダウンロードが必要なことと、
8チーム一括分析するためのパワーを確保するので
CPUリソース・NW帯域確保のため、今回は4OCPUとしました。

image.png

入力したら作成

NoteBookを開く

開くを押下

image.png

Karnelを選択する

image.png

今回はPython3(ipkarnel)を選択します。

Create NoteBookを押下

image.png

以下が開いたらOCI DataScienceの準備完了!

image.png

🧩 コード解説(NoteBook上の準備)

1️⃣ セットアップ

!pip install tensorflow==2.15.0 deepface==0.0.93 tf-keras==2.15.1 \
opencv-python-headless==4.11.0.86 matplotlib pandas python-pptx

以下のライブラリの依存関係の警告がでますが今回はスルーします。

ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
oci-cli 3.66.2 requires click==8.0.4, but you have click 8.3.0 which is incompatible.

image.png

また、現在のNoteBookのバージョンだと、cv2を手動インストールする必要があるので、
以下で対策します。

!pip uninstall -y opencv-python opencv-contrib-python opencv-python-headless
!pip install opencv-python-headless==4.11.0.86

実行後、Karnel 再起動

image.png

import cv2
print("✅ OpenCV version:", cv2.__version__)

以下が出ればOK!

✅ OpenCV version: 4.11.0

image.png

最後に写真をアップロードするフォルダ「photo」を作成しておきましょう。

image.png

これで準備完了です!

2️⃣ AI分析とスコア集計


import os, glob, cv2, pandas as pd, matplotlib.pyplot as plt
from deepface import DeepFace
from pptx import Presentation
from pptx.util import Inches, Pt
from pptx.dml.color import RGBColor

# ===== 環境設定 =====
os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3"

PHOTO_DIR = "/home/datascience/photo"
OUTPUT_CSV = os.path.join(PHOTO_DIR, "smile_scores_all.csv")
OUTPUT_PPTX = os.path.join(PHOTO_DIR, "smile_award_overall.pptx")
NAMES = ["Aさん", "Bさん", "Cさん", "Dさん"]

all_results = []

image_files = sorted(glob.glob(f"{PHOTO_DIR}/*.jpeg"))

for image_path in image_files:
    group_name = os.path.splitext(os.path.basename(image_path))[0]
    print(f"\n📸 分析中: {group_name}")

    try:
        detections = DeepFace.extract_faces(
            img_path=image_path,
            detector_backend="retinaface",
            enforce_detection=False
        )
    except Exception as e:
        print(f"⚠️ 顔検出に失敗: {e}")
        continue

    faces_sorted = sorted(detections, key=lambda f: f["facial_area"]["x"], reverse=True)

    for i, face_data in enumerate(faces_sorted[:4]):
        face_img = (face_data["face"] * 255).astype("uint8")
        temp_path = os.path.join(PHOTO_DIR, f"temp_face_{group_name}_{i}.jpg")
        cv2.imwrite(temp_path, cv2.cvtColor(face_img, cv2.COLOR_RGB2BGR))
        area = face_data["facial_area"]["w"] * face_data["facial_area"]["h"]

        try:
            analysis = DeepFace.analyze(
                img_path=temp_path,
                actions=["emotion"],
                detector_backend="retinaface",
                enforce_detection=False
            )
            emotions = analysis[0]["emotion"]
            happy_score = round(emotions.get("happy", 0.0), 2)
        except Exception as e:
            print(f"⚠️ {group_name}{NAMES[i]} の分析に失敗: {e}")
            happy_score = 0.0

        all_results.append({
            "": group_name,
            "名前": f"{group_name}_{NAMES[i]}",
            "笑顔スコア": happy_score,
            "顔面積": area
        })

# ===== 集約・同点対応 =====
summary_df = pd.DataFrame(all_results)
summary_df = summary_df.sort_values(
    by=["笑顔スコア", "顔面積"], ascending=[False, False]
).reset_index(drop=True)

top_score = summary_df.iloc[0]["笑顔スコア"]
tied = summary_df[summary_df["笑顔スコア"] == top_score]

if len(tied) > 1:
    winner = tied.sort_values(by="顔面積", ascending=False).iloc[0]
    print(f"🤝 同点ですが、顔面積が広い {winner['名前']} さんを総合優勝に決定!({winner['笑顔スコア']}点)")
else:
    winner = summary_df.iloc[0]
    print(f"🏆 総合ベストスマイル賞:{winner['名前']} さん!({winner['笑顔スコア']}点)")

plt.figure(figsize=(10,6))
plt.bar(summary_df["名前"], summary_df["笑顔スコア"], color="orange")
plt.title("総合ベストスマイルスコアランキング(全8組32名)", fontsize=14)
plt.ylabel("笑顔スコア(happy%)")
plt.xticks(rotation=45, ha="right")
plt.tight_layout()
plt.show()

summary_df.to_csv(OUTPUT_CSV, index=False, encoding="utf-8-sig")
print(f"\n✅ すべての結果を保存しました: {OUTPUT_CSV}")

prs = Presentation()
slide_layout = prs.slide_layouts[5]
slide = prs.slides.add_slide(slide_layout)
title = slide.shapes.title
title.text = "🏆 総合ベストスマイル賞発表"

p = slide.shapes.add_textbox(Inches(1), Inches(2), Inches(8), Inches(2))
tf = p.text_frame
tf.text = f"総合優勝:{winner['名前']} さん\n笑顔スコア:{winner['笑顔スコア']}"
tf.paragraphs[0].font.size = Pt(28)
tf.paragraphs[0].font.bold = True
tf.paragraphs[0].font.color.rgb = RGBColor(255, 140, 0)

prs.save(OUTPUT_PPTX)
print(f"🎉 総合表彰スライドを保存しました: {OUTPUT_PPTX}")

セットアップが完了し、コードが用意できたら画像をphotoフォルダにアップして準備完了です。

image.png

📈 結果と反応

実際に出力されたスコアランキング👇

今回は、NoteBook上で結果をグラフで可視化する仕組みと、スコアを把握するために分析結果をCSV出力するようにしました!

グラフから高得点者が多いことがわかります。素敵です☺️

image.png

詳細なスコアの確認のためCSVの中身を確認します。

image.png

100点満点の方が4名いらっしゃいますが、今回は同点だった場合を考慮して
笑顔の面積が広い方に加点するような仕組みを実装しています。

優勝は OUT_Team3のDさんでした!ベストスマイル賞おめでとうございます!

PPTスライドも自動生成され、
表彰式では「AIが決めたスマイル賞」として大盛り上がり!


🗣️ 所感と学び

  • OCI Data Scienceはセットアップが簡単で、数分で動作環境が整う
  • DeepFaceは軽量で精度も高く、笑顔スコア用途には最適
  • AI活用は「業務効率化」だけでなく「体験を豊かにするツール」にも使える

特に印象的だったのは、

“AIが自分の笑顔を採点してくれる”
という仕掛けが、参加者全員の関心を引き、
AI=身近で楽しいもの として浸透したことです。


🚀 まとめ

観点 ポイント
技術的要素 DeepFace(感情分類)+ TensorFlow
インフラ OCI Data Science + Object Storage
成果物 CSVランキング + PowerPoint自動生成
成果 AI表彰で社内イベントを盛り上げた 🎉

🔗 次の展開

次は「ベストドレッサー賞」もAIで判定予定。
服の色彩・コントラスト・明度をスコア化して、
“最もスタイリッシュな人”を選ぶAIを構築中です。

OCIの機能で簡単にAIの取り組みが実装できました。
他のユースケースも実装可能と思います。

ぜひ実践のご参考にしていただければと思います!

24
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
24
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?