EMGU CV实时使用C#进行眼动追踪

时间:2015-01-30 09:18:21

标签: c# opencv emgucv face-detection eye-tracking

我正在关注youtube上的Luca Del Tongo教程,以便从脸部追踪眼睛。我设法使用矩形,但我想使用HoughCircle跟踪它。 https://www.youtube.com/watch?v=07QAhRJmcKQ

我正在使用以下代码来跟踪我的眼睛,并在我的眼睛周围创建了多个圆圈。 enter image description here 我只是将图像转换为灰度,正如他在教程中告诉我们的那样。你能帮忙吗?我是EMGU CV的新手

grayFrame.ROI = possibleROI_leftEye;
                MCvAvgComp[][] leftEyesDetected = grayFrame.DetectHaarCascade(_eyes, 1.15, 0, Emgu.CV.CvEnum.HAAR_DETECTION_TYPE.DO_CANNY_PRUNING, new Size(20, 20));
                grayFrame.ROI = Rectangle.Empty;

                grayFrame.ROI = possibleROI_rightEye;
                MCvAvgComp[][] rightEyesDetected = grayFrame.DetectHaarCascade(_eyes, 1.15, 0, Emgu.CV.CvEnum.HAAR_DETECTION_TYPE.DO_CANNY_PRUNING, new Size(20, 20));
                grayFrame.ROI = Rectangle.Empty;

                //If we are able to find eyes inside the possible face, it should be a face, maybe we find also a couple of eyes
                if (leftEyesDetected[0].Length != 0 && rightEyesDetected[0].Length != 0)
                {
                    //draw the face
                    frame.Draw(face.rect, new Bgr(Color.Violet), 2);


                    #region Hough Circles Eye Detection

                    grayFrame.ROI = possibleROI_leftEye;
                    CircleF[] leftEyecircles = grayFrame.HoughCircles(new Gray(180), new Gray(70), 5.0, 10.0, 1, 200)[0];
                    grayFrame.ROI = Rectangle.Empty;
                    foreach (CircleF circle in leftEyecircles)
                    {
                        float x = circle.Center.X + startingLeftEyePointOptimized.X;
                        float y = circle.Center.Y + startingLeftEyePointOptimized.Y;
                        frame.Draw(new CircleF(new PointF(x, y), circle.Radius), new Bgr(Color.RoyalBlue), 4);
                    }

                    grayFrame.ROI = possibleROI_rightEye;
                    CircleF[] rightEyecircles = grayFrame.HoughCircles(new Gray(180), new Gray(70), 2.0, 20.0, 1, 5)[0];
                    grayFrame.ROI = Rectangle.Empty;

                    foreach (CircleF circle in rightEyecircles)
                    {
                        float x = circle.Center.X + startingPointSearchEyes.X;
                        float y = circle.Center.Y + startingPointSearchEyes.Y;
                        frame.Draw(new CircleF(new PointF(x, y), circle.Radius), new Bgr(Color.RoyalBlue), 4);
                    }

                    #endregion

现在我改变了找到眼睛的部分

 grayImageFrame.ROI = possibleROI_leftEye;
                CircleF[] leftEyecircles = grayImageFrame.HoughCircles(new Gray(180), new Gray(70), 5.0, 10.0, 1, 20)[0];
                if (leftEyecircles.Length > 0)
                {
                    CircleF firstCircle = leftEyecircles[0]; // Pick first circle in list
                    float x = firstCircle.Center.X + startingPointSearchEyes.X;
                    float y = firstCircle.Center.Y + startingPointSearchEyes.Y;
                    ImageFrame.Draw(new CircleF(new PointF(x, y), firstCircle.Radius), new Bgr(Color.RoyalBlue), 4);
                }
                grayImageFrame.ROI = possibleROI_rightEye;
                CircleF[] rightEyecircles = grayImageFrame.HoughCircles(new Gray(180), new Gray(70), 5.0, 10.0, 1, 20)[0];
                grayImageFrame.ROI = Rectangle.Empty;

                if (rightEyecircles.Length > 0)
                {
                    CircleF firstCircle = rightEyecircles[0]; // Pick first circle in list
                    float x = firstCircle.Center.X + startingPointSearchEyes.X;
                    float y = firstCircle.Center.Y + startingPointSearchEyes.Y;
                    ImageFrame.Draw(new CircleF(new PointF(x, y), firstCircle.Radius), new Bgr(Color.RoyalBlue), 4);
                }

只显示一个圆圈,但它跟踪的是眼睛周围的部分,而不是我的眼睛:(

enter image description here

3 个答案:

答案 0 :(得分:0)

您获得多个圈子的原因仅仅是因为您使用此for循环绘制所有找到的圈子

foreach (CircleF circle in rightEyecircles)
{
    float x = circle.Center.X + startingPointSearchEyes.X;
    float y = circle.Center.Y + startingPointSearchEyes.Y;
    frame.Draw(new CircleF(new PointF(x, y), circle.Radius), new Bgr(Color.RoyalBlue), 4);
}

要仅绘制一个圆,您必须从列表中选择一个圆(或者可能是由多个圆形成的复合估计)并仅绘制该圆。

我不是真正的C#家伙,但我猜这样的事情会起作用

CircleF firstCircle = rightEyecircles[0]; // Pick first circle in list
float x = firstCircle.Center.X + startingPointSearchEyes.X;
float y = firstCircle.Center.Y + startingPointSearchEyes.Y;
frame.Draw(new CircleF(new PointF(x, y), firstCircle.Radius), new Bgr(Color.RoyalBlue), 4);

答案 1 :(得分:0)

与Hannes不同,我认为可以使用图像处理方法来删除您收到的检测数量,而不是仅仅绘制一个找到的圆圈。

  1. 应用高斯模糊来减少噪音并避免假圆检测:

    GaussianBlur(src_gray,src_gray,Size(9,9),2,2);

  2. 将最小/最大圆半径应用于Hough变换

    min_radius = 0:要检测的最小无线电。如果未知,则默认为零。

    max_radius = 0:要检测的最大半径。如果未知,则默认为零

答案 2 :(得分:0)

为了检测特定区域中的一只眼球,执行以下任务

* 1-使用haarcascade检测眼睛并选择该眼睛的ROI并检测那里的hough圈。

2-转换为灰色图像

3-图像阈值*

 grayFrame._ThresholdBinary(new Gray(33), new Gray(255));

4- 现在从霍夫圈中找到眼球。

快乐的编码。