円を検出するメソッドは HoughCirclesになります。
CvSeq HoughCircles(CvArr image,CvMemStorage circle_storage,
HoughCirclesMethod method,double dp,double min_dist,double param1,double param2,
int min_radius,int max_radius)
CvArr image : 8ビット,シングルチャンネル,グレースケールの入力画像。
直線の検出は 2値化画像を入力にしますが 円の検出は グレースケール画像を入力にし 内部で2値化(Canny)を行います。
CvMemStorage circle_storage : 作業用領域
HoughCirclesMethod method : 2値化手法 現在のところ, Gradient メソッドのみが実装されています。
double dp : 画像分解能に対する投票分解能の比率の逆数。
例えば, dp=1 の場合は,投票空間は入力画像と同じ分解能をもち 処理は重くなります。
また dp=2 の場合は,投票空間の幅と高さは半分になります。
double min_dist: 検出される円の中心同士の最小距離。
このパラメータが小さすぎると,正しい円の周辺に別の円が複数誤って検出されることになります。
逆に大きすぎると,検出できない円がでてくる可能性があります。
double param1 : 2値化手法ごとに指定するパラメータの 1 番目。
Canny() エッジ検出に渡される2つの閾値の内,大きい方の閾値を表します。(小さい閾値は,この値の半分になります)。
double param2 : 2値化手法ごとに指定するパラメータの 2 番目。
円の中心を検出する際の投票数の閾値を表します。
これが小さくなるほど,より多くの誤検出が起こる可能性があります。より多くの投票を獲得した円が,最初に出力されます。
int minRadius : 円の半径の最小値。
int maxRadius : 円の半径の最大値。
コーディング |
Android版と同じデータ 同じ引数で実験しました。
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using OpenCvSharp; namespace OpenCvShp { public partial class Form1 : Form { private IplImage src; private Boolean flg = false; public Form1() { InitializeComponent(); } //初期処理(画像データ読み込み・表示) private void timer1_Tick(object sender, EventArgs e) { timer1.Enabled = false; src = new IplImage(@"C:\OpenCvTest\Data\a640_480.jpg", LoadMode.Color); flg = true; pictureBox1.Invalidate(); } private void btnHough_Click(object sender, EventArgs e) { CvMemStorage storage = new CvMemStorage(); IplImage gray = new IplImage(src.Size, BitDepth.U8, 1); Cv.CvtColor(src, gray, ColorConversion.BgrToGray); CvSeq circl = Cv.HoughCircles(gray, storage, HoughCirclesMethod.Gradient, 2, 10, 160, 50, 10, 20); foreach (CvCircleSegment crcl in circl) { src.Circle(crcl.Center, (int)crcl.Radius, CvColor.Red, 2); } circl.Dispose(); storage.Dispose(); pictureBox1.Invalidate(); } //描画処理 private void pictureBox1_Paint(object sender, PaintEventArgs e) { if (flg) { Bitmap bmp = new Bitmap(src.Width, src.Height); bmp = src.ToBitmap(); e.Graphics.DrawImage(bmp, 0, 0, bmp.Width, bmp.Height); bmp.Dispose(); } } } }
処理結果 |
円検出結果
Android版の結果と比較すると 同じ引数を使いましたが 誤検出がひとつ減っています。
Windows7 Vs2008 OpenCv2.4 And OpenCvSharp |
コメント
OpenCvSharp.CvSeqでのエラー
「OpenCv Sharp 実験記」は、OpenCvSharpでのプログラム開発において、非常に助かっております。
その中の「円を検出する」についてなのですが、参考プログラムをビルドすると、
「foreach ステートメントは、’OpenCvSharp.CvSeq’ が ‘GetEnumerator’ のパブリック定義を含んでいないため、型 ‘OpenCvSharp.CvSeq’ の変数に対して使用できません。」
というエラーメッセージが出てしまいます。
これは解決する方法をお教えいただけませんでしょうか?
開発環境は
Windous7+VisualStudio2008+OpenCV231
です。
宜しくお願いいたします。
OpenCvSharp.CvSeqでのエラー
試行錯誤しながら進めた 拙い実験記を参考にしていただき お恥ずかしい限りです。
実験を行った際に 参考にしたページは https://opencvsharp.googlecode.com/svn-history/r33773/trunk/2.2/OpenCvSharp.Test/Samples/HoughCircles.cs
です。ここでは Cv.HoughCirclesの戻り値を型指定付きのリストで受けているようです。
完全に自分と同じ環境で ビルドエラーになったとのこと、確実な回答か否かは自信がありませんが、この方法を試されたらいかがでしょうか。
pictureBox内のみに表示
初心者です。
Cv.AdaptiveThreshold(img, binaryAdaptive, 255, AdaptiveThresholdType.GaussianC, ThresholdType.Binary, 9, 12);
CvWindow.ShowImages(img, binaryAdaptive);
で二値化された画像は表示されるのですが、
form1内の
pictureBoxIpl5.ImageIpl=img; には二値化された画像が表示できません。
どのようにすればpictureBox内のみに表示できますでしょうか。
よろしくご教示願います。