33-SIFT特征匹配(EmguCV学习)

Emgucv不完整图像分割试验(十五)—— 匹配特征点的提取以及半透明显示连接线 有人求助说要将Emgucv模板匹配中的连接线半透明显示出来,没想多示例代码的集成度太高, Mat mask; FindMatch(modelImage, observedImage, out matchTime, out modelKeyPoints, out observedKeyPoints, matches, out... 阅读详情

33-SIFT特征匹配

emm

懒了很久,还有最后一点儿,全部整理完~

Record


1、SIFI算子使用流程:

  1. 初始化SIFT向量,调用Detect()方法识别两张图片各自的特征点;
  2. 使用SIFT的Compute()方法计算计算两张图片各自特征点的特征描述符;
  3. 使用匹配器Matcher进行特征描述符匹配(BF与Flann),以其中一幅图片为模板,在另一幅图片中寻找匹配的特征点;
  4. 匹配结果保存在DMatch结构体变量中,设置距离阈值对匹配结果进行筛选,得到好的匹配点;
  5. 使用DrawMatch()方法进行绘制,显示匹配结果;

2、BF暴力匹配器在EmguCV中通过BFMatcher类进行实现,使用Add()方法添加模板的特征描述符,使用 KnnMatch() 方法寻找计算另一幅图像中的k个匹配特征点;


3、可以参考:https://www.cnblogs.com/Jessica-jie/p/8622449.html
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


4、PPT:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

Code

BF匹配:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using Emgu.Util;
using Emgu.CV.Util;
using System.Drawing;
using Emgu.CV.XFeatures2D;      //包含SIFT类
using Emgu.CV.Features2D;       //包含Features2DToolBox类

namespace lesson33
{
    class Program
    {
        static void Main(string[] args)
        {
            Mat srcImg1 = CvInvoke.Imread("1.jpg");
            Mat srcImg2 = CvInvoke.Imread("2.jpg");

            CvInvoke.Imshow("src1", srcImg1);
            CvInvoke.Imshow("src2", srcImg2);

            SIFT sift = new SIFT(1000);
            //计算特征点
            MKeyPoint[] keyPoints1 = sift.Detect(srcImg1);
            MKeyPoint[] keyPoints2 = sift.Detect(srcImg2);
            //绘制特征点
            Mat sift_feature1 = new Mat();
            Mat sift_feature2 = new Mat();
            VectorOfKeyPoint vkeyPoint1 = new VectorOfKeyPoint(keyPoints1);
            VectorOfKeyPoint vkeyPoint2 = new VectorOfKeyPoint(keyPoints2);
            Features2DToolbox.DrawKeypoints(srcImg1, vkeyPoint1, sift_feature1, new Bgr(0, 255, 0),
                Features2DToolbox.KeypointDrawType.Default);
            Features2DToolbox.DrawKeypoints(srcImg2, vkeyPoint2, sift_feature2, new Bgr(0, 255, 0));
            //显示绘制结果
            CvInvoke.Imshow("sift_feature1", sift_feature1);
            CvInvoke.Imshow("sift_feature2", sift_feature2);
            //计算特征描述符
            Mat descriptors1 = new Mat();
            Mat descriptors2 = new Mat();
            sift.Compute(srcImg1, vkeyPoint1, descriptors1);
            sift.Compute(srcImg2, vkeyPoint2, descriptors2);
            //使用BF匹配器进行暴力匹配
            BFMatcher bFMatcher = new BFMatcher(DistanceType.L2);
            VectorOfVectorOfDMatch matches = new VectorOfVectorOfDMatch();
            //添加特征描述符
            bFMatcher.Add(descriptors1);
            //k最邻近匹配
            bFMatcher.KnnMatch(descriptors2, matches, 2, null);
            //寻找匹配结果中距离的最值
            double min_dist = 100, max_dist = 0;
            for(int i = 0; i < descriptors1.Rows;i++)
            {
                if(matches[i][0].Distance > max_dist)
                {
                    max_dist = matches[i][0].Distance;
                }
                if(matches[i][0].Distance < min_dist)
                {
                    min_dist = matches[i][0].Distance;
                }
            }
            //对BF匹配结果进行筛选
            VectorOfVectorOfDMatch good_matches = new VectorOfVectorOfDMatch();
            for(int i = 0; i < matches.Size;i++)
            {
                //符合条件的匹配点进行存储
                if(matches[i][0].Distance < 1.5 * min_dist)
                {
                    good_matches.Push(matches[i]);
                }
            }
            //绘制匹配点
            Mat result = new Mat();
            Features2DToolbox.DrawMatches(srcImg1, vkeyPoint1, srcImg2, vkeyPoint2, good_matches,
                result, new MCvScalar(0, 255, 0), new MCvScalar(0, 0, 255));
            //显示匹配结果
            CvInvoke.Imshow("match-result", result);

            CvInvoke.WaitKey(0);
        }
    }
}

FLANN匹配:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using Emgu.Util;
using Emgu.CV.Util;
using System.Drawing;
using Emgu.CV.XFeatures2D;      //包含SIFT类
using Emgu.CV.Features2D;       //包含Features2DToolBox类
using Emgu.CV.Flann;            //包含快速最邻近匹配
namespace lesson33
{
    class Program
    {
        static void Main(string[] args)
        {
            Mat srcImg1 = CvInvoke.Imread("11.jpg");
            Mat srcImg2 = CvInvoke.Imread("22.jpg");

            CvInvoke.Imshow("src1", srcImg1);
            CvInvoke.Imshow("src2", srcImg2);

            SIFT sift = new SIFT(1000);
            //计算特征点
            MKeyPoint[] keyPoints1 = sift.Detect(srcImg1);
            MKeyPoint[] keyPoints2 = sift.Detect(srcImg2);
            //绘制特征点
            Mat sift_feature1 = new Mat();
            Mat sift_feature2 = new Mat();
            VectorOfKeyPoint vkeyPoint1 = new VectorOfKeyPoint(keyPoints1);
            VectorOfKeyPoint vkeyPoint2 = new VectorOfKeyPoint(keyPoints2);
            Features2DToolbox.DrawKeypoints(srcImg1, vkeyPoint1, sift_feature1, new Bgr(0, 255, 0),
                Features2DToolbox.KeypointDrawType.Default);
            Features2DToolbox.DrawKeypoints(srcImg2, vkeyPoint2, sift_feature2, new Bgr(0, 255, 0));
            //显示绘制结果
            CvInvoke.Imshow("sift_feature1", sift_feature1);
            CvInvoke.Imshow("sift_feature2", sift_feature2);
            //计算特征描述符
            Mat descriptors1 = new Mat();
            Mat descriptors2 = new Mat();
            sift.Compute(srcImg1, vkeyPoint1, descriptors1);
            sift.Compute(srcImg2, vkeyPoint2, descriptors2);
            //快速最邻近匹配Flann
            IIndexParams id = new LinearIndexParams();
            SearchParams sp = new SearchParams();
            FlannBasedMatcher flannBasedMatcher = new FlannBasedMatcher(id, sp);
            //添加模板
            flannBasedMatcher.Add(descriptors1);
            VectorOfVectorOfDMatch matches = new VectorOfVectorOfDMatch();
            flannBasedMatcher.KnnMatch(descriptors2, matches, 2, null);

            //筛选匹配结果
            Mat mask = new Mat(matches.Size, 1, DepthType.Cv8U, 1);
            mask.SetTo(new MCvScalar(255));
            Features2DToolbox.VoteForUniqueness(matches, 0.3, mask);    //去除重复匹配

            Mat result = new Mat();
            Features2DToolbox.DrawMatches(srcImg1, vkeyPoint1, srcImg2, vkeyPoint2, matches, result, new MCvScalar(0, 255, 0),
                                new MCvScalar(0, 0, 255), mask);
            CvInvoke.Imshow("match-result", result);
            CvInvoke.WaitKey(0);
        }
    }
}

效果

BF匹配:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
Flann匹配:
在这里插入图片描述
在这里插入图片描述

C#图像处理 | EmguCV+OpenCVSharp二合一教程 你值得拥有 VS2017+EmguCV3.4高清入门视频教程 视频教程原链接如上,内容预览与目录如下 EmguCV+OpenCVSharp视频教程二合一版本 C#视觉开发者必备 EmguCV基础视频教程---第01讲(EmguCV介绍与安装配置) EmguCV基础视频教程---第01讲---补充更新(EmguCV3.4.1安装配置) EmguCV基础视频教程---第02讲(EmguCV自带例程赏析) EmguCV基础视频教程---第03讲(图像读取_显示_保... 阅读详情

相关推荐

C# OpenCV图片识别落地的四大硬坎:环境、内存、预处理与业务耦合

图片识别是计算机视觉的基础能力,其核心在于将图像数据转化为可计算的结构化信息。OpenCV作为最成熟的开源图像处理库,提供了从滤波、边缘检测到深度学习推理的全栈能力;而C#凭借.NET平台的稳定性与工业软件生态优势,成为上位机、工控系统和边缘设备的首选开发语言。二者结合的技术价值在于兼顾开发效率与生产可靠性,但真实落地时需直面ABI兼容性、托管/非托管内存协同、光照与噪声鲁棒性预处理,以及识别逻辑与业务规则的深度咬合。本文聚焦C#调用OpenCV进行图片识别的工程实践,深入解析DLL加载失败、Mat内存泄漏

weixin_32642109的博客 250

基于emgucv和c#的书本特征匹配

文章目录前言一、主要步骤1.窗体设计2.引用命名空间3.主要算法3.结果总结题外话 前言 本blog是该系列文章的第一篇demo,主要功能是实现书本的目标检测,主要算法是用了sift特征匹配。 一、主要步骤 1.窗体设计 该窗体主要用到了两个imagebox,三个button,整体形状如图 2.引用命名空间 该功能需要引用 emgu.cv, emgu.cv.contrib, emgu.cv.ui, emgu.cv.uti 四个dll库,相应的命名空间如下 using System.Window..

bookshu6的博客 1417

C#工业上位机轻量级图像识别引擎(OpenCV原生实现)

图像识别在工业自动化中常被泛化为AI模型推理,但实际大量场景依赖确定性、低延迟、免训练的计算机视觉技术。OpenCV作为成熟开源库,提供模板匹配、边缘检测、直方图均衡等原生能力,具备跨平台、无GPU依赖、内存可控等工程优势。尤其在C#上位机环境中,结合OpenCvSharp4可规避Python生态复杂性与HALCON授权限制,直接嵌入Win7/Win10工控系统,支撑AOI检测、PLC联动、自动点击等实时闭环控制。本文聚焦‘c#上位机’与‘图片识别’两大核心热词,详解如何基于OpenCV原生API构建稳定、

weixin_33391446的博客 249

32-SIFI特征点提取(EmguCV学习)

文章目录记录Code效果 记录 Code 效果

hello 1276

C# OpenCV图片识别实战:工业级鲁棒性封装与内存安全方案

图片识别是计算机视觉的基础能力,其核心在于图像加载、预处理、特征提取与目标定位的技术闭环。在.NET生态中,C#调用OpenCV实现稳定识别面临跨语言内存管理、实时性约束与工业环境适配三大挑战。OpenCVSharp作为主流绑定方案,虽提供高性能API,但默认Mat对象的非托管内存分配易引发泄漏与崩溃,需通过SafeMat封装、using资源控制及线程隔离策略保障稳定性。本文聚焦真实产线场景——如USB工业相机接入、低配工控机部署、7×24小时运行等需求,详解CLAHE增强、Otsu阈值、模板匹配优化及JS

weixin_33507732的博客 261

c#基于emgu进行图像配准及拼接

在VS环境下用C#进行开发,并配置emgu进行图像处理。利用emgu中自带的sift算法进行图像特征点检测、配准及拼接,并用XML文档形式读取和写图像。

SIFTC#举例

SIFTC#举例

xie__jin__cheng的博客 606

C#-EmguCV 特征匹配

C#版本EmguCV,实现特征匹配,对特征点进行处理,标识

Angel Eyes基于SIFT特征点的图像搜索系统的开发

过年回来以后,Angel Eyes的团队成员又开始了紧张忙碌的工作。为了争取在这个月向外界开放API和SDK,我们又对图像特征点搜索系统开发做了进一步的研究和实验,以力求搜索,匹配的精准。以下是我们基于SIFT特征点的图像搜索系统开发日志,也算是一些心得,与各位CV的同行们分享。 一、C#验证实验阶段 1、实验框架搭建工作:配置EmguCV、编写界面。 写界面是C#的长项,不过需要怎

GeekIn的专栏 1685

SIFT算法提取图像特征

基于无监督学习,无需训练数据, 使用SIFT算法提取图像特征,再使用KMeans聚类算法进行图像分类。 对源代码进行了优化,实现了对应图片自动分类到各自文件夹功能,并且优化了分类准确率。 设计思路: 1)首先编写百度图片搜索网络爬虫(我github其他仓库有),批量下载猫狗等图像数据,构建数据集。 2)利用opencv库对图像数据进行处理,进行灰度化,二值化,膨胀,高斯滤波等操作 3)学习SIFT算法跟KMeans聚类算法,取其优点 4)编写代码进行图像分类 本次使用的是传统图像分类方法,下次会实现基于深度学习卷积神经网络图像分类。

