模板与模板更新匹配
Template Matching with template update
本文关键字:更新 更新时间:2023-10-16
我正在尝试使用OpenCV/C++中的模板实现实时跟踪。我面临着用每一帧更新模板的问题。
以下是代码:
#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; //select_flag is kept false so that new template can
go_fast = true; //copied to 'mytemplate' for each iteration
}
// imshow( "mytemplate", mytemplate ); waitKey(0);
Mat result = TplMatch( img, mytemplate );
Point match = minmax( result ); //PROBLEM: "match" always returning same value!!!
rectangle( img, match, Point( match.x + mytemplate.cols , match.y + mytemplate.rows ), CV_RGB(255, 255, 255), 0.5 );
std::cout << "match: " << match << endl;
/// template update step
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);
}
if (event == CV_EVENT_LBUTTONUP)
{
/// ROI selected
select_flag = 1;
drag = 0;
}
}
///------- Main() ----------------------------------------------------------------------------------------------------------
int main()
{
int k;
///open video file
VideoCapture cap;
cap.open( "Megamind.avi" );
if ( !cap.isOpened() )
{ cout << "Unable to open video file" << endl; return -1; }
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);
k = waitKey(go_fast ? 30 : 10000);
if (k == 27)
break;
}
return 0;
}
未跟踪更新的模板。我不知道为什么会发生这种情况,因为我每次迭代都在更新我的模板(roiImg)。minmax()函数的match值每次都返回相同的值(坐标)。测试视频可在以下网址获取:Megamind请仔细观察并指引前方。。。非常感谢!
编辑:如果您运行代码(与视频一起),您将看到白色边界框始终位于同一位置。这是因为,minmax()始终返回相同的"匹配"值。此值应随每次更新而更改。尝试运行select_flag=false的代码(未提交)。边界框正在根据模板移动。但在这种情况下,不会进行模板更新。
问题出现在本节中:
if (select_flag)
{
roiImg.copyTo(mytemplate);
// select_flag = false; //select_flag is kept false so that new template can
// ^^^^^^^^^^^ WRONG
go_fast = true; //copied to 'mytemplate' for each iteration
}
实际上,您需要在第一次迭代中将select_flag
设置为false
。否则,您只是将该帧上当前图像中的内容复制到模板中,当然,您会在完全相同的位置找到它!
完成后,请确保在该帧上完成跟踪后将模板更新移动到。我还建议在完成所有图像访问之前不要在原始图像(rectangle
)上绘制。你实际上是在复制出图像之前将矩形绘制到图像中。以下是我调整后的模板更新功能:
void track()
{
std::cout << select_flag << std::endl;
if (select_flag)
{
roiImg.copyTo(mytemplate);
select_flag = false; //select_flag is kept false so that new template can
go_fast = true; //copied to 'mytemplate' for each iteration
}
// imshow( "mytemplate", mytemplate ); waitKey(0);
Mat result = TplMatch( img, mytemplate );
imshow("match", result);
Point match = minmax( result ); //PROBLEM: "match" always returning same value!!!
std::cout << "match: " << match << endl;
/// template update step
Rect ROI = cv::Rect( match.x, match.y, mytemplate.cols, mytemplate.rows );
std::cout << ROI << std::endl;
roiImg = img( ROI );
imshow( "roiImg", roiImg ); //waitKey(0);
// Update the template AFTER tracking has occurred to carry it over to the next frame
roiImg.copyTo(mytemplate);
imshow("mytemplate", mytemplate);
// Draw onto the image AFTER all accesses are performed
rectangle( img, match, Point( match.x + mytemplate.cols , match.y + mytemplate.rows ), CV_RGB(255, 255, 255), 0.5 );
}
相关文章:
- 从C++本机插件更新Vector3数组
- QGraphicsPolygonItem在拖动时未更新QPolygonF坐标
- cmake更新缓存的变量
- 更新到莫哈韦后出现cmath错误
- OpenMP:并行更新数组总是需要减少数组吗
- 为什么我的变量没有更新,我的 LED 没有亮起?
- 指针没有更新它在void函数内部指向的值
- 如何在c++中获取要更新的值
- 已修改的LinkedList未在文本文件本身中更新
- Qt:当QListView获得新条目时,如何更新QStringList
- 更新的矢量元素不打印
- 如何使用按钮更新GTK3图像以使用C++从相机捕获图片
- 如何在ECS框架中更新组件数据和通知系统
- 从VS 2015更新3更新到VS2015更新3 d后浮点计算行为不同的原因
- 如果我想在没有更新编译器的情况下使用新功能,该怎么办?
- 如何在 C++11 中查找和更新向量中的一个嵌套结构
- (SFML)按下键时,播放器构造函数未使用正确的动画进行更新
- 在 emscripten 网页汇编正在运行期间更新进度条?
- 在运行时使用范围更新结果
- 用非原子更新原子变量,反之亦然