Как создать вращающуюся ограничивающую область при использовании Capture в EmguCv? - PullRequest
2 голосов
/ 03 декабря 2011

Моя проблема заключается в следующем:

Используя EmguCv (C # OpenCV), мне нужно написать приложение, которое может определять, вращается ли моя фигура или нет, используя веб-камеру на моем компьютере. Я использовал Capture для захвата кадров с моей веб-камеры. Также я «очистил» каждый кадр с помощью фильтров SmoothGausian и Canny. Благодаря этому все, что видит камера, - это моя фигура, которую я нарисовал на листе бумаги. Я проверил момент hu1 моей фигуры и при проверке контуров в моем кадре я выбираю только те, которые имеют hu1 момент. И теперь это самая сложная часть. Пока я начинаю вращать свой лист бумаги, я хочу посчитать угол этого вращения. Я понял, что могу использовать ограничивающую область, которая является квадратом, который окружает найденный контур, и я мог рассчитать угол между линиями (предыдущей и настоящей) между двумя точками этой области. К сожалению, эта ограничивающая область не вращается, и теперь я прошу вас, ребята, о помощи :) Кто-нибудь знает, как решить эту проблему :)?

Извините за такой роман, но я хотел подробно описать мою проблему. Кроме того, я приложил часть моего кода, где происходит весь этот рисунок и захватывающая рамка.

//img - filtrated rame from a camera
var tmp = img.Convert<Gray, byte>().FindContours();

for (; tmp.HNext != null; tmp = tmp.HNext)
{
    if(tmp.GetMoments().GetHuMoment().hu1 > 0.325 && tmp.GetMoments().GetHuMoment().hu1 < 0.34)
    //if (tmp.GetMoments().GetHuMoment().hu1 > 0.33 && tmp.GetMoments().GetHuMoment().hu1 < 0.335)
    {
        var color1 = new Bgra(0, 255, 0, 255);
        drawImg.Draw(tmp, color1, 2);

        int left = tmp.BoundingRectangle.Left;
        int top = tmp.BoundingRectangle.Top;
        int right = tmp.BoundingRectangle.Right;

        Point[] line2 = { new Point(left, top), new Point(right, top) };
        drawImg.DrawPolyline(line2, false, new Bgra(255, 0, 0, 255), 1); 

        plik.WriteLine(left + "\t" + top);

        Point[] tab = tmp.ToArray();

        Point[] pointy = {tab[0], new Point( (int)tmp.GetMoments().GravityCenter.x, (int)tmp.GetMoments().GravityCenter.y )};

        Console.WriteLine(tab[0].ToString());

        drawImg.DrawPolyline(pointy, false, new Bgra(0, 0, 255, 255), 2);
    }
}

Ответы [ 2 ]

0 голосов
/ 04 декабря 2011

Чтобы рассчитать поворот между контрольной цифрой и цифрой, которую вы приобретаете с помощью веб-камеры, я могу предложить вам:

  1. Извлечение набора углов ( xi ) на контрольном изображении с помощью детектора emgucv harris-corner
  2. Извлечение набора углов ( yi ) на полученных кадрах, все еще использующих детектор углов emgucv harris
  3. Вычисление совпадений между xi и yi с использованием простой стратегии сопоставления, такой как ZNCC
  4. Вычислить матрицу преобразования подобия T между совпадениями с шумом, вычисленными на шагах № 3

Первые три шага довольно просты, и вы можете найти примеры кода в Google (поиск детектора углов opencv или emgucv harris).

Я дам вам некоторый полезный код, извлеченный из моей диссертации для шага № 4, который предполагает преобразование подобия с изотропным масштабированием между вашими объектами:

/// <summary>
    ///   Compute the similarity transformation between a set of noise correspondance matching pairs.
    ///   A similarity transformation has got 5 degrees of freedom:
    ///     - tx and ty for translation
    ///     - isotropic scaling s = Math.Sqrt (a^2 + b ^ 2)
    ///     - orientation = tan^-1 (b\a).
    ///     
    /// 
    ///        Similarity Matrix Transformation
    ///        
    ///   | x' |       |  a    -b     tx  |   | x |
    ///   | y' |   =   |  a     b     ty  | . | y |
    ///   | 1  |       |  0     0      1  |   | 1 | 
    ///              
    /// </summary>
    /// <param name="matches">Putative Correspondance Pairs</param>
    /// <param name="homographyDirection">Direction of Transformation Estimation</param>
    /// <returns>Homography Matrix shaped as a Similarity Transformation</returns>
    public static HomographyMatrix GetSimilarityHomographyMatrixLeastSquares(MatchedImageFeature[] matches)
    {
        int n = matches.Length;
        Matrix<float> M = new Matrix<float>(2, 3);
        PointF[] srcPoints = new PointF[n];
        PointF[] dstPoints = new PointF[n];

        for (int i = 0; i < n; i++)
        {
                srcPoints[i] = matches[i].ObservedFeature.KeyPoint.Point;
                dstPoints[i] = matches[i].SimilarFeatures[0].Feature.KeyPoint.Point;
        }

        GCHandle handleSrcPts = GCHandle.Alloc(srcPoints, GCHandleType.Pinned);
        Matrix<float> srcMatrix = new Matrix<float>(n, 1, 2, handleSrcPts.AddrOfPinnedObject(), 2 * sizeof(float));
        GCHandle handleDstPts = GCHandle.Alloc(dstPoints, GCHandleType.Pinned);
        Matrix<float> dstMatrix = new Matrix<float>(n, 1, 2, handleDstPts.AddrOfPinnedObject(), 2 * sizeof(float));

        cvEstimateRigidTransform(srcMatrix, dstMatrix, M, 0);
        handleDstPts.Free();
        handleSrcPts.Free();


        double xScale, yScale;
        xScale = yScale= Math.Sqrt(Math.Pow(M[0,0],2) + Math.Pow(M[0,1],2));
        double xOffset = M[0, 2];
        double yOffset = M[1, 2];
        double theta = Math.Atan(M[0, 1] / M[0, 0]) * (180 / Math.PI);

        HomographyMatrix similarityTransform = new HomographyMatrix();
        similarityTransform[0, 0] = M[0, 0];
        similarityTransform[0, 1] = M[0, 1];
        similarityTransform[0, 2] = M[0, 2];
        similarityTransform[1, 0] = M[1, 0];
        similarityTransform[1, 1] = M[1, 1];
        similarityTransform[1, 2] = M[1, 2];
        similarityTransform[2, 0] = 0;
        similarityTransform[2, 1] = 0;
        similarityTransform[2, 2] = 1;

        return similarityTransform;
    }
0 голосов
/ 03 декабря 2011

Вам нужно взглянуть на соответствие шаблонов и соответствие контуров .Сопоставление с собственным шаблоном, предоставляемое OpenCV, не учитывает ротацию и масштабирование.

В первом справочнике вы найдете код для загрузки и кучу полезных комментариев о том, как также обнаруживать ротацию.

Второе - это интересное сообщение в блоге, в котором поэтапно обсуждается, как выполнить сопоставление контуров (случай сопоставления шаблонов с инвариантом вращения), и делится исходным кодом, который делает свое дело.

Обапредставить исходный код C / C ++ с использованием OpenCV, поэтому я думаю, у вас не возникнет проблем с переводом их на C #.

...