news 2026/4/18 8:41:35

OpenCVSharp:学习最佳匹配矩形检测

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
OpenCVSharp:学习最佳匹配矩形检测

前言

今天来学习一下OpenCVSharp中最佳匹配矩形检测的例子。其过程可以分为ORB特征检测、特征匹配、最佳匹配筛选、单应性计算与矩形绘制。

效果:

实践

ORB特征检测

进行ORB特征检测:

using var img1 = new Mat(FirstImagePath, ImreadModes.Color); usingvar img2 = new Mat(SecondImagePath, ImreadModes.Color); usingvar orb = ORB.Create(1000); usingvar descriptors1 = new Mat(); usingvar descriptors2 = new Mat(); orb.DetectAndCompute(img1, null, outvar keyPoints1, descriptors1); orb.DetectAndCompute(img2, null, outvar keyPoints2, descriptors2);

ORB(Oriented FAST and Rotated BRIEF)是一种快速高效的特征检测算法,它结合了FAST关键点检测器和BRIEF描述符,并添加了旋转不变性和尺度不变性,能够在保持较高匹配精度的同时提供极快的计算速度,特别适合实时应用和移动设备上的计算机视觉任务。

查看ORB.Create方法:

public static ORB Create(int nFeatures = 500, float scaleFactor = 1.2f, int nLevels = 8, int edgeThreshold = 31, int firstLevel = 0, int wtaK = 2, ORBScoreType scoreType = ORBScoreType.Harris, int patchSize = 31, int fastThreshold = 20) { NativeMethods.HandleException(NativeMethods.features2d_ORB_create(nFeatures, scaleFactor, nLevels, edgeThreshold, firstLevel, wtaK, (int)scoreType, patchSize, fastThreshold, out var returnValue)); return new ORB(returnValue); }

ORB.Create() 方法是OpenCV中用于创建ORB特征检测器的静态工厂方法,它提供了多个参数来定制ORB检测器的行为:

参数名

默认值

含义说明

nFeatures

500

要保留的最大特征点数量

scaleFactor

1.2f

金字塔缩放比率,大于1。scaleFactor=2表示经典金字塔,每下一层比上一层少4倍像素

nLevels

8

金字塔层数。最小层尺寸等于输入图像尺寸/pow(scaleFactor, nlevels-firstLevel)

edgeThreshold

31

不检测特征的边界区域大小,应大致匹配patchSize参数

firstLevel

0

放置源图像的金字塔层级,之前的层级用上采样的源图像填充

wtaK

2

生成定向BRIEF描述符每个元素所需的点数。默认值2表示取随机点对比较亮度,输出0/1响应

scoreType

Harris

特征点评分类型。Harris_SCORE表示使用Harris算法对特征排序,FAST_SCORE是稍快但不太稳定的替代方案

patchSize

31

定向BRIEF描述符使用的补丁大小,在较小的金字塔层上特征覆盖的感知图像区域会更大

fastThreshold

20

FAST角点检测的阈值

再来看下DetectAndCompute方法:

public virtual void DetectAndCompute(InputArray image, InputArray? mask, out KeyPoint[] keypoints, OutputArray descriptors, bool useProvidedKeypoints = false) { ThrowIfDisposed(); if (image == null) { thrownew ArgumentNullException("image"); } if (descriptors == null) { thrownew ArgumentNullException("descriptors"); } image.ThrowIfDisposed(); mask?.ThrowIfDisposed(); using VectorOfKeyPoint vectorOfKeyPoint = new VectorOfKeyPoint(); NativeMethods.HandleException(NativeMethods.features2d_Feature2D_detectAndCompute(ptr, image.CvPtr, Cv2.ToPtr(mask), vectorOfKeyPoint.CvPtr, descriptors.CvPtr, useProvidedKeypoints ? 1 : 0)); keypoints = vectorOfKeyPoint.ToArray(); GC.KeepAlive(this); GC.KeepAlive(image); GC.KeepAlive(mask); descriptors.Fix(); GC.KeepAlive(descriptors); }

DetectAndCompute 是OpenCV中特征检测器类的核心方法,用于在图像中检测关键点(特征点)并计算这些点的描述符。这是计算机视觉中特征匹配、物体识别、图像拼接等应用的基础。

查看参数含义:

