工作好きな情報系の雑記

[OpenCV]円の検出はハフ変換より最小外接円がいいぞ

(2026/01/02 デモの映像を追加し、ボール検出用のコードを更新) 

赤いボールを検出しようとした話。

巷ではハフ変換を使った方法がある。
これ説明するのは難しいけど、この辺がわかりやすいかな。↓↓

でも、ハフ変換は処理が重い上に精度が悪い。なーんかもたつくし、できたとしても検出された円の大きさが安定しない。

なんだかなぁと思っていると、経験ある友達が「最小外接円を使った方がいい」と教えてくれた。
実際使ってみたところ、はるかに精度いい(厳密には違うが)しスムーズだった。
「精度がいい」というよりは、円を検出してるわけじゃないから認識が簡単になっていて、精度よく検出できているように感じる、と言った方が正確かな。

デモとして、ハフ変換と最小外接円それぞれで赤いボールの検出の比較をしてみた。

まずハフ変換の方。滅多に円が検出されない上に、検出されても円のサイズがめちゃめちゃに暴れる。
円の大きさで距離を推定したい場合なんかは致命的になる。

続いて最小外接円を使った方式。
基本的にずっとボールが適切に検出されているし、大きさもほぼ狂わない。ボールのブレにも追随できている。
悪くないでしょう?

もちろんハフ変換が最適な場合もあると思うけど、今回は赤いボール1つだけ検出できればよかったから、最小外接円方式で十分快適だった。

検証に使ったコード例を下に置いておく。(検証当時のOpenCVのバージョンは4.12.0)
例えば下記をdetect_red_ball.pyと保存して"python detect_red_ball.py -m -c"とすると、カメラからの映像を元に最小外接円方式で赤い円検出を行う。

みんな、最小外接円、使おうぜ!

輪郭に関するチュートリアル OpenCVにおける輪郭(領域) — OpenCV-Python Tutorials 1 documentation 輪郭抽出 OpenCVの輪郭検出は,黒い背景から白い物体の輪郭を検出すると仮定しています.物体は白(明るい色),背景は黒(暗い色)と覚えておいてください. とある。 cv2.findContours 輪郭抽出と、その輪郭に対する処理を人多りやてみる。 void findContours(const Mat& image, vector& contours, int mode, int method, Point off…
opencv チュートリアルチャレンジ9 OpenCVにおける輪郭(領域) - 機械学習備忘録 - 機械学習備忘録
モバイルバージョンを終了