AIにネジを数えさせたら「鳥」と言われた話:YOLOv8リアルタイム物体検出の検証記録
AIにネジを数えさせたら「鳥」と言われた話:YOLOv8リアルタイム物体検出の検証記録
February 19, 2026


AIにネジを数えさせたら「鳥」と言われた話:YOLOv8リアルタイム物体検出の検証記録
カテゴリ:AI / 機械学習 / 技術検証
Xで見た動画が頭から離れない
きっかけはXで流れてきた1本の動画でした。
ベルトコンベアに乗って次々と流れてくるじゃがいも。それをAIがひたすらカウントし続けています。「YOLOv8」という物体検出AIを使ったデモ映像でした。
「これ、自分でも作れるんじゃないか?」
そこから検証がはじまりました。
YOLOv8とは何か
YOLO(You Only Look Once)は、画像・映像内の物体を1回の推論で検出できるリアルタイム物体検出アーキテクチャです。従来の検出手法が「まず物体の候補領域を探してから分類する」という2段階処理だったのに対し、YOLOは画像全体を一度に処理することで高速性と精度を両立しています。
最新のYOLOv8はUltralyticsが開発・公開しており、用途に応じて複数のモデルサイズが用意されています。
モデル | パラメータ数 | 精度(mAP) | 推論速度 | 用途 |
|---|---|---|---|---|
YOLOv8n(nano) | 3.2M | 37.3 | 最速 | 検証・エッジデバイス |
YOLOv8s(small) | 11.2M | 44.9 | 速い | 軽量な本番環境 |
YOLOv8m(medium) | 25.9M | 50.2 | 普通 | バランス重視 |
YOLOv8l(large) | 43.7M | 52.9 | やや遅い | 高精度が必要な場合 |
YOLOv8x(extra) | 68.2M | 53.9 | 遅い | 最高精度 |
今回の検証ではまず動作確認を優先し、最も軽量な**YOLOv8n(nano)**を使用しました。
COCOデータセットとは
YOLOv8nが事前学習に使用しているのが**COCOデータセット(Common Objects in Context)**です。Microsoftが公開した大規模な画像認識用データセットで、以下の特徴があります。
33万枚以上の画像
80種類のクラス(カテゴリ)
各画像に対してバウンディングボックスとクラスラベルが付与されている
80種類の内訳は人・乗り物・動物・食べ物・家具・電子機器・日用品などで、日常生活でよく見かける物体が中心です。工業部品(ネジ・ボルト・基板など)は含まれていません。
環境構築
構成
項目 | 内容 |
|---|---|
OS | macOS(Apple Silicon) |
開発環境 | VS Code + Claude Code |
言語 | Python 3.13.1 |
モデル | YOLOv8n(nano)- yolov8n.pt |
主要ライブラリ | ultralytics 8.4.14、opencv-python 4.13.0 |
仮想環境が必要な理由
macOSでHomebrewを使ってPythonを管理している場合、システム保護のためpipによるグローバルインストールが制限されています(PEP 668)。これを回避するために**Python仮想環境(venv)**を作成します。venvはプロジェクトごとに独立したPython環境を作る仕組みで、ライブラリのバージョン競合も防げます。
# 仮想環境を作成 python3 -m venv venv # 仮想環境を有効化(このターミナルセッション中のみ有効) source venv/bin/activate # ライブラリをインストール
ultralyticsはYOLOv8の本体、opencv-pythonはカメラ映像の取得と画面表示に使います。
実装:リアルタイム物体カウンター
コード全体
import cv2 from ultralytics import YOLO # モデルの読み込み(初回はGitHubから自動ダウンロード、約6MB) model = YOLO("yolov8n.pt") # カメラを起動(0=内蔵カメラ、1以降=外付けカメラ) cap = cv2.VideoCapture(0) while True: ret, frame = cap.read() # 1フレーム取得 if not ret: break # YOLOv8で推論(1フレームごとに実行) results = model(frame) # 検出結果をフレームに描画(バウンディングボックス+ラベル) annotated = results[0].plot() # 種類別カウントを左上に表示 counts = {} for box in results[0].boxes: cls_id = int(box.cls[0]) cls_name = model.names[cls_id] counts[cls_name] = counts.get(cls_name, 0) + 1 y = 30 total = sum(counts.values()) cv2.putText(annotated, f"Total: {total}", (10, y), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2) for name, count in counts.items(): y += 30 cv2.putText(annotated, f"{name}: {count}", (10, y), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 255), 2) cv2.imshow("Object Counter", annotated) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()
信頼度スコア(Confidence Score)の仕組み
各検出結果には0〜1の信頼度スコアが付与されます。これはモデルが「この検出結果にどれだけ確信があるか」を示すソフトマックス出力の値です。
0.8以上:高確信(ブロッコリー 0.84など)
0.5〜0.8:中程度の確信
0.5未満:確信度が低い(誤検出の可能性大)
デフォルトでは信頼度スコアが0.25以上のものだけが画面に表示されます。この閾値はコードで調整可能です。
# 閾値を0.5に上げることで誤検出を減らせる results = model(frame, conf=0.5)
問題発生:ネジが「鳥」になった
試したかったのはネジのカウントです。工場や製造現場でよくある「部品の個数確認」をAIで自動化できないか、というのが元々の目的でした。
さっそくネジをカメラの前に置いて実行。結果は——
bird 0.31
鳥です。ネジが鳥でした。
原因は明快です。YOLOv8nが学習したCOCOデータセットにネジは含まれていないため、モデルが80種類の中から形状が最も近いと判断したクラスを割り当てた結果です。信頼度スコアも0.31と低く、モデル自身も「あまり自信がない」状態でした。
COCOにある物体で動作確認 → スーパーへ買い物
「まずはモデルが知っている物体で正常動作を確認しよう」と方針転換。COCOデータセットの食材クラスに目をつけ、AI検証のためにスーパーへ買い物に行きました。
じゃがいもを見てはじまった話が、スーパーで野菜を買うところまで来るとは思いませんでしたが、これも検証のためです。購入したのはりんご・ブロッコリー・にんじん・レモンの4品。
検証結果


