使用 EMGU 识别相当简单的形状

Identify fairly simple shapes with EMGU

我正在尝试识别 "T" 形状以及可以反转的 "L" 形状,如下所示。我在 C# 中使用 EMGU。

形状:T

形状:L(常规)

形状:L(反转)

我试图始终如一地检测这些不同的形状,并且我尝试使用 the EMGU shape detection tutorial 中所示的轮廓方法。问题是它没有正确检测到轮廓点,或者偶尔检测到,但不可靠。

轮廓逻辑输出

这些形状大部分相同,但可以旋转或具有略微不同的视角。什么是一致地检测这些不同形状的准确、有效的方法?

谢谢!

我已经用你给定的图像尝试了我的算法,结果和代码如下。我已经使用阈值和 findcontours 函数来检测你的身材。

以下是查找精确轮廓的代码。一旦找到轮廓,我们就可以计算它的长度或简单地存储它的大小。相同的轮廓将始终具有相同的大小或长度(大约),无论是在任何方向。

Mat original_image = new Mat();
Mat gray = new Mat();
Mat threshold_image = new Mat();
VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
Mat new_image = new Mat();
Mat con = new Mat();

//TrackBar Scroll
    private void trackBarLow_Scroll(object sender, EventArgs e)
    {
        try
        {
            low = trackBarLow.Value;
            threshold_value = trackBarThreshold.Value;
            CvInvoke.CvtColor(original_image, gray, ColorConversion.Bgr2Gray, 0);
            CvInvoke.Threshold(gray, threshold_image, low, threshold_value, ThresholdType.Binary);
            Image<Bgr, Byte> threshold_I = threshold_image.ToImage<Bgr, Byte>();
            pictureBox2.Image = threshold_I.ToBitmap();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString());
        }
     }

     private void buttonExactContours_Click(object sender, EventArgs e)
     {
        try
        {
            new_image = new Mat(new System.Drawing.Size(640, 480), DepthType.Cv16S, 3);
            new_image.SetTo(new Emgu.CV.Structure.MCvScalar(150, 0, 150));
            con = threshold_image;

            Image<Bgr, Byte> new_image1_I = new_image.ToImage<Bgr, Byte>();
            pictureBox3.Image = new_image1_I.ToBitmap();

            CvInvoke.FindContours(con, contours, null, RetrType.Ccomp, ChainApproxMethod.ChainApproxSimple, new Point(0, 0));

            IInputArrayOfArrays arr;

            for (int j = 0; j < contours.Size; j++)
            {
                arr = contours[j];

                //textBox1.AppendText(Environment.NewLine + CvInvoke.ArcLength(arr, true).ToString() + Environment.NewLine);
                textBox1.AppendText(Environment.NewLine + contours[j].Size.ToString() + Environment.NewLine);
                if (contours[j].Size < 500) //Value "500" may vary according to the size you may want to filter
                    continue;
            }
            Image<Bgr, Byte> new_image_I = new_image.ToImage<Bgr, Byte>();
            pictureBox2.Image = new_image_I.ToBitmap();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString());
        }

    }