直線を検出する(確率的Hough変換)

直線を検出する Hough変換には 前回取り上げた『古典的Hough変換』と、その分解能を粗い分解能と細かい分解能を自動的に切り替える『マルチスケールHough変換』、さらに今回取り上げる『確率的Hough変換』の3種類の検出方法があります。
『マルチスケールHough変換』は、Android版でも書きましたが、粗い分解能と細かい分解能との意味あいと実際の効果がいまひとつつかめないこともあり ここでも割愛します。

他のHough変換が 検出した直線と 左上隅からの垂線との交点の位置を、極座標で表現するのに対し、 『確率的Hough変換は検出した直線の始点・終点を直交座標で表現されます。 『確率的Hough変換を行うには、他のHough変換同様 HoughLines2メソッドを使います。
static CvSeq HoughLines2( CvArr image, CvMemStorage line_storage,HoughLinesMethod method,double rho, double theta, int threshold, double param1, double param2)
このメソッドの引数の詳細は前回の記事を参照してください。ただしdouble param1, double param2は次の意味になります。
double param1: 最小の線分長.これより短い線分は棄却されます。
double param2: 2点が同一線分上にあると見なす場合に許容される最大距離。

 コーディング 
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;
        IplImage edge;
        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);
            edge = new IplImage(src.Size, BitDepth.U8, 1);
            Cv.Canny(src, edge, 100, 200, ApertureSize.Size3);
            flg = true;
            pictureBox1.Invalidate();
        }
        private void btnHough_Click(object sender, EventArgs e)
        {
            CvMemStorage storage = new CvMemStorage();
            CvSeq lines = Cv.HoughLines2(edge, storage, HoughLinesMethod.Probabilistic, 1, Math.PI / 180, 50, 100, 10);
            for (int i = 0;i < lines.Total;i++) {
                CvLineSegmentPoint elem = lines.GetSeqElem(i).Value;
                src.Line(elem.P1, elem.P2, CvColor.Red, 1, LineType.AntiAlias, 0);
            }
            lines.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();
            }
        }
    }
}
 処理結果 

元画像

検出した直線 Andoroid版と同じ結果が得られています。

 Windows7 Vs2008 OpenCv2.4 And OpenCvSharp
スポンサーリンク
Rectangle大広告
Rectangle大広告

シェアする

  • このエントリーをはてなブックマークに追加

フォローする