OpenCV Max Location

I am working on an OpenCV project and use cvMatchTemplate to find the part of the image that I use cvMinMaxLoc to find the maximum area, so the best thing to combine, my problem is that cvMinMaxLoc returns only one maximum location, as there can be several matches on one image.

Is there a way to return all max locations above a certain threshold

those.

for each location> threshold add location to array

I'm new to OpenCV and don't know if something like this exists, but so far I have not been able to find anything

Any help is much appreciated

+3
source share
2 answers

I changed the matchTemplate tutorial to get you started. It mainly uses a queue to track the top match points of X, and then displays all of them. Hope this will be helpful!

 #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <iostream> #include <vector> #include <limits> #include <queue> using namespace cv; using namespace std; void maxLocs(const Mat& src, queue<Point>& dst, size_t size) { float maxValue = -1.0f * numeric_limits<float>::max(); float* srcData = reinterpret_cast<float*>(src.data); for(int i = 0; i < src.rows; i++) { for(int j = 0; j < src.cols; j++) { if(srcData[i*src.cols + j] > maxValue) { maxValue = srcData[i*src.cols + j]; dst.push(Point(j, i)); // pop the smaller one off the end if we reach the size threshold. if(dst.size() > size) { dst.pop(); } } } } } /// Global Variables Mat img; Mat templ; Mat result; string image_window = "Source Image"; string result_window = "Result window"; int match_method; int max_Trackbar = 5; /// Function Headers void MatchingMethod( int, void* ); int main(int argc, char* argv[]) { /// Load image and template img = imread( "dogs.jpg", 1 ); templ = imread( "dog_templ.jpg", 1 ); /// Create windows namedWindow( image_window, CV_WINDOW_AUTOSIZE ); namedWindow( result_window, CV_WINDOW_AUTOSIZE ); /// Create Trackbar string trackbar_label = "Method: \n 0: SQDIFF \n 1: SQDIFF NORMED \n 2: TM CCORR \n 3: TM CCORR NORMED \n 4: TM COEFF \n 5: TM COEFF NORMED"; createTrackbar( trackbar_label, image_window, &match_method, max_Trackbar, MatchingMethod ); MatchingMethod( 0, 0 ); waitKey(0); return 0; } /** * @function MatchingMethod * @brief Trackbar callback */ void MatchingMethod( int, void* ) { /// Source image to display Mat img_display; img.copyTo( img_display ); /// Create the result matrix int result_cols = img.cols - templ.cols + 1; int result_rows = img.rows - templ.rows + 1; result.create( result_cols, result_rows, CV_32FC1 ); /// Do the Matching and Normalize matchTemplate( img, templ, result, match_method ); normalize( result, result, 0, 1, NORM_MINMAX, -1, Mat() ); /// For SQDIFF and SQDIFF_NORMED, the best matches are lower values. For all the other methods, the higher the better if( match_method == CV_TM_SQDIFF || match_method == CV_TM_SQDIFF_NORMED ) { result = 1.0 - result; } // get the top 100 maximums... queue<Point> locations; maxLocs(result, locations, 100); /// Show me what you got while(!locations.empty()) { Point matchLoc = locations.front(); rectangle( img_display, matchLoc, Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), Scalar::all(0), 2, 8, 0 ); rectangle( result, matchLoc, Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), Scalar::all(0), 2, 8, 0 ); locations.pop(); } imshow( image_window, img_display ); imshow( result_window, result ); return; } 
+3
source

Try cvThreshold (src, dst, threshold, CV_THRESH_BINARY)

This will cause the image to return to dst with all pixels above the white threshold and all the others black. Then you will iterate over all the pixels and check if it is greater than 0 than this is the place you want. Something like that

  char* data = dst->imageData; int size = (dst->height) * (dst->width) for (int i=0; i<size; i++) { if(data[i] > 0) //copy i into your array } 
0
source

Source: https://habr.com/ru/post/1394598/


All Articles