2011-11-16 57 views
3

我正在开发一个OpenCV项目,并使用cvMatchTemplate来定位图像的一部分,然后我使用cvMinMaxLoc来查找最大面积,因此最匹配,我的问题是cvMinMaxLoc只返回一个最大位置为一个图像中可能有多个匹配。OpenCV最大位置

有没有办法返回特定阈值之上

即所有的最大位置

每个位置>门槛 添加位置阵列

我是新来的OpenCV和不知道如果这样的事情已经存在,但到目前为止,我一直没能找到任何

任何帮助非常感谢

回答

3

我修改了matchTemplate教程,让你开始。它基本上使用queue来跟踪前X个匹配点,然后绘制所有匹配点。希望有帮助!

#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; 
} 
+1

最大值和最小值的东西都点(四舍五入区),其中需要找到单一最大或最小值,然后,一滴加工点,并开始另一点是多少像素的距离都在期待中* *处理点内的本地**最大值或最小值。这就像测量山脉:如果第一个比另一个高10米,那么你不会说第一个占据前10个地方为“最高的山峰”,第11个地方为第二个。但提出的algorythm会说。如果我没错的话。 – Slav

+0

这只是一个快速示例,展示如何获得多个最大匹配。但是,如果您需要本地最大值查找算法,那么我可以将其添加到答案中...... – mevatron

+0

这样做会很好,但复杂因素是分配这些点,然后在其中找到它们。 – Slav

0

尝试cvThreshold(SRC,DST,阈值,CV_THRESH_BINARY)

这将在dst的返回图像与高于阈值的所有像素为白色和所有其他为黑色。然后,您将遍历所有像素,并检查它是否大于0,然后这是您想要的位置。这样

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

我遇到的问题是,会有一小群像素,而不仅仅是找到匹配位置的单个像素 – CaffGeek