如何在EmguCv中使用捕获时创建旋转边界区域

本文关键字:创建 旋转 区域 边界 EmguCv | 更新日期: 2023-09-27 18:16:53

我的问题如下:

使用EmguCv (c# OpenCV),我必须写一个应用程序,可以检测我的数字旋转或不使用我的电脑摄像头。我用Capture从我的网络摄像头捕捉帧。此外,我使用SmoothGausianCanny过滤器"清理"了每一帧。多亏了这一点,相机所能看到的只是我画在纸上的形象。我检查了我的人物的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);
    }
}

如何在EmguCv中使用捕获时创建旋转边界区域

你需要看一下模板匹配和轮廓匹配。OpenCV提供的本地模板匹配不考虑旋转和缩放。

在第一个参考中,你会发现下载的代码和一堆关于如何检测旋转的有用评论。

第二篇是一篇有趣的博客文章,讨论了如何一步一步地进行轮廓匹配(模板匹配旋转不变量的一种情况),并分享了实现这一技巧的源代码。

都是使用OpenCV的C/c++源代码,所以我想你把它们翻译成c#是没有问题的。

要计算参考图和您使用网络摄像头获得的图之间的旋转,我可以建议您:

  1. 利用emgucv哈里斯角点检测器
  2. 提取参考图像的角点集合(xi)
  3. 提取角集(yi)仍然使用emgucv harris角检测器
  4. 计算xiyi之间的匹配使用一个简单的匹配策略,如ZNCC
  5. 在步骤3计算的噪声匹配之间计算相似变换矩阵T

前三个步骤非常简单,你可以在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;
    }