参数名

类型

含义

image

InputArray

输入的灰度图像,大多数特征检测器要求单通道灰度图像

mask

InputArray?

可选的掩码,用于指定在图像的哪些区域检测特征

keypoints

out KeyPoint[]

输出的关键点数组,包含检测到的关键点信息

descriptors

OutputArray

输出的描述符,包含每个关键点的描述符

useProvidedKeypoints

bool

是否使用提供的关键点

查看得到的关键点数组:

特征匹配

进行汉明特征匹配:

using var bf = new BFMatcher(NormTypes.Hamming, crossCheck: true); var matches = bf.Match(descriptors1, descriptors2);

汉明匹配是一种基于汉明距离的二进制特征描述符匹配方法,通过计算两个二进制字符串之间不同位的数量来衡量相似度,主要用于ORB、BRISK、FREAK等二进制特征描述符的快速匹配。相比传统的欧几里得距离匹配,汉明匹配具有计算速度快、内存占用小的优势,只需简单的位运算和计数操作,特别适合实时应用和移动设备场景。在OpenCV中,通常使用BFMatcher配合NormTypes.Hamming来实现,通过设置距离阈值(如ORB通常为30-70)来筛选最佳匹配,广泛应用于特征匹配、物体识别和图像拼接等计算机视觉任务中。

查看BFMatcher类的这个构造函数:

public BFMatcher(NormTypes normType = NormTypes.L2, bool crossCheck = false) { NativeMethods.HandleException(NativeMethods.features2d_BFMatcher_new((int)normType, crossCheck ? 1 : 0, out ptr)); detectorPtr = null; }

BFMatcher(Brute-Force Matcher,暴力匹配器)是OpenCV中用于特征描述符匹配的基础类,它通过遍历所有可能的描述符对来找到最佳匹配。

参数名

类型

默认值

含义

normType

NormTypes

NormTypes.L2

距离度量类型,用于计算描述符之间的相似度

crossCheck

bool

false

是否启用交叉验证,确保匹配的对称性

再来看下Match方法:

public DMatch[] Match(Mat queryDescriptors, Mat trainDescriptors, Mat? mask = null) { ThrowIfDisposed(); if (queryDescriptors == null) { thrownew ArgumentNullException("queryDescriptors"); } if (trainDescriptors == null) { thrownew ArgumentNullException("trainDescriptors"); } using VectorOfDMatch vectorOfDMatch = new VectorOfDMatch(); NativeMethods.HandleException(NativeMethods.features2d_DescriptorMatcher_match1(ptr, queryDescriptors.CvPtr, trainDescriptors.CvPtr, vectorOfDMatch.CvPtr, Cv2.ToPtr(mask))); GC.KeepAlive(this); GC.KeepAlive(queryDescriptors); GC.KeepAlive(trainDescriptors); GC.KeepAlive(mask); return vectorOfDMatch.ToArray(); }

Match 是OpenCV中描述符匹配器的核心方法,用于在两组描述符之间找到最佳匹配对。这是特征匹配流程中的关键步骤,将查询描述符与训练描述符进行一对一匹配。

参数名

类型

默认值

含义

queryDescriptors

Mat

-

查询描述符集合,通常来自第一幅图像

trainDescriptors

Mat

-

训练描述符集合,通常来自第二幅图像

mask

Mat?

null

可选掩码,用于指定哪些描述符对可以匹配

返回的是DMatch结构体数组,查看这个结构体

属性名

类型

含义

QueryIdx

int

查询描述符索引,指向查询描述符集合中的第几个描述符

TrainIdx

int

训练描述符索引,指向训练描述符集合中的第几个描述符

ImgIdx

int

训练图像索引,当有多个训练图像时指定匹配来自哪个图像

Distance

float

两个描述符之间的距离,值越小表示匹配质量越好

选取最好的10个匹配:

var goodMatches = matches .OrderBy(x => x.Distance) .Take(10) .ToArray();

提取这些关键点坐标:

var srcPts = goodMatches.Select(m => keyPoints1[m.QueryIdx].Pt).Select(p => new Point2d(p.X, p.Y)); var dstPts = goodMatches.Select(m => keyPoints2[m.TrainIdx].Pt).Select(p => new Point2d(p.X, p.Y));

计算单应性矩阵

