OpenCV Max位置 [英] OpenCV Max locations
问题描述
我正在一个OpenCV项目上,正在使用cvMatchTemplate定位图像的一部分,然后使用cvMinMaxLoc查找最大面积,因此最佳匹配,我的问题是cvMinMaxLoc仅返回一个最大位置,因为可能存在一幅图像中有多个匹配项.
I am working on an OpenCV project and am using cvMatchTemplate to locate part of an image I am then using cvMinMaxLoc to find the maximum area, therefore best match, my problem is that cvMinMaxLoc only returns one max location were as there may be multiple matches in one image.
有没有办法返回超出特定阈值的所有最大位置
Is there any way to return all the max locations above a particular threshold
即
对于每个位置>阈值 将位置添加到数组
for each location > threshold add location to array
我是OpenCV的新手,不知道是否已经存在类似的东西,但到目前为止我还找不到任何东西
I'm new to OpenCV and dont know if something like this already exists but so far I haven't been able to find anything
任何帮助表示赞赏
推荐答案
我修改了matchTemplate
教程以帮助您入门.它基本上使用queue
来跟踪最前面的X个匹配点,然后绘制所有这些匹配点.希望对您有所帮助!
I modified the matchTemplate
tutorial to get you started. It basically uses a queue
to track the top X match points, and later plots all of them. Hope that is 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;
}
这篇关于OpenCV Max位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!