找回密码
 立即注册
首页 业界区 业界 OpenCVSharp:BRISK特征检测

OpenCVSharp:BRISK特征检测

东门芳洲 2025-11-21 11:40:01
概述

BRISK(Binary Robust Invariant Scalable Keypoints)是一种快速、高效的特征检测和描述算法,由Stefan Leutenegger等人于2011年提出。它属于二进制特征描述符家族,与SIFT、SURF等浮点型特征描述符相比,具有计算速度快、内存占用小的特点。
BRISK是一种平衡了速度和性能的特征检测算法,特别适合需要实时处理的应用场景。虽然其精度可能不如SIFT或SURF,但在许多实际应用中,其速度优势更为重要。在OpenCV中,BRISK被广泛应用于需要快速特征检测和匹配的计算机视觉任务中。
1.png

实践

示例中的核心代码很少:
  1. using var brisk = BRISK.Create();
  2. KeyPoint[] keypoints = brisk.Detect(gray);
  3. if (keypoints != null)
  4. {
  5.     var color = new Scalar(0, 255, 0);
  6.     foreach (KeyPoint kpt in keypoints)
  7.     {
  8.         float r = kpt.Size / 2;
  9.         Cv2.Circle(dst, (Point)kpt.Pt, (int)r, color);
  10.         Cv2.Line(dst,
  11.             (Point)new Point2f(kpt.Pt.X + r, kpt.Pt.Y + r),
  12.             (Point)new Point2f(kpt.Pt.X - r, kpt.Pt.Y - r),
  13.             color);
  14.         Cv2.Line(dst,
  15.             (Point)new Point2f(kpt.Pt.X - r, kpt.Pt.Y + r),
  16.             (Point)new Point2f(kpt.Pt.X + r, kpt.Pt.Y - r),
  17.             color);
  18.     }
  19. }
复制代码
OpenCVSharp中封装了一个BRISK,现在来看看这个类的Create方法:
  1.   public static BRISK Create(int thresh = 30, int octaves = 3, float patternScale = 1.0f)
  2.   {
  3.       NativeMethods.HandleException(
  4.           NativeMethods.features2d_BRISK_create1(thresh, octaves, patternScale, out var ptr));
  5.       return new BRISK(ptr);
  6.   }
复制代码
先了解一下参数的意义:
thresh(AGAST检测阈值)
基于AGAST(Adaptive and Generic Accelerated Segment Test)算法的阈值,用于判断像素点是否为角点,控制特征点检测的敏感度。
较低值(如10-20):检测更多特征点,但可能包含噪声
较高值(如40-60):检测更少但更稳定的特征点
octaves(检测八度数)
构建图像金字塔,在不同尺度上检测特征点,控制多尺度检测的层数。
0:仅进行单尺度检测,速度最快
1-4:多尺度检测,能识别不同大小的特征
更高值:增加尺度范围但降低性能
patternScale(采样模式缩放)
BRISK使用特定的采样模式来计算描述符,此参数控制该模式的缩放,整特征点邻域采样模式的缩放比例。
< 1.0:更密集的采样,可能提高精度但降低速度
> 1.0:更稀疏的采样,提高速度但可能降低精度
再来看一下Detect方法:
  1. public KeyPoint[] Detect(Mat image, Mat? mask = null)
  2. {
  3.      if (image is null)
  4.          throw new ArgumentNullException(nameof(image));
  5.      ThrowIfDisposed();
  6.      image.ThrowIfDisposed();
  7.      try
  8.      {
  9.          using var keyPoints = new VectorOfKeyPoint();
  10.          NativeMethods.HandleException(
  11.              NativeMethods.features2d_Feature2D_detect_Mat1(ptr, image.CvPtr, keyPoints.CvPtr, Cv2.ToPtr(mask)));
  12.          return keyPoints.ToArray();
  13.      }
  14.      finally
  15.      {
  16.          GC.KeepAlive(this);
  17.          GC.KeepAlive(image);
  18.          GC.KeepAlive(mask);
  19.      }
  20. }
复制代码
直接使用这个方法就可以获取特征点:
2.png

然后在图像上显示这些特征点即可得到上面的图。
我看到说BRISK可以用于物体识别,我在想既然会生成特征点,那么肯定可以进行特征点匹配,这样能不能拿两张图去匹配,比如两个人有两张不同的照片能不能识别出是同一个人呢?
我做了一个简单的Demo,但是效果其实不好:
3.png

没有后面DrawBestMatchRectangle这个示例的效果好,后面这个示例使用的是ORB,然后也有使用汉明匹配,等后面再介绍。
DrawBestMatchRectangle示例效果:
4.png


来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册