gpt4 book ai didi

c++ - 实时模板匹配 - OpenCV,C++

转载 作者:可可西里 更新时间:2023-11-01 17:25:53 25 4
gpt4 key购买 nike

我正在尝试使用模板实现实时跟踪。我希望用每一帧更新模板。我所做的主要修改是:

1) 将模板匹配和 minmaxLoc 分离到单独的模块中,即分别为 TplMatch()minmax() 函数。

2) 在 track() 函数内,select_flag 始终保持为真,以便在每次迭代时将新模板复制到“myTemplate”。

3) track()函数的最后3行是更新模板(roiImg)。

4) 此外, 我已经删除了 track() 函数的所有参数,因为 imgroiImg 是全局变量,因此无需将它们传递给函数。

代码如下:

#include <iostream>
#include "opencv2/opencv.hpp"
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/objdetect/objdetect.hpp>

#include <sstream>


using namespace cv;
using namespace std;

Point point1, point2; /* vertical points of the bounding box */
int drag = 0;
Rect rect; /* bounding box */
Mat img, roiImg; /* roiImg - the part of the image in the bounding box */
int select_flag = 0;
bool go_fast = false;

Mat mytemplate;


///------- template matching -----------------------------------------------------------------------------------------------

Mat TplMatch( Mat &img, Mat &mytemplate )
{
Mat result;

matchTemplate( img, mytemplate, result, CV_TM_SQDIFF_NORMED );
normalize( result, result, 0, 1, NORM_MINMAX, -1, Mat() );

return result;
}


///------- Localizing the best match with minMaxLoc ------------------------------------------------------------------------

Point minmax( Mat &result )
{
double minVal, maxVal;
Point minLoc, maxLoc, matchLoc;

minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, Mat() );
matchLoc = minLoc;

return matchLoc;
}


///------- tracking --------------------------------------------------------------------------------------------------------

void track()
{
if (select_flag)
{
roiImg.copyTo(mytemplate);
// select_flag = false;
go_fast = true;
}

// imshow( "mytemplate", mytemplate ); waitKey(0);

Mat result = TplMatch( img, mytemplate );
Point match = minmax( result );

rectangle( img, match, Point( match.x + mytemplate.cols , match.y + mytemplate.rows ), CV_RGB(255, 255, 255), 0.5 );

std::cout << "match: " << match << endl;

/// latest match is the new template
Rect ROI = cv::Rect( match.x, match.y, mytemplate.cols, mytemplate.rows );
roiImg = img( ROI );
imshow( "roiImg", roiImg ); //waitKey(0);
}


///------- MouseCallback function ------------------------------------------------------------------------------------------

void mouseHandler(int event, int x, int y, int flags, void *param)
{
if (event == CV_EVENT_LBUTTONDOWN && !drag)
{
/// left button clicked. ROI selection begins
point1 = Point(x, y);
drag = 1;
}

if (event == CV_EVENT_MOUSEMOVE && drag)
{
/// mouse dragged. ROI being selected
Mat img1 = img.clone();
point2 = Point(x, y);
rectangle(img1, point1, point2, CV_RGB(255, 0, 0), 3, 8, 0);
imshow("image", img1);
}

if (event == CV_EVENT_LBUTTONUP && drag)
{
point2 = Point(x, y);
rect = Rect(point1.x, point1.y, x - point1.x, y - point1.y);
drag = 0;
roiImg = img(rect);
// imshow("MOUSE roiImg", roiImg); waitKey(0);
}

if (event == CV_EVENT_LBUTTONUP)
{
/// ROI selected
select_flag = 1;
drag = 0;
}

}



///------- Main() ----------------------------------------------------------------------------------------------------------

int main()
{
int k;
/*
///open webcam
VideoCapture cap(0);
if (!cap.isOpened())
return 1;*/

///open video file
VideoCapture cap;
cap.open( "Megamind.avi" );
if ( !cap.isOpened() )
{ cout << "Unable to open video file" << endl; return -1; }
/*
/// Set video to 320x240
cap.set(CV_CAP_PROP_FRAME_WIDTH, 320);
cap.set(CV_CAP_PROP_FRAME_HEIGHT, 240);*/

cap >> img;
GaussianBlur( img, img, Size(7,7), 3.0 );
imshow( "image", img );

while (1)
{
cap >> img;
if ( img.empty() )
break;

// Flip the frame horizontally and add blur
cv::flip( img, img, 1 );
GaussianBlur( img, img, Size(7,7), 3.0 );

if ( rect.width == 0 && rect.height == 0 )
cvSetMouseCallback( "image", mouseHandler, NULL );
else
track();

imshow("image", img);
// waitKey(100); k = waitKey(75);
k = waitKey(go_fast ? 30 : 10000);
if (k == 27)
break;
}

return 0;
}

未跟踪更新的模板。我无法弄清楚为什么会发生这种情况,因为我在每次迭代时都更新了我的模板 (roiImg)。 minmax() 函数的匹配 值每次都返回相同的点(坐标)。测试视频位于:http://www.youtube.com/watch?v=vpnkk7N2E0Q&feature=youtu.be请仔细研究并提前指导...非常感谢!

最佳答案

我从你的问题的这个修订版中得到了你的原始代码:https://stackoverflow.com/revisions/20180073/3

我对你的原始代码做了最小的改动,我的结果代码如下:

#include <iostream>
#include "opencv2/opencv.hpp"
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/objdetect/objdetect.hpp>

#include <sstream>


using namespace cv;
using namespace std;

Point point1, point2; /* vertical points of the bounding box */
int drag = 0;
Rect rect; /* bounding box */
Mat img, roiImg; /* roiImg - the part of the image in the bounding box */
int select_flag = 0;
bool go_fast = false;