C#中OpenCvSharp 通过特征点匹配图片的方法

主要介绍了OpenCvSharp 通过特征点匹配图片的方法,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下

Emgu cv中的SIFT算法实现

SIFT算法大家都比较熟悉,网上的版本很多,刚开始接触时我主要研究的是C++,因为相对于C#,基于OPEN CV C++的SIFT算法资料更多,但是由于想要实现较为理想的界面效果,最终还是放弃了使用C++转而使用C#。 C#中SIFT算法主要分为三种: 1)脱离Emgu cv平台,完全手动实现所有SIFT算法函数,这样的程序虽然实现有些困难,但是完全可借助已有的C++程序做更改,而

XIANG__jiangsu的专栏 3230

单片机笔记十二:华大HC32L136超低功耗设计实战

本文详细介绍了华大HC32L136单片机的超低功耗设计实战,包括深度睡眠模式下仅0.5μA的电流消耗、五种功耗模式的对比与配置、外设使用技巧及硬件级优化方法。通过实际项目案例,展示了如何利用ARM Cortex-M0+内核的HC32L136显著延长电池寿命,适用于智能门锁、额温枪等低功耗设备。

weixin_29189373的博客 391

emgucv中SIFT、SURF匹配算法

emgucv3.0.0有自带的SIFT和SURF匹配算法,在文件夹C:\Emgu\emgucv-windows-universal 3.0.0.2157\Emgu.CV.Example(该文件夹含有许多emgucv案例)下的SURFFeature下,该程序直接可以运行,是现成的SURF算法可以用来做匹配算法比较。 emgucv库中也含有SIFT算法,只需要将代码中 SURF对象改变为SIFT对象即可。 ...