using var homography = Cv2.FindHomography(srcPts, dstPts, HomographyMethods.Ransac, 5, null);

查看FindHomography方法:

public static Mat FindHomography(IEnumerable<Point2d> srcPoints, IEnumerable<Point2d> dstPoints, HomographyMethods method = HomographyMethods.None, double ransacReprojThreshold = 3.0, OutputArray? mask = null, int maxIters = 2000, double confidence = 0.995) { if (srcPoints == null) { thrownew ArgumentNullException("srcPoints"); } if (dstPoints == null) { thrownew ArgumentNullException("dstPoints"); } Point2d[] obj = (srcPoints as Point2d[]) ?? srcPoints.ToArray(); Point2d[] array = (dstPoints as Point2d[]) ?? dstPoints.ToArray(); NativeMethods.HandleException(NativeMethods.calib3d_findHomography_vector(obj, obj.Length, array, array.Length, (int)method, ransacReprojThreshold, ToPtr(mask), maxIters, confidence, outvar returnValue)); GC.KeepAlive(mask); mask?.Fix(); returnnew Mat(returnValue); }

FindHomography 是OpenCV中用于计算最佳透视变换矩阵的核心方法,它能够找到将源平面点映射到目标平面点的单应性矩阵。这是计算机视觉中图像配准、拼接和三维重建的基础算法。

参数名

类型

默认值

含义

srcPoints

IEnumerable

-

原始平面中的点坐标集合

dstPoints

IEnumerable

-

目标平面中的点坐标集合

method

HomographyMethods

HomographyMethods.None

计算单应性矩阵的方法

ransacReprojThreshold

double

3.0

RANSAC方法中允许的最大重投影误差

mask

OutputArray?

null

可选输出掩码,标记内点和外点

maxIters

int

2000

RANSAC最大迭代次数

confidence

double

0.995

置信水平,范围0-1

HomographyMethods 选项:

方法值

含义

适用场景

HomographyMethods.None

普通最小二乘法

数据质量好,无外点

HomographyMethods.Ransac

RANSAC算法

存在外点和噪声

HomographyMethods.Lmeds

最小中值法

外点比例适中

HomographyMethods.Rho

RHO算法

对外点鲁棒性强

int h = img1.Height, w = img1.Width; var img2Bounds = new[] { new Point2d(0, 0), new Point2d(0, h-1), new Point2d(w-1, h-1), new Point2d(w-1, 0), }; var img2BoundsTransformed = Cv2.PerspectiveTransform(img2Bounds, homography);

定义图像边界然后变换图像边界。

public static Point2d[] PerspectiveTransform(IEnumerable<Point2d> src, Mat m) { if (src == null) { thrownew ArgumentNullException("src"); } if (m == null) { thrownew ArgumentNullException("m"); } using Mat<Point2d> mat = Mat.FromArray(src); using Mat<Point2d> mat2 = new Mat<Point2d>(); NativeMethods.HandleException(NativeMethods.core_perspectiveTransform_Mat(mat.CvPtr, mat2.CvPtr, m.CvPtr)); GC.KeepAlive(m); return mat2.ToArray(); }

PerspectiveTransform 是OpenCV中用于执行透视变换的核心方法,它能够对二维或三维点集合应用透视变换矩阵,实现坐标系的转换。这是图像几何变换中的基础操作,广泛应用于图像校正、拼接和增强现实等领域。

矩形绘制

using var view = img2.Clone(); var drawingPoints = img2BoundsTransformed.Select(p => (Point)p).ToArray(); Cv2.Polylines(view, new[] { drawingPoints }, true, Scalar.Red, 3);

查看Polylines方法:

public static void Polylines( Mat img, IEnumerable<IEnumerable<Point>> pts, bool isClosed, Scalar color, int thickness = 1, LineTypes lineType = LineTypes.Link8, int shift = 0) { if (img isnull) thrownew ArgumentNullException(nameof(img)); if (pts isnull) thrownew ArgumentNullException(nameof(pts)); img.ThrowIfDisposed(); var ptsList = new List<Point[]>(); var nptsList = new List<int>(); foreach (var pts1 in pts) { var pts1Arr = pts1.ToArray(); ptsList.Add(pts1Arr); nptsList.Add(pts1Arr.Length); } var ptsArr = ptsList.ToArray(); var npts = nptsList.ToArray(); var ncontours = ptsArr.Length; usingvar ptsPtr = new ArrayAddress2<Point>(ptsArr); NativeMethods.HandleException( NativeMethods.imgproc_polylines_Mat( img.CvPtr, ptsPtr.GetPointer(), npts, ncontours, isClosed ? 1 : 0, color, thickness, (int) lineType, shift)); GC.KeepAlive(img); }

