OpenCV Max位置 [英] OpenCV Max locations

查看:336
本文介绍了OpenCV Max位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在一个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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