円を検出するメソッドは 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内のみに表示できますでしょうか。
よろしくご教示願います。