21xrx.com
2025-04-01 00:41:54 Tuesday
文章检索 我的文章 写文章
C++ OpenCV 非极大值抑制 (NMS)
2023-07-09 07:23:16 深夜i     209     0
C++ OpenCV 非极大值抑制 NMS 图像处理

非极大值抑制是一种干扰物减少算法,常用于图像处理中。在计算机视觉中,非极大值抑制(Non-Maximum Suppression, NMS)是一种常见的技术,用于对边缘、特征点等检测结果进行后处理,以减少检测冗余和消除错误结果。

C++ OpenCV是一种常用的计算机视觉库,提供了非常便捷的实现NMS的函数。在OpenCV中,可以使用cv::dilate函数对检测结果进行膨胀操作,并使用cv::compare函数比较原图像和膨胀后的图像,得到一个二值图像。然后,使用cv::findNonZero函数将二值图像中的非零像素坐标提取出来,并遍历这些像素,计算具有最大值的连通分量,并将其余像素值设为0。

下面是一个简单的代码示例:

void nonMaximumSuppression(cv::Mat& src, cv::Mat& dst, int ksize) {
  cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(ksize, ksize));
  cv::Mat dilateImg;
  cv::dilate(src, dilateImg, kernel);
  cv::compare(src, dilateImg, dst, cv::CMP_EQ);
  cv::Mat points;
  cv::findNonZero(dst, points);
  for (cv::Point p : points) {
    int x = p.x;
    int y = p.y;
    cv::Rect region(x - ksize / 2, y - ksize / 2, ksize, ksize);
    cv::Mat roi = src(region);
    double maxVal;
    cv::minMaxLoc(roi, NULL, &maxVal);
    if (maxVal < src.at<float>(y, x)) {
      dst.at<uchar>(y, x) = 0;
    }
  }
}

这段代码中,传入的src为待处理图像,ksize为膨胀核的大小,dst为输出二值图像。在函数内部,首先使用cv::getStructuringElement函数构造一个$ksize \times ksize$的矩形膨胀核kernel,然后用cv::dilate函数对src进行膨胀。接下来,使用cv::compare函数比较src和膨胀后的图像,得到一个二值图像dst。然后使用cv::findNonZero函数将dst中非零像素坐标提取出来,并对这些像素进行遍历。对于每个像素,通过cv::Rect函数构造一个$ksize \times ksize$的矩形区域roi,并使用cv::minMaxLoc函数计算区域内的最大值maxVal。如果maxVal小于该像素的值,则将dst中该像素设为0,否则保留。

在C++ OpenCV中,实现非极大值抑制是十分简单的。这种技术广泛应用于计算机视觉、图像处理、目标检测等领域,为提高算法的准确性和性能提供了很好的帮助。

  
  

评论区

请求出错了