Polylines 是OpenCV中用于绘制一个或多个多边形曲线的绘图函数。它可以在图像上绘制连续的线段,形成闭合或开放的多边形形状,是计算机视觉中可视化检测结果、标注区域和绘制轮廓的重要工具。

参数名

类型

默认值

含义

img

Mat

-

目标图像,要在其上绘制多边形

pts

IEnumerable<IEnumerable>

-

多边形点集合的集合,每个内层集合代表一个多边形

isClosed

bool

-

是否闭合多边形,true表示闭合,false表示开放

color

Scalar

-

绘制颜色,BGR格式

thickness

int

1

线条粗细,正数表示粗细,负数表示填充

lineType

LineTypes

LineTypes.Link8

线条类型,抗锯齿算法

shift

int

0

坐标点的小数位数

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 8:08:05

15、数据类型转换函数与元素提取详解

数据类型转换函数与元素提取详解 1. 输入值与格式规范中的分隔符 虽然建议输入值和格式规范使用相同的分隔符(这样更清晰),但 Oracle 对此要求并不严格,分隔符甚至在间距方面都可以不同。以下两个示例均能正常工作: select TO_DATE(15.10.2020, DD/MM/YYYY) from dual…

作者头像 李华
网站建设 2026/4/18 8:17:07

LLama-Factory集成HuggingFace镜像,加速模型下载提升训练效率

LLama-Factory集成HuggingFace镜像&#xff0c;加速模型下载提升训练效率 在大语言模型&#xff08;LLM&#xff09;快速发展的今天&#xff0c;微调已成为将通用预训练模型转化为行业专用智能体的核心手段。然而&#xff0c;现实中的开发者常常面临两个“拦路虎”&#xff1a;…

作者头像 李华
网站建设 2026/4/17 10:21:50

AutoGPT与Zapier集成可能性分析:连接上千种SaaS服务的桥梁

AutoGPT与Zapier集成&#xff1a;构建智能自动化代理的实践路径 在企业系统日益碎片化的今天&#xff0c;一个常见的困境是&#xff1a;我们拥有强大的AI语言模型&#xff0c;能写出流畅报告、设计学习计划&#xff0c;甚至模拟决策逻辑&#xff0c;却难以让它真正“动手”——…

作者头像 李华
网站建设 2026/4/16 18:05:20

中国科学技术大学论文模板参考文献格式调整深度解析与实用指南

中国科学技术大学论文模板参考文献格式调整深度解析与实用指南 【免费下载链接】ustcthesis LaTeX template for USTC thesis 项目地址: https://gitcode.com/gh_mirrors/us/ustcthesis 中国科学技术大学论文模板&#xff08;ustcthesis&#xff09;近期针对参考文献格式…

作者头像 李华
网站建设 2026/4/17 17:23:41

GitHub镜像同步更新:LLama-Factory支持100+主流大模型高效微调

GitHub镜像同步更新&#xff1a;LLama-Factory支持100主流大模型高效微调 在AI技术快速迭代的今天&#xff0c;越来越多企业和开发者希望基于大语言模型构建专属应用——无论是医疗问答系统、金融客服机器人&#xff0c;还是教育领域的智能辅导工具。然而&#xff0c;面对动辄数…

作者头像 李华
网站建设 2026/4/18 8:29:19

《2026年春节出境游趋势》显示,十大热搜目的地中新西兰与挪威热度持续冲高 | 美通社头条

、美通社消息&#xff1a;史上最长春节假期全面点燃中国旅行者的出境游热情。Airbnb爱彼迎发布《2026年春节出境游趋势》显示&#xff0c;中国旅行者计划在春节假期前后出境游的搜索热度达到去年同期的两倍左右&#xff0c;延续了国庆黄金周的强劲势头。同时&#xff0c;越来越…

作者头像 李华