検出精度
物体 | 検出ラベル | 信頼度 | 結果 |
|---|---|---|---|
りんご | apple | 0.52 / 0.31 | ✅ 正検出 |
ブロッコリー | broccoli | 0.84 / 0.82 | ✅ 正検出 |
にんじん | carrot | 0.76 / 0.83 | ✅ 正検出 |
ボトル | bottle | 0.62 | ✅ 正検出 |
人間 | person | 0.87 / 0.26 | ✅ 正検出 |
レモン | orange(誤検出) | 0.78 / 0.66 | ⚠️ 誤検出 |
ネジ | bird(誤検出) | 低 | ❌ 未対応 |
画面表示の例
COCOに含まれる食材は安定して正検出できました。一方、レモンはCOCOに「lemon」クラスが存在しないため、黄色くて丸い形状からorangeと誤検出されました。ネジと同じ原理です。
カスタムモデルを作るには
ネジや特定の工業部品をカウントするには、専用データでの**転移学習(Transfer Learning)**が必要です。YOLOv8nの事前学習済みの重みをベースに、新しいクラスのデータで追加学習させます。
手順
ステップ | 内容 | ポイント |
|---|---|---|
1. データ収集 | 対象物体を撮影 | 最低50〜100枚。様々な角度・照明・背景で撮影するほど精度が上がる |
2. アノテーション | バウンディングボックスを付与 | Roboflow・CVATなどのツールを使用。YOLO形式で書き出す |
3. 学習 | YOLOv8で転移学習 | 下記コマンドを実行 |
4. 評価 | 精度を確認 | mAP・Precision・Recallで評価 |
5. 差し替え | コードに組み込む | best.ptを読み込むだけでOK |
# 学習の実行 yolo train data=screw.yaml model=yolov8n.pt epochs=100 imgsz=640 # 学習済みモデルで推論 model = YOLO("runs/detect/train/weights/best.pt"
精度評価指標
指標 | 説明 |
|---|---|
mAP@0.5 | IoUしきい値0.5でのmAP。精度の基本指標 |
Precision | 検出したうち正解の割合(誤検出が少ないか) |
Recall | 正解のうち検出できた割合(見逃しが少ないか) |
まとめ
Xのじゃがいも動画から着想を得てネジのカウントを試みた結果、スーパーで野菜を買うという予想外の展開になりましたが、YOLOv8の仕組みと限界を実際に体感できた検証になりました。
YOLOv8nはCOCOデータセット80クラスをリアルタイムで検出できる
学習済みクラス外の物体は誤検出される(ネジ→鳥、レモン→オレンジ)
信頼度スコアで検出の確信度を定量的に把握できる
特定物体には転移学習によるカスタムモデルが必要
Claude Codeを活用することで環境構築からコード生成まで大幅に効率化できた
次回はネジのカスタムモデル学習に挑戦します。データ収集・アノテーション・学習・精度評価の過程も引き続き公開予定です。
ご質問・ご意見はお気軽にお問い合わせください。
AIにネジを数えさせたら「鳥」と言われた話:YOLOv8リアルタイム物体検出の検証記録
カテゴリ:AI / 機械学習 / 技術検証
Xで見た動画が頭から離れない
きっかけはXで流れてきた1本の動画でした。
ベルトコンベアに乗って次々と流れてくるじゃがいも。それをAIがひたすらカウントし続けています。「YOLOv8」という物体検出AIを使ったデモ映像でした。
「これ、自分でも作れるんじゃないか?」
そこから検証がはじまりました。
YOLOv8とは何か
YOLO(You Only Look Once)は、画像・映像内の物体を1回の推論で検出できるリアルタイム物体検出アーキテクチャです。従来の検出手法が「まず物体の候補領域を探してから分類する」という2段階処理だったのに対し、YOLOは画像全体を一度に処理することで高速性と精度を両立しています。
最新のYOLOv8はUltralyticsが開発・公開しており、用途に応じて複数のモデルサイズが用意されています。
モデル | パラメータ数 | 精度(mAP) | 推論速度 | 用途 |
|---|---|---|---|---|
YOLOv8n(nano) | 3.2M | 37.3 | 最速 | 検証・エッジデバイス |
YOLOv8s(small) | 11.2M | 44.9 | 速い | 軽量な本番環境 |
YOLOv8m(medium) | 25.9M | 50.2 | 普通 | バランス重視 |
YOLOv8l(large) | 43.7M | 52.9 | やや遅い | 高精度が必要な場合 |
YOLOv8x(extra) | 68.2M | 53.9 | 遅い | 最高精度 |
今回の検証ではまず動作確認を優先し、最も軽量な**YOLOv8n(nano)**を使用しました。
COCOデータセットとは
YOLOv8nが事前学習に使用しているのが**COCOデータセット(Common Objects in Context)**です。Microsoftが公開した大規模な画像認識用データセットで、以下の特徴があります。
33万枚以上の画像
80種類のクラス(カテゴリ)
各画像に対してバウンディングボックスとクラスラベルが付与されている
80種類の内訳は人・乗り物・動物・食べ物・家具・電子機器・日用品などで、日常生活でよく見かける物体が中心です。工業部品(ネジ・ボルト・基板など)は含まれていません。
環境構築
構成
項目 | 内容 |
|---|---|
OS | macOS(Apple Silicon) |
開発環境 | VS Code + Claude Code |
言語 | Python 3.13.1 |
モデル | YOLOv8n(nano)- yolov8n.pt |
主要ライブラリ | ultralytics 8.4.14、opencv-python 4.13.0 |
仮想環境が必要な理由
macOSでHomebrewを使ってPythonを管理している場合、システム保護のためpipによるグローバルインストールが制限されています(PEP 668)。これを回避するために**Python仮想環境(venv)**を作成します。venvはプロジェクトごとに独立したPython環境を作る仕組みで、ライブラリのバージョン競合も防げます。
# 仮想環境を作成 python3 -m venv venv # 仮想環境を有効化(このターミナルセッション中のみ有効) source venv/bin/activate # ライブラリをインストール
ultralyticsはYOLOv8の本体、opencv-pythonはカメラ映像の取得と画面表示に使います。
実装:リアルタイム物体カウンター
コード全体
import cv2 from ultralytics import YOLO # モデルの読み込み(初回はGitHubから自動ダウンロード、約6MB) model = YOLO("yolov8n.pt") # カメラを起動(0=内蔵カメラ、1以降=外付けカメラ) cap = cv2.VideoCapture(0) while True: ret, frame = cap.read() # 1フレーム取得 if not ret: break # YOLOv8で推論(1フレームごとに実行) results = model(frame) # 検出結果をフレームに描画(バウンディングボックス+ラベル) annotated = results[0].plot() # 種類別カウントを左上に表示 counts = {} for box in results[0].boxes: cls_id = int(box.cls[0]) cls_name = model.names[cls_id] counts[cls_name] = counts.get(cls_name, 0) + 1 y = 30 total = sum(counts.values()) cv2.putText(annotated, f"Total: {total}", (10, y), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2) for name, count in counts.items(): y += 30 cv2.putText(annotated, f"{name}: {count}", (10, y), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 255), 2) cv2.imshow("Object Counter", annotated) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()
信頼度スコア(Confidence Score)の仕組み
各検出結果には0〜1の信頼度スコアが付与されます。これはモデルが「この検出結果にどれだけ確信があるか」を示すソフトマックス出力の値です。
0.8以上:高確信(ブロッコリー 0.84など)
0.5〜0.8:中程度の確信
0.5未満:確信度が低い(誤検出の可能性大)
デフォルトでは信頼度スコアが0.25以上のものだけが画面に表示されます。この閾値はコードで調整可能です。
# 閾値を0.5に上げることで誤検出を減らせる results = model(frame, conf=0.5)
問題発生:ネジが「鳥」になった
試したかったのはネジのカウントです。工場や製造現場でよくある「部品の個数確認」をAIで自動化できないか、というのが元々の目的でした。
さっそくネジをカメラの前に置いて実行。結果は——
bird 0.31
鳥です。ネジが鳥でした。
原因は明快です。YOLOv8nが学習したCOCOデータセットにネジは含まれていないため、モデルが80種類の中から形状が最も近いと判断したクラスを割り当てた結果です。信頼度スコアも0.31と低く、モデル自身も「あまり自信がない」状態でした。
COCOにある物体で動作確認 → スーパーへ買い物
「まずはモデルが知っている物体で正常動作を確認しよう」と方針転換。COCOデータセットの食材クラスに目をつけ、AI検証のためにスーパーへ買い物に行きました。
じゃがいもを見てはじまった話が、スーパーで野菜を買うところまで来るとは思いませんでしたが、これも検証のためです。購入したのはりんご・ブロッコリー・にんじん・レモンの4品。
検証結果


