更新:この StackOverflow の投稿 (いくつかの素敵なサンプル写真が含まれています) は、少なくとも問題の一部である円の検出を解決したようです。彼が指摘している優れた記事の参照は、このwiki ページで見つけることができます(残念ながら、ウェイバック マシンを介してのみ)。
その新しいリンクも保持されない場合は、関連するセクションを次に示します。
画像の検出:
画像内の円を検出するために注意が必要ないくつかの厄介なビットがあります。- 円検出機能で画像を処理する前にcvHoughCircles、まずグレー画像に変換して滑らかにしたい場合があります。以下は、使用する必要がある関数の一般的な手順とその使用例です。
イメージの作成
'img' と呼ばれる処理用の初期画像があると仮定すると、最初に を使用して img と同じ次元で 'gray' と呼ばれる画像変数を作成しますcvCreateImage。
IplImage* gray = cvCreateImage( cvGetSize(img), 8, 1 );
// allocate a 1 channel byte image
CvMemStorage* storage = cvCreateMemStorage(0);
IplImage* cvCreateImage(CvSize size, int depth, int channels);
size: cvSize(width,height);
depth: pixel depth in bits: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U,
IPL_DEPTH_16S, IPL_DEPTH_32S, IPL_DEPTH_32F, IPL_DEPTH_64F
channels: Number of channels per pixel. Can be 1, 2, 3 or 4. The channels
are interleaved. The usual data layout of a color image is
b0 g0 r0 b1 g1 r1 ...
グレーに変換
cvCvtColor次に、色空間間の変換を使用してグレーに変換する必要があります。
cvCvtColor( img, gray, CV_BGR2GRAY );
cvCvtColor(src,dst,code); // src -> dst
code = CV_<X>2<Y>
<X>/<Y> = RGB, BGR, GRAY, HSV, YCrCb, XYZ, Lab, Luv, HLS
e.g.: CV_BGR2GRAY, CV_BGR2HSV, CV_BGR2Lab
滑らかな画像
これは、多くの偽の円が検出されるのを防ぐために行われます。奇数に乗算する必要があることに注意して、最後の 2 つのパラメーターをいじる必要があるかもしれません。
cvSmooth( gray, gray, CV_GAUSSIAN, 9, 9 );
// smooth it, otherwise a lot of false circles may be detected
void cvSmooth( const CvArr* src, CvArr* dst,
int smoothtype=CV_GAUSSIAN,
int param1, int param2);
ソース
dst
滑らかなタイプ
スムージングのタイプ:
- CV_BLUR_NO_SCALE (スケーリングなしの単純なぼかし) - ピクセル param1×param2 近傍の合計。近傍サイズが固定されていない場合は、cvIntegral 関数を使用できます。
- CV_BLUR (単純なぼかし) - 1/(param1•param2) によるスケーリングを伴う、ピクセル param1×param2 近傍の合計。
- CV_GAUSSIAN (ガウスぼかし) - param1×param2 ガウスで画像を畳み込みます。
- CV_MEDIAN (メディアン ブラー) - param1×param1 近傍 (つまり、近傍は正方形) の中央値を見つけます。
- CV_BILATERAL (バイラテラル フィルター) - および を使用してバイラテラル 3x3 フィルタリングを適用します
color sigma=param1。space sigma=param2
パラメータ1
param2
単純なスケーリング/非スケーリングおよびガウス ブラーの場合、param2が 0 の場合、に設定されます。param1
ハフ サークルを使用して検出する
この関数cvHoughCirclesは、グレー イメージ上の円を検出するために使用されます。ここでも、最後の 2 つのパラメーターをいじる必要がある場合があります。
CvSeq* circles =
cvHoughCircles( gray, storage, CV_HOUGH_GRADIENT, 2, gray->height/4, 200, 100 );
CvSeq* cvHoughCircles( CvArr* image, void* circle_storage,
int method, double dp, double min_dist,
double param1=100, double param2=100,
int min_radius=0, int max_radius=0 );
======= 関連セクションの終わり =========
その wiki ページの残りの部分は実際には非常に優れています (ただし、残りの部分は元の質問のトピックから外れており、StackOverflow には回答のサイズ制限があるため、ここでは再コピーしません)。願わくば、 Wayback マシン上のキャッシュされたコピーへのリンクが無期限に機能し続けることを願っています。
私の更新前の前の回答:
すごい!いくつかの例を投稿したので、長方形、正方形の長方形、および円だけでなく、3D 環境でこれらの形状を見つけたいと考えていることがわかります。したがって、ビデオからの平行四辺形と楕円形の特殊なケースを探している可能性があります。フレームからビデオ フレームへの変換は、最終的にそれ自体が長方形、正方形、および/または円であることが明らかになります (カメラのパン方法によって異なります)。
個人的には、既存の (多くの場合、非常に成熟した) ライブラリの使用方法を理解しようとするよりも、自分で問題を解決する方が簡単だと思います。これは、私自身の作品が成熟したライブラリよりも優れていると言っているわけではありません。問題を自分で処理できるようになると、ライブラリを理解し、使用することが容易になります (ライブラリ自体は、多くの場合、自分のソリューションよりもはるかに高速でスマートに実行されます)。
したがって、次のステップは、ビットマップの色空間をグレースケールに変更することです。カラー ビットマップは、理解するのも操作するのも難しいです。特に、表現方法が非常に多いためです。グレースケール ビットマップの場合、各値が異なる光強度を表す値のグリッドを想像してみてください。
そして今のところ、問題の範囲を静的な 2D 環境内で平行四辺形と楕円形を見つけることに限定しましょう (後で 3D 環境の処理とビデオ フレームの移動について心配します。その問題はすでに私にとって複雑になりすぎています)。
また、今のところ、使用するツールや言語について心配する必要はありません。最も簡単で迅速な方法を使用してください。たとえば、時間が問題にならないと仮定して、画像を自動的にグレースケールに変換するスクリプトを作成できます。ImageMagick、Gimp、Marvin、Processing、Python、Ruby、Java など。
そして、これらのツールのいずれかを使用すると、十分に類似した強度を持つピクセルをグループ化し (計算をより管理しやすくするため)、各ピクセル座標を光強度バケットごとに異なる配列に並べ替えることが簡単になるはずです。言い換えれば、各ピクセルの x 位置と y 位置を含む強度で並べ替えられた配列のある種の大まかなヒストグラムを配置することは、それほど難しくないはずです。
その後、問題はこの問題(StackOverflow で見つけることができます) に似た問題になり、提案された解決策に取り組むことができます。
そして、その方法で問題を処理できるようになったら、思いついた解決策をタスクに適したより良い言語に変換することはそれほど難しくありません。また、タスクのために選択した既存のライブラリの基礎となる機能を理解して使用することも、はるかに簡単になるはずです。少なくとも、それが私が望んでいることです。なぜなら、私は十分に精通しておらず、OpenCV ライブラリ自体について実際にお手伝いすることはできないからです。