2011-11-16 61 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