物体検出

ロボットが「何が・どこに」を知る

大阪大学 中島優作

← シリーズ一覧に戻る

カメラを使うと、まず物体検出

カメラ画像 物体検出 何が・どこに・いくつ 取りに行く(ピッキング) 見つけた位置へ手を伸ばしてつかむ 合わせに行く(ビジョンFB) 検出した位置とのずれを毎回直す 数える・調べる 在庫・検査・人の見守り

ほとんどの応用は「物体を見つけた」が前提。検出がこけると後ろが全部こける

分類・検出・セグメンテーション

「コップがある」 分類 画像全体に 1 つのラベル cup 0.92 box 0.88 物体検出 物体ごとに 箱+ラベル+確信度 セグメンテーション 画素ごとにどの物体か(形まで)

ロボットではまず検出(箱)。つかみ方まで考えるなら形が分かるセグメンテーション

画像の箱から、ロボットの座標へ

箱の中心 (u, v) 画素の位置 + 深度 Z デプスカメラ・ステレオ カメラ座標 (X, Y, Z) 内部パラメータで変換 ロボット座標 外部パラメータ・TF X = (u − cx) Z / fx, Y = (v − cy) Z / fy
  • 検出が出すのは画像上の箱だけ。つかむには 3 次元の位置が要る
  • キャリブレーション(内部・外部パラメータ)がずれると、検出が正しくても手が届かない

キャリブレーションはカメラ/デプスカメラのスライドを参照

前処理が性能を決める

撮影 前処理 ここで勝負が決まる 検出モデル 後処理 撮影条件をそろえるのも、広い意味での前処理
  • 深層学習なら「そのまま突っ込めば動く」こともある。でも性能は前処理で大きく変わる
  • モデルは学習で見た画像に似た画像しか得意でない(明るさ・色・大きさ・向き)
  • 前処理の役目は、実際の画像を学習時の画像に近づけること

いちばん効くのは撮影条件

ありがちな失敗
  • 窓の光で朝と夕方で色が違う
  • 自動露出・自動ホワイトバランスで、フレームごとに明るさ・色が揺れる
  • 金属・ガラスの映り込み、ロボット自身の影
  • カメラが振動・ピンぼけ
対策
  • 照明を足して外光に負けない(拡散光で影を減らす)
  • 露出・WB・ピントを固定値にする
  • 背景を物体と違う色の無地にする
  • カメラをしっかり固定する

画像を後から直すより、撮る前にそろえる方がずっと安くて確実

よく使う前処理

処理何をする効く場面
歪み補正レンズの歪みを内部パラメータで戻す広角カメラ、画像の端の物体の位置
ROI 切り出し作業台など見る場所だけ切り出す小さい物体、関係ない物の誤検出
リサイズモデルの入力サイズ(例 640)へ。縦横比を保って余白を足す(レターボックス)必須。つぶすと形が変わる
色の変換BGR ↔ RGB、HSV(色と明るさを分ける)色で判定、モデルの入力順
明るさ・色の補正ガンマ補正、CLAHE、ホワイトバランス暗い・明暗差が大きい・色かぶり
平滑化ガウシアン・メディアンフィルタノイズが多い(暗所・高感度)
正規化画素値を 0〜1 などにそろえるモデルの入力(多くはライブラリが自動)

試してみる:前処理で検出結果が変わる

「暗い部屋+電球色」を押して、前処理を 1 つずつ足してみよう。1 つだけでは足りないことも多い

OpenCV で書くと


import cv2

img = cv2.imread("table.png")                 # OpenCV は BGR の順で読む
img = cv2.undistort(img, K, dist)             # 歪み補正(K, dist はキャリブレーション結果)
roi = img[200:680, 300:1100]                  # 作業台だけ切り出す

lab = cv2.cvtColor(roi, cv2.COLOR_BGR2LAB)    # 明るさ L だけを補正する
l, a, b = cv2.split(lab)
l = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8)).apply(l)
roi = cv2.cvtColor(cv2.merge((l, a, b)), cv2.COLOR_LAB2BGR)

roi = cv2.GaussianBlur(roi, (5, 5), 0)        # ノイズを均す
rgb = cv2.cvtColor(roi, cv2.COLOR_BGR2RGB)    # モデルが RGB を期待するなら変換
                    

色だけ・明るさだけを触れるよう、色空間を変えてから処理するのが定石

前処理のハマりどころ

  • BGR と RGB の取り違え:赤と青が入れ替わっても動いてしまい、気づきにくい
  • 縮めすぎ:4K 画像を 640 にすると小さい部品は数画素 → 見えなくなる(ROI 切り出しやタイル分割)
  • 学習時と推論時で前処理が違う:同じ処理を同じ順で通す
  • 補正しすぎ:強い補正は学習データにない見た目を作る
  • 処理が重い:前処理だけでフレームレートが落ちていないか測る

YOLO:一度見るだけで検出

2 段階型(R-CNN 系) 画像 ① 候補の 場所を出す ② 候補ごとに 分類 正確だが遅い(候補の数だけ計算) 1 段階型(YOLO) 各マスが 箱・クラス・ 確信度を一度に 1 回のネットワーク計算で全部出す → 速い
  • You Only Look Once(2016)。画像をマス目に分け、全マスの答えを同時に出す
  • 動画でもリアルタイムに動くので、ロボットで定番になった

従来の YOLO の後処理:NMS

1 つの物体に箱がたくさん NMS 確信度の高い箱を残し 重なる箱を消す cup 0.92 1 物体に 1 つの箱
  • NMS(Non-Maximum Suppression)はネットワークの外で行う別の処理
  • 物体が多いと遅くなり、時間が読めない。エッジ機器への書き出しも面倒
  • しきい値(どれだけ重なったら消すか)の調整も必要

