【问题标题】:Find all peaks for Mat() in OpenCV C++在 OpenCV C++ 中查找 Mat() 的所有峰值
【发布时间】:2015-03-04 01:27:58
【问题描述】:

我想找到我的图像的所有最大值(非零像素的数量)。我需要它以这样的方式划分我的图片:

所以,我已经问过question,如何将所有图像投影到一个轴上,现在我需要在这个单行图像上找到所有最大值。 这是我的部分代码:

void segment_plate (Mat input_image) {
    double minVal; 
    double maxVal; 
    Point minLoc; 
    Point maxLoc;
    Mat work_image = input_image;
    Mat output;
    //binarize image
    adaptiveThreshold(work_image,work_image, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 15, 10);  
    //project it to one axis
    reduce(work_image,output,0,CV_REDUCE_SUM,CV_32S);

    //find minimum and maximum falue for ALL image
    minMaxLoc(output, &minVal,&maxVal,&minLoc,&maxLoc);
    cout << "min val : " << minVal << endl;
    cout << "max val: " << maxVal << endl;

如您所见,我可以为所有图片找到一个最大值和一个最小值,但我需要找到局部最大值。感谢您的帮助!

编辑 好的,所以我犯了一个错误,我需要找到这个向量的峰值。我用这段代码找到了第一个峰值:

int findPeakUtil(Mat arr, int low, int high, int n) {
// Find index of middle element
    int mid = low + (high - low)/2;  /* (low + high)/2 */

// Compare middle element with its neighbours (if neighbours exist)
    if ((mid == 0 || arr.at<int>(0,mid-1) <= arr.at<int>(0,mid)) &&
        (mid == n-1 || arr.at<int>(0,mid+1) <= arr.at<int>(0,mid)))
    return mid;

// If middle element is not peak and its left neighbor is greater than it
// then left half must have a peak element
    else if (mid > 0 && arr.at<int>(0,mid-1) > arr.at<int>(0,mid))
    return findPeakUtil(arr, low, (mid - 1), n);

// If middle element is not peak and its right neighbor is greater than it
// then right half must have a peak element
    else return findPeakUtil(arr, (mid + 1), high, n);
}

// A wrapper over recursive function findPeakUtil()
int findPeak(Mat arr, int n) {
   return findPeakUtil(arr, 0, n-1, n);
}

所以现在我的代码如下所示:

void segment_plate (Mat input_image) {
    Mat work_image = input_image;
    Mat output;
    //binarize image
    adaptiveThreshold(work_image,work_image, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 15, 10);  
    //project it to one axis
    reduce(work_image,output,0,CV_REDUCE_SUM,CV_32S);
    int n = output.cols;
    printf("Index of a peak point is %d", findPeak(output, n));

但是我怎样才能找到另一个山峰?寻峰算法取自here

【问题讨论】:

  • 所以你有一个向量,想要找到局部最大值?邻域是如何计算的?你的意思是向量中的每个峰值?还是如图所示,每个字母的每个峰值?
  • 好吧,我猜是每个字母的每个峰值,但我们不知道它是字母,还是泥土。所以我想我需要从图片中找到 12 个最高值的坐标。
  • 问题是你想要峰值而不是最大值,所以你需要分析峰值的向量,用峰值和位置创建一个向量,然后按值对它们进行排序并得到前 12 , 如果是最大的话会容易很多
  • 好吧,我错了,但我怎样才能找到峰? :)

标签: c++ opencv histogram ocr


【解决方案1】:

我可以考虑找到峰值的一种方法是找到一阶导数,然后找到它的负数。

例如,

a = [ 1, 2, 3, 4, 4, 5, 6, 3, 4]

在这个例子中,峰值是 6 在位置 6 和 4 在 las 位置。 因此,如果您扩展向量(末尾为 0)并应用一阶导数(a[i] - a[i-1]),您将得到 ​​p>

a_deriv = [1,1,1,0,1,1,-3,1,-4]

负数在峰的位置。在这种情况下,-3 位于位置 6,-4 位于位置 8,即峰值所在的位置。

这是一种方法......但不是唯一的。

请注意,此方法将仅将高原中的最后一个数字计为峰值(当两个数字共享峰值时,您可以找到高原,因为它们具有相同的值并且是连续的)

希望对你有帮助

【讨论】:

  • 注意:找到一个函数的所有“峰值”肯定有很大的分形性。峰与非峰的区别是什么?这取决于您定义导数的 x 比例(在我引用的答案中,x 比例 = 1)。还有很多主观性:“找到n个最高峰”!=“找到n个最突出的山峰”。只是一些思考的食物;基本算法是相同的,但必须根据具体情况进行调整。
  • 我的想法完全正确,这在很大程度上取决于人们想要什么,这将是它开始下降之前的重点....但是由于我看不到论文或教程他在跟随,那么要准确地理解他想要什么并不容易
猜你喜欢
  • 1970-01-01
  • 2021-04-04
  • 1970-01-01
  • 2018-02-09
  • 1970-01-01
  • 2013-10-15
  • 1970-01-01
  • 2014-08-07
  • 2020-01-03
相关资源
最近更新 更多