Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Find all peaks for Mat() in OpenCV C++

I want to find all peaks for my image. I need it to divide my picture such way:

enter image description here

So, i already asked question, how to project all image to one of the axis, and now i need to find all maximums on this one-row image. Here's my part of the code:

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;

As you can see, i could find one maximum and one minimum for all picture, but i need to find local maximums. Thanks for any help!

EDIT Ok, so i made a mistake, i need to find peaks for this vector. I've used this code to find first peak:

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);
}

So now my code looks like:

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));

But how can i find another peaks? The algorithm of peak finding i took from here.

Find all peaks for Mat() in OpenCV C++

I want to find all peaks for my image. I need it to divide my picture such way:

enter image description here

So, i already asked question, how to project all image to one of the axis, and now i need to find all maximums on this one-row image. Here's my part of the code:

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;

As you can see, i could find one maximum and one minimum for all picture, but i need to find local maximums. Thanks for any help!

EDIT Ok, so i made a mistake, i need to find peaks for this vector. I've used this code to find first peak:

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);
}

So now my code looks like:

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));

But how can i find another peaks? The algorithm of peak finding i took from here.