EmguCV SURF - 确定匹配的点对

2023-12-22

我目前正在修改 EmguCV(版本 3.0.0.2157)SurfFeature 示例(在这里看到的 https://github.com/neutmute/emgucv/blob/master/Emgu.CV.Example/SURFFeature/DrawMatches.cs#L33).

我试图确定匹配的点对的数量,以便计算输入图像之间的相似度百分比。

据我了解,这些信息存储在mask变量,但我不知道如何访问它?

(这个问题之前已经被问过here https://stackoverflow.com/questions/14374423/use-surf-to-match-images-in-opencv-emgucv,但引用的示例源代码使用的是旧版本的 EmguCV)

提前致谢!


p 确定匹配项

    public static Image<Bgr, Byte> Draw(Image<Gray, Byte> modelImage, Image<Gray, byte> observedImage, out long matchTime, out int nonofZeroCount)
    {
        int returnValue = 0;

        Stopwatch watch;
        HomographyMatrix homography = null;

        SURFDetector surfCPU = new SURFDetector(500, false);
        VectorOfKeyPoint modelKeyPoints;
        VectorOfKeyPoint observedKeyPoints;
        Matrix<int> indices;

        Matrix<byte> mask;
        int k = 2;
        double uniquenessThreshold = 0.8;

        if (GpuInvoke.HasCuda)
        {
            GpuSURFDetector surfGPU = new GpuSURFDetector(surfCPU.SURFParams, 0.01f);
            using (GpuImage<Gray, Byte> gpuModelImage = new GpuImage<Gray, byte>(modelImage))
            //extract features from the object image
            using (GpuMat<float> gpuModelKeyPoints = surfGPU.DetectKeyPointsRaw(gpuModelImage, null))
            using (GpuMat<float> gpuModelDescriptors = surfGPU.ComputeDescriptorsRaw(gpuModelImage, null, gpuModelKeyPoints))
            using (GpuBruteForceMatcher<float> matcher = new GpuBruteForceMatcher<float>(DistanceType.L2))
            {
                modelKeyPoints = new VectorOfKeyPoint();
                surfGPU.DownloadKeypoints(gpuModelKeyPoints, modelKeyPoints);
                watch = Stopwatch.StartNew();

                // extract features from the observed image
                using (GpuImage<Gray, Byte> gpuObservedImage = new GpuImage<Gray, byte>(observedImage))
                using (GpuMat<float> gpuObservedKeyPoints = surfGPU.DetectKeyPointsRaw(gpuObservedImage, null))
                using (GpuMat<float> gpuObservedDescriptors = surfGPU.ComputeDescriptorsRaw(gpuObservedImage, null, gpuObservedKeyPoints))
                using (GpuMat<int> gpuMatchIndices = new GpuMat<int>(gpuObservedDescriptors.Size.Height, k, 1, true))
                using (GpuMat<float> gpuMatchDist = new GpuMat<float>(gpuObservedDescriptors.Size.Height, k, 1, true))
                using (GpuMat<Byte> gpuMask = new GpuMat<byte>(gpuMatchIndices.Size.Height, 1, 1))
                using (Stream stream = new Stream())
                {
                    matcher.KnnMatchSingle(gpuObservedDescriptors, gpuModelDescriptors, gpuMatchIndices, gpuMatchDist, k, null, stream);
                    indices = new Matrix<int>(gpuMatchIndices.Size);
                    mask = new Matrix<byte>(gpuMask.Size);

                    //gpu implementation of voteForUniquess
                    using (GpuMat<float> col0 = gpuMatchDist.Col(0))
                    using (GpuMat<float> col1 = gpuMatchDist.Col(1))
                    {
                        GpuInvoke.Multiply(col1, new MCvScalar(uniquenessThreshold), col1, stream);
                        GpuInvoke.Compare(col0, col1, gpuMask, CMP_TYPE.CV_CMP_LE, stream);
                    }

                    observedKeyPoints = new VectorOfKeyPoint();
                    surfGPU.DownloadKeypoints(gpuObservedKeyPoints, observedKeyPoints);

                    //wait for the stream to complete its tasks
                    //We can perform some other CPU intesive stuffs here while we are waiting for the stream to complete.
                    stream.WaitForCompletion();

                    gpuMask.Download(mask);
                    gpuMatchIndices.Download(indices);

                    if (GpuInvoke.CountNonZero(gpuMask) >= 4)
                    {
                        int nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(modelKeyPoints, observedKeyPoints, indices, mask, 1.5, 20);
                        if (nonZeroCount >= 4)
                            homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(modelKeyPoints, observedKeyPoints, indices, mask, 2);

                        returnValue = nonZeroCount;
                    }

                    watch.Stop();
                }
            }
        }
        else
        {
            //extract features from the object image
            modelKeyPoints = surfCPU.DetectKeyPointsRaw(modelImage, null);
            Matrix<float> modelDescriptors = surfCPU.ComputeDescriptorsRaw(modelImage, null, modelKeyPoints);

            watch = Stopwatch.StartNew();

            // extract features from the observed image
            observedKeyPoints = surfCPU.DetectKeyPointsRaw(observedImage, null);
            Matrix<float> observedDescriptors = surfCPU.ComputeDescriptorsRaw(observedImage, null, observedKeyPoints);
            BruteForceMatcher<float> matcher = new BruteForceMatcher<float>(DistanceType.L2);
            matcher.Add(modelDescriptors);

            indices = new Matrix<int>(observedDescriptors.Rows, k);
            using (Matrix<float> dist = new Matrix<float>(observedDescriptors.Rows, k))
            {
                matcher.KnnMatch(observedDescriptors, indices, dist, k, null);
                mask = new Matrix<byte>(dist.Rows, 1);
                mask.SetValue(255);
                Features2DToolbox.VoteForUniqueness(dist, uniquenessThreshold, mask);
            }

            int nonZeroCount = CvInvoke.cvCountNonZero(mask);
            if (nonZeroCount >= 4)
            {
                nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(modelKeyPoints, observedKeyPoints, indices, mask, 1.5, 20);
                if (nonZeroCount >= 4)
                    homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(modelKeyPoints, observedKeyPoints, indices, mask, 2);
            }

            returnValue = nonZeroCount;
            watch.Stop();
        }

        int p = mask.ManagedArray.OfType<byte>().ToList().Where(q => q == 1).Count();

        //Draw the matched keypoints
        Image<Bgr, Byte> result = Features2DToolbox.DrawMatches(modelImage, modelKeyPoints, observedImage, observedKeyPoints,
           indices, new Bgr(255, 255, 255), new Bgr(255, 255, 255), mask, Features2DToolbox.KeypointDrawType.DEFAULT);

        #region draw the projected region on the image
        if (homography != null && p > 20)
        {  //draw a rectangle along the projected model
            Rectangle rect = modelImage.ROI;
            PointF[] pts = new PointF[] { 
           new PointF(rect.Left, rect.Bottom),
           new PointF(rect.Right, rect.Bottom),
           new PointF(rect.Right, rect.Top),
           new PointF(rect.Left, rect.Top)};
            homography.ProjectPoints(pts);

            result.DrawPolyline(Array.ConvertAll<PointF, Point>(pts, Point.Round), true, new Bgr(Color.Red), 5);
        }
        #endregion

        matchTime = watch.ElapsedMilliseconds;

        nonofZeroCount = returnValue;

        return result;
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

EmguCV SURF - 确定匹配的点对 的相关文章

  • Qt - QProcess 不工作

    我尝试启动 Internet Explorer 所以我使用下面的代码 QProcess process new QProcess this QString temp C Program Files Internet Explorer iex
  • Exit() 时是否调用基本对象析构函数?

    我意识到这个问题已经出现过几次 但我试图获得上述问题的明确答案 但我不断遇到相互矛盾的信息 我需要知道的是 当我使用 exit 时 基本类对象是否被破坏 我知道需要删除动态内存 但我的意思更像是 include
  • 在 HKCR 中创建新密钥有效,但不起作用

    我有以下代码 它返回 成功 但使用两种不同的工具使用搜索字符串 3BDAAC43 E734 11D5 93AF 00105A990292 搜索注册表不会产生任何结果 RegistryKey RK Registry ClassesRoot C
  • 尝试了解使用服务打开对话框

    我已经阅读了有关使用 mvvm 模式打开对话框的讨论 我看过几个使用服务的示例 但我不明白所有部分如何组合在一起 我发布这个问题寻求指导 以了解我应该阅读哪些内容 以更好地理解我所缺少的内容 我将在下面发布我所拥有的内容 它确实有效 但从我
  • Grpc - 将消息从一个客户端发送到连接到同一服务器的另一个客户端

    是否可以将消息从一个客户端发送到连接到同一服务器的另一个客户端 我想将数据从一个客户端发送到服务器然后发送到特定客户端 我想我需要获取客户端 ID 但我不知道如何获取此 ID 以及如何从服务器将此消息发送到该客户端 我这里有一个样本 这是一
  • Environment.CurrentDirectory 与 System.IO.Directory.GetCurrentDirectory

    我正在编写一个 Net WinForms 并不断在调试和发布配置之间切换 并且有一些文件我需要任一配置才能访问 我想做的是将文件放在 BIN 文件夹中的公共目录中 这样它看起来像这样 MyProject Bin CommonFiles My
  • 按扩展名过滤搜索文件返回太多结果

    我正在开发一个 C 控制台应用程序 它必须管理 Windows 操作系统上的文件 我需要获取具有特定扩展名的文件名 列表 我找到了很多解决方案 最建议的是以下一种 HANDLE hFind WIN32 FIND DATA data hFin
  • 前向声明类型和“已声明为类类型的非类类型”

    我对以下代码有问题 template
  • 未找到 Boost 库,但编译正常

    我正在尝试在 C 中使用 boost 的文件系统 使用时看起来编译没问题 c c Analyse c o Analyse o g W Wall L usr local lib lboost filesystem lboost system
  • 有些有助于理解“产量”

    在我不断追求少吸的过程中 我试图理解 产量 的说法 但我不断遇到同样的错误 someMethod 的主体不能是迭代器块 因为 System Collections Generic List 不是迭代器接口类型 这是我被卡住的代码 forea
  • RestSharp获取序列化输出

    我正在寻找一种方法来访问 AddBody 调用的序列化结果 我正在使用内置的 RestSharp 序列化器 例子 class Foo public string FooField void SendRecord var f new Foo
  • Eigen 和 OpenMP:由于错误共享和线程开销而没有并行化

    系统规格 Intel Xeon E7 v3 处理器 4 插槽 16 核 插槽 2 线程 核心 Eigen 系列和 C 的使用 以下是代码片段的串行实现 Eigen VectorXd get Row const int j const int
  • 在 C# 中检查 PowerShell 执行策略的最佳方法是什么?

    当你跑步时Get ExecutionPolicy在 PowerShell 中 它得到有效的执行政策 https learn microsoft com en us powershell module microsoft powershell
  • 在 VS 中运行时如何查看 C# 控制台程序的输出?

    我刚刚编写了一个名为 helloworld 的聪明程序 它是一个 C NET 4 5 控制台应用程序 在扭曲的嵌套逻辑迷宫深处 使用了 Console WriteLine 当我在命令行运行它时 它会运行并且我会看到输出 我可以执行其他命令并
  • 如何递归取消引用指针(C++03)?

    我正在尝试在 C 中递归地取消引用指针 如果传递一个对象 那就是not一个指针 这包括智能指针 我只想返回对象本身 如果可能的话通过引用返回 我有这个代码 template
  • 从 C# 使用 Odbc 调用 Oracle 包函数

    我在 Oracle 包中定义了一个函数 CREATE OR REPLACE PACKAGE BODY TESTUSER TESTPKG as FUNCTION testfunc n IN NUMBER RETURN NUMBER as be
  • 如果输入被重定向则执行操作

    我想知道如果我的输入被重定向 我应该如何在 C 程序中执行操作 例如 假设我有已编译的程序 prog 并且我将输入 input txt 重定向到它 我这样做 prog lt input txt 我如何在代码中检测到这一点 一般来说 您无法判
  • 比较:接口方法、虚方法、抽象方法

    它们各自的优点和缺点是什么 接口方法 虚拟方法 抽象方法 什么时候应该选择什么 做出这一决定时应牢记哪些要点 虚拟和抽象几乎是一样的 虚方法在基类中有一个实现 可以选择重写 而抽象方法则没有 并且must在子类中被覆盖 否则它们是相同的 在
  • C++:二叉树所有节点值的总和

    我正在准备面试 我被一个二叉树问题困住了 我们如何计算二叉树所有节点中存在的值的总和 优雅的递归解决方案 伪代码 def sum node if node NULL return 0 return node gt value sum nod
  • 是否允许全局静态标识符以单个 _ 开头?

    换句话说 可能static 文件范围 全局变量恰好以一个下划线开头 而不会产生与 C 实现发生名称冲突的可能性 https www gnu org software libc manual html node Reserved Names

随机推荐

  • 使用 JSP 列出服务器目录的内容

    我在服务器上的以下目录中有文件 D tomcat8 webapps schema files 我想列出上面目录中存在的所有文件 我尝试过的 它不起作用 但是 如果我将文件存储在应用程序本身的 WEB INF filefolder 中 则以下
  • 如何在容器上使用本地文件?

    我正在尝试创建一个容器来运行程序 我正在使用预配置映像 现在我需要运行该程序 然而 它是一个机器学习程序 我需要计算机中的数据集才能运行 文件太大 无法复制到容器中 最好是在容器中运行的程序在我的计算机的本地目录中搜索数据集 但我不知道如何
  • 基于字符向量进行子集化时 knit_expand 失败

    我本质上是想修改这个答案 https stackoverflow com a 14368148 2726564以编程方式生成带有变量每个级别的图的块 然而 在我的特定情况下 我传递了一个用于后续子集设置的字符向量 这似乎是代码失败的根源 M
  • 如何在 C# 中以编程方式读取 sql server mdf header 中的日志文件信息

    我需要以编程方式附加数据库 但日志文件命名约定似乎不同 例如 database1 mdf has database1 ldf database2 mdf has database2 log ldf等等 所以 我的猜测是有关日志文件的信息将位
  • 导出 webpack 包/前置 module.exports?避免节点中出现空对象?

    我试图将我的bundle js放入我的Node服务器 但显然webpack包缺少一个module exports 在顶部的所有捆绑代码之前 我可以手动放置module exports 到这个捆绑包中 但必须有一种编程方式来指定该捆绑包应该是
  • Wpf 使用 MvvmCross 进行多个嵌套用户控件

    我是新来的MvvmCross但我正在与mvvm一阵子 我知道如何使用嵌套用户控件来组合用户控件 现在与mvvmcross我被困在另一个用户控件中显示两个或多个用户控件 我不使用任何其他框架MvvmCross 我的根视图如下所示
  • 使用 Jquery 调整 Html 表的行和列大小

    我必须调整 HTML 表格行 列的宽度和高度 现在我使用单独的插件来调整列宽插件链接 http quocity com colresizable 并单独的jquery函数来调整rowHeight MatrixTabletr resizabl
  • Javascript require 方法未找到 axios 模块

    我正在为 gmail 创建一个 chrome 扩展 我已经使用 npm install axios 安装了 axios 并创建了一个包含该模块的 node modules 文件夹 然后 我尝试将该模块包含在我的 extension js 文
  • MatSort 显示了箭头,但它实际上并未对数据进行排序

    我在这个项目中使用了很多表 并且 MatSort 在所有其他组件中都运行良好 但是 我创建了这个新组件 尽管单击表标题时可以显示箭头 但数据本身并未排序 我将项目的每一行与 Sort Header Angular 演示以及已经运行良好的组件
  • 为什么我不能单独打印复制的字符串? [关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 string s 1 23 string a a 0 s 2 a 1 s 3 cout lt
  • 查找所有未使用的变量

    通常 在 Netbeans 中很容易看到未使用的变量 只是一条灰色的波浪线 但是我如何在我的项目或单个类中找到所有这些未使用的变量呢 Reason 我正在调试一个有大量复制和粘贴的代码库 但做得不够仔细 复制粘贴后存在许多未替换为正确变量的
  • Windows 7:属性处理程序在资源管理器中工作,但在 FileOpenDialog 中不起作用?

    致力于为 Windows 7 中的自定义文件类型编写自定义属性处理程序 我已经安装了 Windows 7 SDK 并构建了示例属性处理程序 注册处理程序后 它在 Windows 资源管理器中运行良好 但在通用文件打开对话框中 自定义值不会出
  • JavaScript 中的大括号变量

    我在 ExtJS 中经常遇到这种情况 我想知道它是从哪里来的 我有一个这样的例子 view new Ext grid GroupingView forceFit true groupTextTpl text values rs length
  • Thymeleaf + Spring-Boot - 为什么我无法访问静态资源?

    我的项目树如下所示 我现在可以访问模板 但无法加载 CSS 图像和 JS 等静态资源 我有一个common html我在其中声明所有静态资源的片段 例如 我包含的标题片段common html像这样 page body A de
  • 如何在Linux中做一个假的鼠标滚轮移动

    我正在尝试模拟键盘和鼠标事件 我已经成功制作了假键盘 keydown keyup 假鼠标按钮按下 向上和假鼠标移动 但我没有找到如何做假鼠标滚轮移动 有人可以向我解释一个在 C 中执行此操作的简单方法吗 鼠标移动和鼠标按钮按下 Displa
  • 在Python中,我可以根据其他参数指定函数参数的默认值吗?

    假设我有一个带有两个参数的 python 函数 但我希望第二个参数是可选的 默认值是作为第一个参数传递的任何参数 所以 我想做这样的事情 def myfunc arg1 arg2 arg1 print arg1 arg2 但那是行不通的 我
  • 将 json 反序列化为匿名类型列表

    我有一个 json 如下 a b c d a e c f a g c h 现在我想将其反序列化为匿名类型 foo 的对象列表 var foo new a string empty c string empty 代码是 ServiceStac
  • Angular 清除子表单数据并重置验证

    我正在尝试创建一个子表单 div 使用 Angular js 有一种数据有很多字段 标题 可用日期 Price 都有required对他们进行验证 一旦我提交了该数据 我将对其进行所需的操作 但我想重置子表单 以便所有字段都不脏 并且表单在
  • Android Aidl错误sdk构建工具29.0.0

    我升级了 Android 应用程序以开始使用 SDK 29 和构建工具 29 0 0 在 Android Studio 中编译时出现错误 进程 命令 C Users ma fo AppData Local Android Sdk build
  • EmguCV SURF - 确定匹配的点对

    我目前正在修改 EmguCV 版本 3 0 0 2157 SurfFeature 示例 在这里看到的 https github com neutmute emgucv blob master Emgu CV Example SURFFeat