最新の YOLO:NMS が要らない

従来 ネットワーク 箱が何千個 NMS 結果 最新 ネットワーク 1 物体に 1 つだけ出すよう学習(one-to-one) 結果 エンドツーエンド:入力から結果まで 1 つのネットワーク
  • YOLOv10(2024、清華大)が NMS 不要の学習方法を導入
  • YOLO26(Ultralytics、2026 年 1 月):NMS 不要を標準にし、CPU・エッジ機器向けに軽量化
  • Ultralytics の発表では、最小モデルの CPU 推論が YOLO11 より最大 43% 高速
  • ロボットに載せる小型 PC(Jetson など)で速さと時間の読みやすさが効く

Wang et al., YOLOv10: Real-Time End-to-End Object Detection, NeurIPS 2024 / Ultralytics YOLO26

YOLO の歩み

201620182020 2022202320242026 YOLOv11 段階で検出 YOLOv3定番化 v4 / v5v5 で PyTorch 化 YOLOv7 YOLOv8検出・セグメ・姿勢 YOLOv10NMS 不要 YOLO11 YOLO26 NMS 不要・エッジ向け 作者・開発元はバージョンごとにバラバラ(番号が大きい=同じ系列の後継、とは限らない) 実用では Ultralytics 版(v5 / v8 / 11 / 26)が使いやすく、情報も多い

使ってみる(Ultralytics)


# pip install ultralytics
from ultralytics import YOLO

model = YOLO("yolo26n.pt")            # n=最小。s/m/l/x と大きくなるほど高精度・低速
results = model("table.jpg")          # 画像・動画・カメラ番号を渡せる

for box in results[0].boxes:
    name = model.names[int(box.cls)]  # クラス名(COCO の 80 クラス)
    print(name, float(box.conf), box.xyxy.tolist())

# 自分の物体で追加学習(ファインチューニング)
model.train(data="my_objects.yaml", epochs=100, imgsz=640)
                    
  • リサイズ・正規化などモデル用の前処理はライブラリが自動。撮影条件・ROI・色補正は自分の仕事
  • ライセンスは AGPL-3.0(製品に組み込むなら商用ライセンスを確認)

学習していない物は見つけられない

普通の YOLO
  • COCO の80 クラス(人・コップ・瓶…)だけ
  • 実験器具・部品など自分の物は追加学習が必要
  • そのぶん速くて確実
オープンボキャブラリ
  • 言葉で探す物を指定(「赤いマグカップ」)
  • Grounding DINO、YOLO-World、YOLOE など
  • 学習なしで使えるが、重い・確実さは劣る

決まった物は追加学習した YOLO、初めて見る物はオープンボキャブラリ、と使い分け

ROS で使う

カメラノード RealSense など カラー+深度 前処理ノード 歪み補正(image_proc) ROI・色補正 YOLO ノード 2D 検出 + 深度 → 3D 検出 TF で変換 ロボット座標の位置 → MoveIt で把持 結果は RViz に重ねて表示できる(検出画像・3D の箱)
  • yolo_ros(ROS 2):Ultralytics の YOLO26 まで対応。深度画像から3D 検出、追跡も出せる
  • Isaac ROS(NVIDIA):Jetson の GPU で高速に推論

ros2 launch yolo_bringup yolo.launch.py
                

▶ yolo_ros ▶ Isaac ROS

応用例:RoboCup@Home

  • 家の中で人の手伝いをするロボットの競技会(RoboCup の 1 部門、2006 年〜)
  • 部屋のどこかにある物を見つけて持ってくる、テーブルを片付ける、食料品を棚にしまう
  • トヨタの生活支援ロボット HSR を全チーム共通で使うリーグ(DSPL)もある
  • どの課題も、まず物体検出から始まる
「コップを取って」 物体検出 深度で 3D 位置 近づいてつかむ 人に渡す

▶ RoboCup@Home 公式

難しさ:物は大会で初めて知らされる

  • 使う物(食品・食器・日用品)は大会会場で発表される
  • 数日のうちに写真を撮る → ラベルを付ける → 学習まで終わらせる
  • 会場の照明・家具は練習環境と違う → 前処理とデータの多様さが効く
  • ロボットに載せた PC で動かすので軽くて速い YOLOが定番

短時間で「自分の物」を検出できるようにするデータづくりが勝負

例:Hibikino-Musashi@Home

九州工業大学などの合同チーム

物を 3D スキャン LiDAR 付きスマホ シミュレータで合成 照明・家具・背景をばらつかせる ラベルは自動 50 万枚を 2 時間以内 YOLOv8 を学習 TensorRT で高速化 人がラベルを付ける作業がゼロ → 新しい物にすぐ対応
  • HSR を使う日本の強豪チーム。RoboCup 2024(アイントホーフェン)DSPL で 1 位
  • YOLO で足りない物は Grounding DINO(言葉で検出)と物ごとに使い分け
  • 「カウンターの一番右の物を持ってきて」→ LLM が探す・つかむ・運ぶに分解

Hibikino-Musashi@Home 2025 Team Description Paper, arXiv:2511.20180

まとめ

  • 物体検出は、ピッキングもビジョンフィードバックも支える土台
  • 性能は前処理で大きく変わる。まず撮影条件をそろえる
  • YOLO は一度見るだけで検出。最新の YOLO26 は NMS 不要でエッジでも速い
  • ROS では yolo_ros で検出 → 深度で 3D → TF でロボット座標へ
  • RoboCup@Home のように、自分の物を短時間で学習させるデータづくりが実践の鍵

次は、検出した物体に合わせに行くビジョンフィードバック制御へ

← シリーズ一覧に戻る

参考資料