weixin_42062353的博客 845

PCIE Lane Margining Linux 环境配置

Copy all the provided files in folder PYC38 or PYC310 to the created pcie_lmt folder. Index of /ftp/python/3.8.10/Copy below commands to a file and rename it as "scan_pcie.py", the commands are from "685662 PCIe-LMT-Gen4_Gen5-r0p77.pdf" in the lane margi

mysongshine的博客 1433

Ubuntu配置Qt Creator树莓派交叉编译环境一步到位

本文详细指导在Ubuntu系统上配置Qt Creator树莓派交叉编译环境。从工具链安装、sysroot创建到Qt库编译,逐步讲解如何搭建完整的ARMv7交叉编译工具链,实现高效开发树莓派应用。

1273

surf 检测

using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Runtime.InteropServices; using Emgu.CV; using Emgu.CV.CvEnum; using Emgu.CV.Features2D; u...

qq_36786800的博客 1368

利用树莓派制作智能音箱

利用树莓派制作智能音箱

qq_61803022的博客 1776

EmguCV学习笔记 VB.Net 7.2 特征点检测

SIFT算法是一种基于尺度空间极值检测和高斯差分图像描述子的算法,具有较高的特征检测精度和描述子匹配准确性,它可以在不同尺度和旋转角度下检测和描述图像中的特征点,由于其良好的尺度不变性和旋转不变性,被广泛应用于计算机视觉领域。在使用SIFT算法提取特征描述子时,特征描述子保存在一个Mat类型变量中,该Mat的大小是“关键点的数量×128”,对应Mat的“行×列”,每个关键点为一行,128表示每个特征描述子包含128个数值,这些数值表示了关键点周围区域的特征信息,可以用于描述和区分不同的关键点。

