获取已在 OpenCV C++ 中的跟踪算法中跟踪的 ROI 的 x 和 y 像素坐标
Get the x and y pixel co-ordinates of the ROI that has been tracked in a tracking algorithm in OpenCV C++
我有一个跟踪程序,如下所示。我在视频的第一帧中绘制了两个 ROI(矩形框),并且在整个视频中跟踪了这些 ROI 中的对象。我想获得将在视频中跟踪的 ROI 的 x 和 y 坐标(即视频所有帧中 2 个 ROI 的位置)。我在调试时可以看到这些值,但是当我尝试为每一帧使用 bboxes[0].x,bboxes[0].y,bboxes[1].x,bboxes[1].y
打印它们时,我得到了所有帧的相同值。我在这里做错了什么?
#include <opencv2/opencv.hpp>
#include <opencv2/tracking.hpp>
#include "opencv2/highgui.hpp"
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
using namespace cv;
using namespace std;
// Convert to string
//#define SSTR( x ) static_cast< std::ostringstream & >( \
( std::ostringstream() << std::dec << x ) ).str()
vector<string> trackerTypes = { "BOOSTING", "MIL", "KCF", "TLD", "MEDIANFLOW", "GOTURN", "MOSSE", "CSRT" };
// create tracker by name
Ptr<Tracker> createTrackerByName(string trackerType)
{
Ptr<Tracker> tracker;
if (trackerType == trackerTypes[0])
tracker = TrackerBoosting::create();
else if (trackerType == trackerTypes[1])
tracker = TrackerMIL::create();
else if (trackerType == trackerTypes[2])
tracker = TrackerKCF::create();
else if (trackerType == trackerTypes[3])
tracker = TrackerTLD::create();
else if (trackerType == trackerTypes[4])
tracker = TrackerMedianFlow::create();
else if (trackerType == trackerTypes[5])
tracker = TrackerGOTURN::create();
else if (trackerType == trackerTypes[6])
tracker = TrackerMOSSE::create();
else if (trackerType == trackerTypes[7])
tracker = TrackerCSRT::create();
else {
cout << "Incorrect tracker name" << endl;
cout << "Available trackers are: " << endl;
for (vector<string>::iterator it = trackerTypes.begin(); it != trackerTypes.end(); ++it)
std::cout << " " << *it << endl;
}
return tracker;
}
// Fill the vector with random colors
void getRandomColors(vector<Scalar> &colors, int numColors)
{
RNG rng(0);
for (int i = 0; i < numColors; i++)
colors.push_back(Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)));
}
int main(int argc, char * argv[])
{
cout << "Available tracking algorithms are:" << endl;
for (vector<string>::iterator it = trackerTypes.begin(); it != trackerTypes.end(); ++it)
std::cout << " " << *it << endl;
string trackerType = "KCF";
cout << "The Selected tracker is " << trackerType << endl;
string videoPath = "SS-100_zoom_Trim.mp4";
// Initialize MultiTracker with tracking algo
vector<Rect> bboxes;
Mat frame;
cv::VideoCapture cap(videoPath);
//cap.set(CV_CAP_PROP_FRAME_WIDTH, 1280);
//cap.set(CV_CAP_PROP_FRAME_HEIGHT, 720);
if (!cap.isOpened())
{
cout << "Error opening video file " << videoPath << endl;
return -1;
}
cap >> frame;
bool showCrosshair = true;
bool fromCenter = false;
cv::selectROIs("MultiTracker", frame, bboxes, showCrosshair, fromCenter);
if (bboxes.size() < 1)
return 0;
vector<Scalar> colors;
getRandomColors(colors, bboxes.size());
// Create multitracker
Ptr<MultiTracker> multiTracker = cv::MultiTracker::create();
// initialize multitracker
for (int i = 0; i < bboxes.size(); i++)
multiTracker->add(createTrackerByName(trackerType), frame, Rect2d(bboxes[i]));
cout << "Started tracking, press ESC to quit." << endl;
while (cap.isOpened())
{
cap >> frame;
if (frame.empty()) break;
//update the tracking result with new frame
multiTracker->update(frame);
putText(frame, trackerType + " Tracker", Point(100, 20), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(50, 170, 50), 2);
// draw tracked objects
for (unsigned i = 0; i < multiTracker->getObjects().size(); i++)
{
rectangle(frame, multiTracker->getObjects()[i], colors[i], 2, 1);
}
cout << "\nPosition of box1 in X-axis :" << bboxes[0].x << endl;
cout << "\nPosition of box1 in Y-axis :" << bboxes[0].y << endl;
cout << "\nPosition of box2 in X-axis :" << bboxes[1].x << endl;
cout << "\nPosition of box2 in Y-axis :" << bboxes[1].y << endl;
resize(frame, frame, Size(1280, 720), 0, 0, INTER_CUBIC);
imshow("MultiTracker", frame);
if (waitKey(1) == 27) break;
}
}
bboxes.size() 是 2 ,因为我只画了 2 个 ROI。我正在使用 OpenCV 3.4.1 和 Visual Studio 2015
这是我得到的输出样本
您的 bboxes[]
变量似乎用于初始化,但之后没有更新。您可以尝试使用 multiTracker->getObjects()
的输出作为 x 和 y 坐标,就像您在绘制矩形时已经在做的那样。
如@Nicolas Gaborel 所述,您没有更新 bboxes
的值。有两种方法可以做到这一点
如果顺序无关紧要,那么只需在 for-loop
中执行 bboxes[i] = multiTracker->getObjects()[i]
如果您还想跟踪订单,则需要为检测到的箱子分配某种 ID。一种快速的方法是首先计算矩形的质心并存储它们。检测到对象后,您将计算对象矩形的质心。此后计算检测到的对象的质心与存储在 bboxes
中的欧几里德距离。 bboxes
中距离最小的矩形是正确的。
我有一个跟踪程序,如下所示。我在视频的第一帧中绘制了两个 ROI(矩形框),并且在整个视频中跟踪了这些 ROI 中的对象。我想获得将在视频中跟踪的 ROI 的 x 和 y 坐标(即视频所有帧中 2 个 ROI 的位置)。我在调试时可以看到这些值,但是当我尝试为每一帧使用 bboxes[0].x,bboxes[0].y,bboxes[1].x,bboxes[1].y
打印它们时,我得到了所有帧的相同值。我在这里做错了什么?
#include <opencv2/opencv.hpp>
#include <opencv2/tracking.hpp>
#include "opencv2/highgui.hpp"
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
using namespace cv;
using namespace std;
// Convert to string
//#define SSTR( x ) static_cast< std::ostringstream & >( \
( std::ostringstream() << std::dec << x ) ).str()
vector<string> trackerTypes = { "BOOSTING", "MIL", "KCF", "TLD", "MEDIANFLOW", "GOTURN", "MOSSE", "CSRT" };
// create tracker by name
Ptr<Tracker> createTrackerByName(string trackerType)
{
Ptr<Tracker> tracker;
if (trackerType == trackerTypes[0])
tracker = TrackerBoosting::create();
else if (trackerType == trackerTypes[1])
tracker = TrackerMIL::create();
else if (trackerType == trackerTypes[2])
tracker = TrackerKCF::create();
else if (trackerType == trackerTypes[3])
tracker = TrackerTLD::create();
else if (trackerType == trackerTypes[4])
tracker = TrackerMedianFlow::create();
else if (trackerType == trackerTypes[5])
tracker = TrackerGOTURN::create();
else if (trackerType == trackerTypes[6])
tracker = TrackerMOSSE::create();
else if (trackerType == trackerTypes[7])
tracker = TrackerCSRT::create();
else {
cout << "Incorrect tracker name" << endl;
cout << "Available trackers are: " << endl;
for (vector<string>::iterator it = trackerTypes.begin(); it != trackerTypes.end(); ++it)
std::cout << " " << *it << endl;
}
return tracker;
}
// Fill the vector with random colors
void getRandomColors(vector<Scalar> &colors, int numColors)
{
RNG rng(0);
for (int i = 0; i < numColors; i++)
colors.push_back(Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)));
}
int main(int argc, char * argv[])
{
cout << "Available tracking algorithms are:" << endl;
for (vector<string>::iterator it = trackerTypes.begin(); it != trackerTypes.end(); ++it)
std::cout << " " << *it << endl;
string trackerType = "KCF";
cout << "The Selected tracker is " << trackerType << endl;
string videoPath = "SS-100_zoom_Trim.mp4";
// Initialize MultiTracker with tracking algo
vector<Rect> bboxes;
Mat frame;
cv::VideoCapture cap(videoPath);
//cap.set(CV_CAP_PROP_FRAME_WIDTH, 1280);
//cap.set(CV_CAP_PROP_FRAME_HEIGHT, 720);
if (!cap.isOpened())
{
cout << "Error opening video file " << videoPath << endl;
return -1;
}
cap >> frame;
bool showCrosshair = true;
bool fromCenter = false;
cv::selectROIs("MultiTracker", frame, bboxes, showCrosshair, fromCenter);
if (bboxes.size() < 1)
return 0;
vector<Scalar> colors;
getRandomColors(colors, bboxes.size());
// Create multitracker
Ptr<MultiTracker> multiTracker = cv::MultiTracker::create();
// initialize multitracker
for (int i = 0; i < bboxes.size(); i++)
multiTracker->add(createTrackerByName(trackerType), frame, Rect2d(bboxes[i]));
cout << "Started tracking, press ESC to quit." << endl;
while (cap.isOpened())
{
cap >> frame;
if (frame.empty()) break;
//update the tracking result with new frame
multiTracker->update(frame);
putText(frame, trackerType + " Tracker", Point(100, 20), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(50, 170, 50), 2);
// draw tracked objects
for (unsigned i = 0; i < multiTracker->getObjects().size(); i++)
{
rectangle(frame, multiTracker->getObjects()[i], colors[i], 2, 1);
}
cout << "\nPosition of box1 in X-axis :" << bboxes[0].x << endl;
cout << "\nPosition of box1 in Y-axis :" << bboxes[0].y << endl;
cout << "\nPosition of box2 in X-axis :" << bboxes[1].x << endl;
cout << "\nPosition of box2 in Y-axis :" << bboxes[1].y << endl;
resize(frame, frame, Size(1280, 720), 0, 0, INTER_CUBIC);
imshow("MultiTracker", frame);
if (waitKey(1) == 27) break;
}
}
bboxes.size() 是 2 ,因为我只画了 2 个 ROI。我正在使用 OpenCV 3.4.1 和 Visual Studio 2015
这是我得到的输出样本
您的 bboxes[]
变量似乎用于初始化,但之后没有更新。您可以尝试使用 multiTracker->getObjects()
的输出作为 x 和 y 坐标,就像您在绘制矩形时已经在做的那样。
如@Nicolas Gaborel 所述,您没有更新 bboxes
的值。有两种方法可以做到这一点
如果顺序无关紧要,那么只需在 for-loop
中执行 如果您还想跟踪订单,则需要为检测到的箱子分配某种 ID。一种快速的方法是首先计算矩形的质心并存储它们。检测到对象后,您将计算对象矩形的质心。此后计算检测到的对象的质心与存储在
bboxes
中的欧几里德距离。bboxes
中距离最小的矩形是正确的。
bboxes[i] = multiTracker->getObjects()[i]