検出精度
物体 | 検出ラベル | 信頼度 | 結果 |
|---|---|---|---|
りんご | apple | 0.52 / 0.31 | ✅ 正検出 |
ブロッコリー | broccoli | 0.84 / 0.82 | ✅ 正検出 |
にんじん | carrot | 0.76 / 0.83 | ✅ 正検出 |
ボトル | bottle | 0.62 | ✅ 正検出 |
人間 | person | 0.87 / 0.26 | ✅ 正検出 |
レモン | orange(誤検出) | 0.78 / 0.66 | ⚠️ 誤検出 |
ネジ | bird(誤検出) | 低 | ❌ 未対応 |
画面表示の例
COCOに含まれる食材は安定して正検出できました。一方、レモンはCOCOに「lemon」クラスが存在しないため、黄色くて丸い形状からorangeと誤検出されました。ネジと同じ原理です。
カスタムモデルを作るには
ネジや特定の工業部品をカウントするには、専用データでの**転移学習(Transfer Learning)**が必要です。YOLOv8nの事前学習済みの重みをベースに、新しいクラスのデータで追加学習させます。
手順
ステップ | 内容 | ポイント |
|---|---|---|
1. データ収集 | 対象物体を撮影 | 最低50〜100枚。様々な角度・照明・背景で撮影するほど精度が上がる |
2. アノテーション | バウンディングボックスを付与 | Roboflow・CVATなどのツールを使用。YOLO形式で書き出す |
3. 学習 | YOLOv8で転移学習 | 下記コマンドを実行 |
4. 評価 | 精度を確認 | mAP・Precision・Recallで評価 |
5. 差し替え | コードに組み込む | best.ptを読み込むだけでOK |
# 学習の実行 yolo train data=screw.yaml model=yolov8n.pt epochs=100 imgsz=640 # 学習済みモデルで推論 model = YOLO("runs/detect/train/weights/best.pt"
精度評価指標
指標 | 説明 |
|---|---|
mAP@0.5 | IoUしきい値0.5でのmAP。精度の基本指標 |
Precision | 検出したうち正解の割合(誤検出が少ないか) |
Recall | 正解のうち検出できた割合(見逃しが少ないか) |
まとめ
Xのじゃがいも動画から着想を得てネジのカウントを試みた結果、スーパーで野菜を買うという予想外の展開になりましたが、YOLOv8の仕組みと限界を実際に体感できた検証になりました。
YOLOv8nはCOCOデータセット80クラスをリアルタイムで検出できる
学習済みクラス外の物体は誤検出される(ネジ→鳥、レモン→オレンジ)
信頼度スコアで検出の確信度を定量的に把握できる
特定物体には転移学習によるカスタムモデルが必要
Claude Codeを活用することで環境構築からコード生成まで大幅に効率化できた
次回はネジのカスタムモデル学習に挑戦します。データ収集・アノテーション・学習・精度評価の過程も引き続き公開予定です。
ご質問・ご意見はお気軽にお問い合わせください。