学习微软 .net 技术开发 2174

Matlab之App Designer 如何进行三维图形绘制教程

基于Matlab中的App Designer设计可视化界面并进行数据导入及3D绘图,可以直观的在可视化界面上展示分析结果,方便用户进行图形的操作。本文采用案例讲解的方式,详细介绍了如何采用Matlab App Designer建立数据3D绘图的GUI可视化界面的方法和详细的过程步骤,并介绍了导入数据进行计算时需要注意的相关事项,同时提供了详细的代码,以便读者进行学习和操作。

m0_59012156的博客 2066

如何使用Google Maps API爬取地理数据:详细教程与Python实现

Google Maps API 是一组服务的集合,允许开发者访问地图、地点、路线等地理信息。:将地址转换为地理坐标,或将地理坐标转换为地址。:计算两点之间的行车路线、步行路线等。Places API:获取附近的地点、商店、餐馆等。:计算多个地点之间的距离和时间。在接下来的代码中,我们将结合这些 API,展示如何获取并处理地理数据。本文详细介绍了如何使用 Google Maps API 获取地理数据,涵盖了从地址转经纬度、获取地点详情、计算路线、计算多个地点的距离与时间等多个功能。

2201_76125261的博客 733

Emgucv SURF特征点的寻找和匹配

使用SURF类和其相关的函数需要添加Emgu.CV.Features2D和Emgu.CV.XFeatures2D这两个命名空间,同时也可以使用cuda模块来进行加速,由于使用Cuda需要安装,但Cuda目前支持的显卡驱动并不兼容win10,所以这里我就简单的说一下通用的方法吧。 这个代码里使用了UMat,UMat应该算是3.0版本中的新特性,根据官方的说法,UMat等价于Opencv中的Mat。具

