OpenCV Max位置

Mik*_*ate 5 opencv

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

有没有办法将所有最大位置返回到特定阈值以上

对于每个位置>阈值将位置添加到阵列

我是OpenCV的新手,不知道这样的事情是否已经存在,但到目前为止我还没有找到任何东西

任何帮助非常感谢

mev*_*ron 3

我修改了matchTemplate教程来帮助您入门。它基本上使用 aqueue来跟踪前 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;
}
Run Code Online (Sandbox Code Playgroud)

  • 最大值和最小值位于需要找到单个最大值或最小值的点(圆形区域)内,然后删除已处理的点并开始在距离内所有**本地**最大值或最小值远像素的另一个点内查找加工现货。这就像量山一样:如果第一座山比另一座山高 10 米,那么你就不会说第一座山占据前 10 位,成为“最高的山”,而第二座山则占据第 11 位。但提出的算法会这么说。如果我没错的话。 (2认同)