装甲块识别(2)——Tracker跟踪器

简介:
本算法使用了OpenCV自带Tracker,设定使用了其中的TLD跟踪器。该跟踪器使用Median-Flow追踪算法(光流跟踪器)。
优点:
1.不会跟踪丢失目标(其他跟踪器会跟踪丢,但可以通过重新匹配到ROI来补偿)
2.大的程度上跟踪比较稳定,每帧的目标都跟踪的比较符合实际情况
缺点:
1.虽然能跟踪上,但有时标识框选区域比较歪曲,偏小或溢出
2.计算量比较大,处理速度比较慢(我电脑性能不高也是一个原因)

编程思路:

选择tracker算法(TLD) -> 通过模板匹配找到第一桢ROI
-> 使用该算法循环处理视频每一帧,跟踪成功,继续
————————————————跟踪不成功就重新模板匹配到ROI,继续
-> 在当前帧标注 算法名,处理时FPS,目标中心点坐标,导出.bmp图片
-> 将图片以FPS=20接成.avi视频并播放

global.h

#include "global.h"#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include using namespace cv;
using namespace std;Rect2d _tempImgframe(Mat *frame);
void img2video();

img2video.cpp

#include "global.h"void img2video()
{// 读取输出的图片Mat src = imread("D:\\openCV_file\\coins_matchTemplate\\coins_matchTemplate\\out\\00001.bmp");char imgName[200];   // Iamge name read inint isColor = 1;     // RGBint fps = 20;int frameWidth = src.cols;int frameHeight = src.rows;Mat Video;// Output Video// 确定输出视频地址及文件名VideoWriter writer("D:\\openCV_file\\coins_matchTemplate\\coins_matchTemplate\\TLD.avi", VideoWriter::fourcc('M', 'J', 'P', 'G'), fps, Size(frameWidth, frameHeight), isColor);// Play Videofor (int i = 1; i < 1000; i++){sprintf_s(imgName, "D:\\openCV_file\\coins_matchTemplate\\coins_matchTemplate\\out\\%05d.bmp", i);//将图片名放入字符串src = imread(imgName, 1);if (src.empty()){cout << "Error!Can't read the image!" << endl;break;}imshow("Output Video", src);waitKey(5);writer.write(src);//输出视频}
}

templateImg.cpp

#include "global.h"// description: Use template matching to determine ROI
// 描述:使用模板匹配确定感兴趣区域ROI
Rect2d _tempImgframe(Mat *frame)
{Mat tempImg = imread("a.bmp");imshow("tempImg", tempImg);waitKey(50);Mat result;// int result_cols = frame->cols - tempImg.cols + 1;int result_rows = frame->rows - tempImg.rows + 1;result.create(result_cols, result_rows, CV_32FC1);matchTemplate(*frame, tempImg, result, CV_TM_SQDIFF_NORMED);normalize(result, result, 0, 1, NORM_MINMAX, -1, Mat());double minVal = -1;double maxVal;Point minLoc;Point maxLoc;Point matchLoc;cout << "匹配度:" << minVal << endl;minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc, Mat());cout << "匹配度:" << minVal << endl;matchLoc = minLoc;Rect2d ans = Rect(matchLoc.x, matchLoc.y, tempImg.cols, tempImg.rows);return ans;
}

如果对opencv中的 col 和 row 感到迷惑,可以看看下面这篇 点我跳转

main.cpp