Mat mytemplate;


///------- template matching -----------------------------------------------------------------------------------------------

Mat TplMatch( Mat &img, Mat &mytemplate )
{
Mat result;

matchTemplate( img, mytemplate, result, CV_TM_SQDIFF_NORMED );
normalize( result, result, 0, 1, NORM_MINMAX, -1, Mat() );

return result;
}


///------- Localizing the best match with minMaxLoc ------------------------------------------------------------------------

Point minmax( Mat &result )
{
double minVal, maxVal;
Point minLoc, maxLoc, matchLoc;

minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, Mat() );
matchLoc = minLoc;

return matchLoc;
}


///------- tracking --------------------------------------------------------------------------------------------------------

void track()
{
if (select_flag)
{
//roiImg.copyTo(mytemplate);
// select_flag = false;
go_fast = true;
}

// imshow( "mytemplate", mytemplate ); waitKey(0);

Mat result = TplMatch( img, mytemplate );
Point match = minmax( result );

rectangle( img, match, Point( match.x + mytemplate.cols , match.y + mytemplate.rows ), CV_RGB(255, 255, 255), 0.5 );

std::cout << "match: " << match << endl;

/// latest match is the new template
Rect ROI = cv::Rect( match.x, match.y, mytemplate.cols, mytemplate.rows );
roiImg = img( ROI );
roiImg.copyTo(mytemplate);
imshow( "roiImg", roiImg ); //waitKey(0);
}


///------- MouseCallback function ------------------------------------------------------------------------------------------

void mouseHandler(int event, int x, int y, int flags, void *param)
{
if (event == CV_EVENT_LBUTTONDOWN && !drag)
{
/// left button clicked. ROI selection begins
point1 = Point(x, y);
drag = 1;
}

if (event == CV_EVENT_MOUSEMOVE && drag)
{
/// mouse dragged. ROI being selected
Mat img1 = img.clone();
point2 = Point(x, y);
rectangle(img1, point1, point2, CV_RGB(255, 0, 0), 3, 8, 0);
imshow("image", img1);
}

if (event == CV_EVENT_LBUTTONUP && drag)
{
point2 = Point(x, y);
rect = Rect(point1.x, point1.y, x - point1.x, y - point1.y);
drag = 0;
roiImg = img(rect);
roiImg.copyTo(mytemplate);
// imshow("MOUSE roiImg", roiImg); waitKey(0);
}

if (event == CV_EVENT_LBUTTONUP)
{
/// ROI selected
select_flag = 1;
drag = 0;
}

}



///------- Main() ----------------------------------------------------------------------------------------------------------

int main()
{
int k;
/*
///open webcam
VideoCapture cap(0);
if (!cap.isOpened())
return 1;*/

///open video file
VideoCapture cap;
cap.open( "Megamind.avi" );
if ( !cap.isOpened() )
{ cout << "Unable to open video file" << endl; return -1; }
/*
/// Set video to 320x240
cap.set(CV_CAP_PROP_FRAME_WIDTH, 320);
cap.set(CV_CAP_PROP_FRAME_HEIGHT, 240);*/

cap >> img;
GaussianBlur( img, img, Size(7,7), 3.0 );
imshow( "image", img );

while (1)
{
cap >> img;
if ( img.empty() )
break;

// Flip the frame horizontally and add blur
cv::flip( img, img, 1 );
GaussianBlur( img, img, Size(7,7), 3.0 );

if ( rect.width == 0 && rect.height == 0 )
cvSetMouseCallback( "image", mouseHandler, NULL );
else
track();

imshow("image", img);
// waitKey(100); k = waitKey(75);
k = waitKey(go_fast ? 30 : 10000);
if (k == 27)
break;
}

return 0;
}

视频位于 https://www.youtube.com/watch?v=rBCopeneCos显示了对上述程序的测试。

我会避免使用全局变量,因为我认为它们无助于理解问题所在;此外,我还会注意 OpenCV 的 Mat 类的浅拷贝和深拷贝,如 1''在他的 answer 中写道:

OpenCV's Mat class is simply a header for the actual image data, which it contains a pointer to. The operator= copies the pointer (and the other information in the header, like the image dimensions) so that both Mats share the same data. This means that modifying the data in one Mat also changes it in the other. This is called a "shallow" copy, since only the top layer (the header) is copied, not the lower layer (the data).

To make a copy of the underlying data (called a "deep copy"), use the clone() method. You can find information about it on the page that you linked to.

编辑漂移:在评论中Real-time template matching - OpenCV, C++ , learner询问跟踪漂移。看视频https://www.youtube.com/watch?v=rBCopeneCos我们看到,在视频的开头,程序正在跟踪女孩的右眼,而在 0:15 开始跟踪女孩的眉毛,在 0:19 开始跟踪男孩的眉毛,但不再跟踪女孩的眼睛,例如,在 0:27,它跟踪女孩的右眉,而女孩的右眼在图像中清晰可见。

这种从跟踪眼睛到跟踪眉毛的漂移在我发布的简单代码中是正常的,解释也很简单:参见 https://www.youtube.com/watch?v=sGHEu3u9XvI 处的视频。 ,视频从扑克牌的跟踪(黑色矩形的内容)开始,然后我从场景中取出扑克牌,跟踪黑色矩形“漂移”到场景的左下方;毕竟我们不断更新模板,所以行为是正确的:程序停止跟踪扑克牌并开始跟踪白色背景,所以你有“漂移”......换句话说,你的 TplMatch () 函数将始终返回有效的 result 图像,而您当前的 minmax() 实现将始终返回有效的最小值。

关于c++ - 实时模板匹配 - OpenCV,C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20180073/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com