k 2万+

手把手教您如何在飞牛NAS上部署OpenClaw(Clawdbot/Moltbot)智能助手,接入钉钉,0成本使用(万字保姆级教程)

想在飞牛NAS上部署一个24小时待命的AI助手?🤖 本文手把手教您如何在飞牛NAS上部署一个完全免费的OpenClaw智能助手 ✅

XiaoqiangClub的博客 7226

34-SURF特征匹配(EmguCV学习)

@toc Record Code 效果

hello 1506

电阻抗成像肺功能测试数据分析与直方图生成

本文介绍了基于MATLAB的电阻抗成像(EIT)肺功能测试数据分析方法。研究针对32×32像素的EIT图像序列,通过三步算法处理:首先计算特定时间点与谷值图像的差值,然后分析1秒后峰值与1秒值的差值,最终计算比值矩阵并处理异常值。系统展示了数据预处理、关键时间点检测、比值计算及统计分析的全流程,包括生成概率分布直方图和空间分布图等可视化方法。该分析为无创肺功能评估提供量化指标,可应用于临床呼吸监测和疾病诊断。

huanghm88的专栏 197

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

上一篇: CHUSEI 3D Webcam摄像头双目模式使用(转载)
下一篇: 34-SURF特征匹配(EmguCV学习)
hellohake
博客等级 码龄10年 4543粉丝 108原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值