#include "global.h"// List of tracker types in OpenCV 3.4.6
string trackerTypes[7] = { "BOOSTING", "MIL", "KCF", "TLD","MEDIANFLOW", "GOTURN", "MOSSE" };
Rect2d bboxTarget;float x_label = 0.0, y_label = 0.0;// 如果opencv的版本低于3
#if (CV_MINOR_VERSION < 3){tracker = Tracker::create(trackerType);}
#else{if (trackerType == "BOOSTING")tracker = TrackerBoosting::create();if (trackerType == "MIL")tracker = TrackerMIL::create();if (trackerType == "KCF")tracker = TrackerKCF::create();if (trackerType == "TLD")tracker = TrackerTLD::create();if (trackerType == "MEDIANFLOW")tracker = TrackerMedianFlow::create();if (trackerType == "GOTURN")tracker = TrackerGOTURN::create();if (trackerType == "MOSSE")tracker = TrackerMOSSE::create();}
#endifreturn tracker;
}// bbox: 选择的区域
int main(int argc, char **argv)
{// Choose the method you want to use// 选择你想用的跟踪器int trackerMethod = 2;// Read videoVideoCapture video("IdentifyArmor.avi");// Exit if video is not opened// 如果没有该videoif (!video.isOpened()){cout << "Could not read video file" << endl;return 1;} // Read first frame Mat frame; bool ok = video.read(frame); // Define initial boundibg box // 定义初始框大小Rect2d bbox(287, 23, 86, 320); // Target determination by template matching// 通过模板匹配确定目标,并返回一个具有坐标性质的的框(有坐标性质才能准确地在frame上框出ROI)bbox = _tempImgframe(&frame);// Display bounding box. // 在第一帧上都将该框显示出来,即完成了ROI的标识rectangle(frame, bbox, Scalar( 255, 0, 0 ), 2, 1 ); bboxTarget = bbox;imshow("Tracking", frame);waitKey(50);tracker->init(frame, bbox);// frameCnt:当前第几桢int frameCnt = 0;// 循环读取每一帧while (video.read(frame)){frameCnt++;// process once per n frame/*if (frameCnt % 10 < 0)continue;*/// Start timerdouble timer = (double)getTickCount();// Update the tracking resultbool ok = tracker->update(frame, bbox);// compute the central point(x,y)x_label = bbox.x + cvRound(bbox.width / 2.0);y_label = bbox.y + cvRound(bbox.height / 2.0);// Calculate Frames per second (FPS)float fps = getTickFrequency() / ((double)getTickCount() - timer);// 如果跟踪到了,就在当前帧框出ROIif (ok){// Tracking success : Draw the tracked objectrectangle(frame, bbox, Scalar(255, 0, 0), 2, 1);}// 如果没跟踪到,就重新匹配,本处依然使用模板匹配else{// Tracking failure detected.// putText(frame, "Tracking failure detected", Point(100, 80), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(0, 0, 255), 2);// reTargetbbox = _tempImgframe(&frame);rectangle(frame, bbox, Scalar(255, 0, 0), 2, 1);bboxTarget = bbox;//imshow("Tracking", frame);//waitKey(50);tracker->init(frame, bbox);}// Display tracker type on frameputText(frame, trackerTypes[trackerMethod] + " Tracker", Point(100, 20), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(50, 170, 50), 2);// Display FPS on framechar fpsStr[10];sprintf_s(fpsStr, "FPS : %d", int(fps));putText(frame, fpsStr, Point(100, 40), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(50, 170, 50), 2);// Display coordinate// 显示当前ROI的中心坐标char coordinate[100];sprintf_s(coordinate, "x:%d y:%d", int(x_label), int(y_label));putText(frame, coordinate, Point(100, 60), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(50, 170, 50), 2);// Display frame.imshow("Tracking", frame);waitKey(50);// Save framechar imgSaveName[200];sprintf_s(imgSaveName, "D:\\openCV_file\\coins_matchTemplate\\coins_matchTemplate\\out\\%05d.bmp", frameCnt);imwrite(imgSaveName, frame);// Exit if ESC pressed.// 按ESC即退出,此时k是返回了ASCII值27int k = waitKey(1);if (k == 27)break;}img2video();
}

解释一下:我的电脑配置不是很好,所以FPS基本都在5桢以下…
在这里插入图片描述
在这里插入图片描述

部分借鉴 https://www.cnblogs.com/annie22wang/p/9366610.html , 有改动


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部