Приведенный ниже код предназначен для отслеживания объектов на основе их формы (с помощью вершин) с камеры. Хотя этот код работает без ошибок, файл, в котором хранится информация об отслеживаемых объектах (положение, форма, время регистрации данных), записывается всего около 30 раз в секунду. Я хотел бы значительно улучшить эту скорость (желательно примерно до 100 раз в секунду). Я попытался изменить используемую камеру, которая может снимать со скоростью более 100 кадров в секунду, но это не повлияло на вышеупомянутую проблему и дает те же результаты, что и веб-камера со скоростью 30 кадров в секунду. Есть ли в моем коде что-то, что излишне замедляет процесс, или есть что-то, что я могу добавить в свой код, чтобы ускорить его? Любая помощь более чем приветствуется.
EDIT: я совсем забыл - спасибо Dan Mašek за написание большая часть приведенного ниже кода.
РЕДАКТИРОВАНИЕ: здесь представлено видео отслеживания в в этом случае всего один четырехугольник на сферической поверхности.
РЕДАКТИРОВАТЬ: Сейчас моя цель состоит в том, чтобы зарегистрировать "центроид" фигур, обозначенных этой программой, для отслеживания в файле данных как можно точнее (что я реализовал), предпочтительно по крайней мере 100 зарегистрированных точек данных в секунду (с чем я продолжаю бороться).
РЕДАКТИРОВАНИЕ: измененный код для включения двух камер, каждая из которых записывает в отдельный текстовый файл. В настоящее время оба записываются в shape_data1.txt
, поэтому на самом деле это работает неправильно. Кроме того, findPos()
был удален, потому что на самом деле он не регистрировал позицию, а только миллисекундное значение текущего времени процессора.
Код:
#include <fstream>
#include <time.h>
#include<opencv2\opencv.hpp>
#include<opencv2\highgui\highgui.hpp>
std::vector<std::vector<cv::Point> > contours;
std::vector<cv::Vec4i> hierarchy;
std::ofstream file_;
std::ofstream file1_;
void morphOps(cv::Mat &thresh){
//create structuring element that will be used to "dilate" and "erode" image.
//the element chosen here is a 3px by 3px rectangle
cv::Mat erodeElement = cv::getStructuringElement( cv::MORPH_RECT,cv::Size(10,10));
//dilate with larger element so make sure object is nicely visible
cv::Mat dilateElement = cv::getStructuringElement( cv::MORPH_RECT,cv::Size(10,10));
cv::erode(thresh,thresh,erodeElement);
cv::erode(thresh,thresh,erodeElement);
cv::dilate(thresh,thresh,dilateElement);
cv::dilate(thresh,thresh,dilateElement);
}
void process_contour(cv::Mat& frame, std::vector<cv::Point> const& contour, int num)
{
clock_t t;
t = clock();
int minArea = 100;
int x1,y1;
cv::Scalar TRIANGLE_COLOR(0, 0, 255);
cv::Scalar QUADRILATERAL_COLOR(0, 255, 0);
cv::Scalar HEPTAGON_COLOR(255, 0, 0);
cv::Scalar DECA_COLOR(126, 126, 0);
cv::Scalar color;
if (contour.size() == 3 && contourArea(contour) > minArea) {
color = TRIANGLE_COLOR;
for (int index = 0; index >= 0; index = hierarchy[index][0]) {
cv::Moments moment = cv::moments((cv::Mat)contours[index]);
double area = moment.m00;
if(area > minArea){
x1 = moment.m10/area;
y1 = moment.m01/area;
}
}
if (num = 0) {
file_ << "Triangle " << "X: " << x1 << " Y: " << y1 << " " << /*"Area: " << contourArea(contour) << " " <<*/ double(t)/CLOCKS_PER_SEC << " seconds" << "\n";
} else {
file1_ << "Triangle " << "X: " << x1 << " Y: " << y1 << " " << /*"Area: " << contourArea(contour) << " " <<*/ double(t)/CLOCKS_PER_SEC << " seconds" << "\n";
}
} else if (contour.size() == 4 && contourArea(contour) > minArea) {
color = QUADRILATERAL_COLOR;
for (int index = 0; index >= 0; index = hierarchy[index][0]) {
cv::Moments moment = cv::moments((cv::Mat)contours[index]);
double area = moment.m00;
if(area > minArea){
x1 = moment.m10/area;
y1 = moment.m01/area;
}
}
if (num = 0) {
file_ << "Quadrilateral " << "X: " << x1 << " Y: " << y1 << " " << /*"Area: " << contourArea(contour) << " " <<*/ double(t)/CLOCKS_PER_SEC << " seconds" << "\n";
} else {
file1_ << "Quadrilateral " << "X: " << x1 << " Y: " << y1 << " " << /*"Area: " << contourArea(contour) << " " <<*/ double(t)/CLOCKS_PER_SEC << " seconds" << "\n";
}
} else if (contour.size() == 7 && contourArea(contour) > minArea) {
color = HEPTAGON_COLOR;
for (int index = 0; index >= 0; index = hierarchy[index][0]) {
cv::Moments moment = cv::moments((cv::Mat)contours[index]);
double area = moment.m00;
if(area > minArea){
x1 = moment.m10/area;
y1 = moment.m01/area;
}
}
if (num = 0) {
file_ << "Heptagon " << "X: " << x1 << " Y: " << y1 << " " << /*"Area: " << contourArea(contour) << " " <<*/ double(t)/CLOCKS_PER_SEC << " seconds" << "\n";
} else {
file1_ << "Heptagon " << "X: " << x1 << " Y: " << y1 << " " << /*"Area: " << contourArea(contour) << " " <<*/ double(t)/CLOCKS_PER_SEC << " seconds" << "\n";
}
} else if (contour.size() == 10 && contourArea(contour) > minArea) {
color = DECA_COLOR;
for (int index = 0; index >= 0; index = hierarchy[index][0]) {
cv::Moments moment = cv::moments((cv::Mat)contours[index]);
double area = moment.m00;
if(area > minArea){
x1 = moment.m10/area;
y1 = moment.m01/area;
}
}
if (num = 0) {
file_ << "Decagon " << "X: " << x1 << " Y: " << y1 << " " << /*"Area: " << contourArea(contour) << " " <<*/ double(t)/CLOCKS_PER_SEC << " seconds" << "\n";
} else {
file1_ << "Decagon " << "X: " << x1 << " Y: " << y1 << " " << /*"Area: " << contourArea(contour) << " " <<*/ double(t)/CLOCKS_PER_SEC << " seconds" << "\n";
}
} else {
return;
}
cv::Point const* points(&contour[0]);
int n_points(static_cast<int>(contour.size()));
polylines(frame, &points, &n_points, 1, true, color, 4);
}
void process_frame(cv::Mat const& frame, cv::Mat& result_frame, int num)
{
cv::Mat feedGrayScale;
cv::cvtColor(frame, feedGrayScale, cv::COLOR_BGR2GRAY);
//cv::imshow("Grayscale", feedGrayScale);
frame.copyTo(result_frame);
//thresholding the grayscale image to get better results
cv::threshold(feedGrayScale, feedGrayScale, 128, 255, cv::THRESH_BINARY);
//morphOps(feedGrayScale);
if (num = 0) {
cv::imshow("Threshold - Webcam", feedGrayScale);
}
if (num = 1) {
cv::imshow("Threshold - Basler Cam", feedGrayScale);
}
cv::findContours(feedGrayScale, contours, hierarchy, CV_RETR_TREE,CV_CHAIN_APPROX_SIMPLE );
for (size_t k(0); k < contours.size(); ++k) {
std::vector<cv::Point> approx_contour;
cv::approxPolyDP(cv::Mat(contours[k]), approx_contour, 3, true);
process_contour(result_frame, approx_contour, num);
}
}
int main()
{
file_.open("shape_data.txt");
file1_.open("shape_data1.txt");
cv::VideoCapture cap(0); // open the video camera no.0
cv::VideoCapture cap1(1); // open the video camera no.0
//cap.set(CV_CAP_PROP_FRAME_WIDTH,1000);
//cap.set(CV_CAP_PROP_FRAME_HEIGHT,1000);
//cap.set(CV_CAP_PROP_FPS,120);
//cap.set(CV_CAP_PROP_FOURCC, CV_FOURCC('M', 'J', 'P', 'G'));
if (!cap.isOpened() || !cap1.isOpened()) // if not success, exit program
{
std::cout << "Cannot open the video cam\n";
return -1;
}
//cv::namedWindow("Original", CV_WINDOW_AUTOSIZE);
cv::namedWindow("Tracked - Webcam", CV_WINDOW_AUTOSIZE);
cv::namedWindow("Tracked - Basler Cam", CV_WINDOW_AUTOSIZE);
// Process frames from the video stream...
for(;;) {
cv::Mat frame, result_frame;
cv::Mat frame1, result_frame1;
// read a new frame from video
if (!cap.read(frame)) {
std::cout << "Cannot read a frame from video stream\n";
break;
}
if (!cap1.read(frame1)) {
std::cout << "Cannot read a frame from video stream\n";
break;
}
process_frame(frame, result_frame, 0);
process_frame(frame1, result_frame1, 1);
cv::imshow("Tracked - Webcam", result_frame);
cv::imshow("Tracked - Basler Cam", result_frame1);
cv::waitKey(1);
}
return 0;
}
Образец части текстового файла, который записывается в:
Quadrilateral X: 361 Y: 136 168.156 seconds
Quadrilateral X: 361 Y: 138 168.204 seconds
Quadrilateral X: 361 Y: 138 168.212 seconds
Quadrilateral X: 371 Y: 138 168.259 seconds
Quadrilateral X: 371 Y: 138 168.308 seconds
Quadrilateral X: 372 Y: 139 168.349 seconds
Quadrilateral X: 372 Y: 139 168.381 seconds
Quadrilateral X: 372 Y: 138 168.411 seconds
Quadrilateral X: 372 Y: 140 168.443 seconds
Quadrilateral X: 372 Y: 140 168.473 seconds
Quadrilateral X: 373 Y: 141 168.504 seconds
Quadrilateral X: 374 Y: 140 168.535 seconds
Quadrilateral X: 374 Y: 142 168.566 seconds
Quadrilateral X: 374 Y: 143 168.597 seconds
Quadrilateral X: 375 Y: 145 168.631 seconds
Quadrilateral X: 376 Y: 145 168.663 seconds
Quadrilateral X: 376 Y: 146 168.694 seconds
Quadrilateral X: 375 Y: 147 168.769 seconds
Quadrilateral X: 376 Y: 147 168.799 seconds
Quadrilateral X: 377 Y: 146 168.831 seconds
Quadrilateral X: 376 Y: 145 168.862 seconds
Quadrilateral X: 376 Y: 145 168.894 seconds
Quadrilateral X: 377 Y: 145 168.925 seconds
Quadrilateral X: 376 Y: 146 169.034 seconds
Quadrilateral X: 376 Y: 146 169.065 seconds
Quadrilateral X: 377 Y: 146 169.095 seconds
Quadrilateral X: 378 Y: 145 169.127 seconds
Quadrilateral X: 377 Y: 144 169.158 seconds
Quadrilateral X: 377 Y: 144 169.192 seconds
Quadrilateral X: 378 Y: 144 169.254 seconds
Quadrilateral X: 378 Y: 144 169.286 seconds
Quadrilateral X: 377 Y: 145 169.319 seconds
Quadrilateral X: 378 Y: 145 169.366 seconds
Quadrilateral X: 378 Y: 145 169.398 seconds
Quadrilateral X: 379 Y: 144 169.439 seconds
Quadrilateral X: 379 Y: 144 169.471 seconds
Quadrilateral X: 380 Y: 144 169.534 seconds
Quadrilateral X: 380 Y: 144 169.565 seconds
Quadrilateral X: 380 Y: 144 169.595 seconds
Quadrilateral X: 378 Y: 145 169.628 seconds
Quadrilateral X: 379 Y: 145 169.658 seconds
Quadrilateral X: 379 Y: 145 169.688 seconds
Quadrilateral X: 380 Y: 143 169.758 seconds
Quadrilateral X: 380 Y: 143 169.807 seconds
Quadrilateral X: 379 Y: 143 169.85 seconds
Quadrilateral X: 377 Y: 135 169.928 seconds
Quadrilateral X: 377 Y: 134 169.975 seconds
Quadrilateral X: 381 Y: 134 170.02 seconds
Quadrilateral X: 382 Y: 134 170.051 seconds
Quadrilateral X: 381 Y: 136 170.113 seconds
Quadrilateral X: 382 Y: 137 170.145 seconds
Quadrilateral X: 382 Y: 137 170.175 seconds
Quadrilateral X: 380 Y: 135 170.267 seconds
Quadrilateral X: 380 Y: 135 170.295 seconds
Quadrilateral X: 381 Y: 134 170.328 seconds
Quadrilateral X: 380 Y: 133 170.391 seconds
Quadrilateral X: 381 Y: 134 170.47 seconds
Quadrilateral X: 381 Y: 134 170.502 seconds
Quadrilateral X: 380 Y: 134 170.534 seconds
Quadrilateral X: 380 Y: 134 170.566 seconds
Quadrilateral X: 380 Y: 134 170.597 seconds
Quadrilateral X: 381 Y: 133 170.629 seconds
Quadrilateral X: 381 Y: 133 170.662 seconds
Quadrilateral X: 381 Y: 133 170.735 seconds
Quadrilateral X: 381 Y: 133 170.765 seconds
Quadrilateral X: 381 Y: 134 170.806 seconds
Quadrilateral X: 380 Y: 134 170.855 seconds
Quadrilateral X: 381 Y: 134 170.891 seconds
Quadrilateral X: 381 Y: 135 170.923 seconds
Quadrilateral X: 382 Y: 134 170.955 seconds
Quadrilateral X: 382 Y: 134 170.986 seconds
Quadrilateral X: 382 Y: 134 171.018 seconds
Quadrilateral X: 382 Y: 134 171.048 seconds
Quadrilateral X: 382 Y: 134 171.079 seconds
Quadrilateral X: 381 Y: 135 171.142 seconds
Quadrilateral X: 382 Y: 135 171.176 seconds
Quadrilateral X: 382 Y: 135 171.219 seconds
Quadrilateral X: 383 Y: 134 171.251 seconds
Quadrilateral X: 383 Y: 134 171.283 seconds
Quadrilateral X: 383 Y: 134 171.314 seconds
Quadrilateral X: 383 Y: 134 171.345 seconds
Quadrilateral X: 383 Y: 134 171.376 seconds
Quadrilateral X: 383 Y: 134 171.408 seconds
Quadrilateral X: 382 Y: 135 171.438 seconds
Quadrilateral X: 383 Y: 135 171.468 seconds
Quadrilateral X: 383 Y: 135 171.5 seconds
Quadrilateral X: 384 Y: 134 171.544 seconds
Quadrilateral X: 384 Y: 134 171.608 seconds
Quadrilateral X: 384 Y: 134 171.639 seconds
Quadrilateral X: 384 Y: 134 171.67 seconds
Quadrilateral X: 383 Y: 135 171.765 seconds
Quadrilateral X: 384 Y: 135 171.798 seconds
Quadrilateral X: 384 Y: 134 171.829 seconds
Quadrilateral X: 384 Y: 134 171.91 seconds
Quadrilateral X: 384 Y: 134 171.95 seconds
Quadrilateral X: 384 Y: 134 171.981 seconds
Quadrilateral X: 385 Y: 134 172.013 seconds
Quadrilateral X: 383 Y: 135 172.045 seconds
Quadrilateral X: 384 Y: 135 172.074 seconds
Quadrilateral X: 384 Y: 135 172.106 seconds
Quadrilateral X: 385 Y: 134 172.137 seconds
Quadrilateral X: 385 Y: 135 172.168 seconds
Quadrilateral X: 385 Y: 134 172.199 seconds
Quadrilateral X: 385 Y: 134 172.246 seconds
Quadrilateral X: 385 Y: 134 172.31 seconds
Quadrilateral X: 384 Y: 135 172.341 seconds
Quadrilateral X: 385 Y: 135 172.373 seconds
Quadrilateral X: 385 Y: 135 172.405 seconds
Quadrilateral X: 386 Y: 134 172.437 seconds
Quadrilateral X: 385 Y: 134 172.469 seconds
Quadrilateral X: 386 Y: 134 172.502 seconds
Quadrilateral X: 385 Y: 134 172.544 seconds
Quadrilateral X: 385 Y: 134 172.574 seconds
Quadrilateral X: 386 Y: 134 172.638 seconds
Quadrilateral X: 385 Y: 134 172.676 seconds
Quadrilateral X: 386 Y: 133 172.787 seconds
Quadrilateral X: 385 Y: 133 172.903 seconds
Quadrilateral X: 385 Y: 134 172.935 seconds
Quadrilateral X: 385 Y: 133 173.007 seconds
Quadrilateral X: 385 Y: 133 173.056 seconds
Quadrilateral X: 386 Y: 132 173.093 seconds
Quadrilateral X: 385 Y: 132 173.126 seconds
Quadrilateral X: 385 Y: 132 173.172 seconds
Quadrilateral X: 385 Y: 131 173.234 seconds
Quadrilateral X: 384 Y: 132 173.265 seconds
Quadrilateral X: 384 Y: 132 173.295 seconds
Quadrilateral X: 384 Y: 132 173.327 seconds
Quadrilateral X: 383 Y: 131 173.359 seconds
Quadrilateral X: 382 Y: 131 173.408 seconds
Quadrilateral X: 380 Y: 131 173.449 seconds
Quadrilateral X: 379 Y: 131 173.481 seconds
Quadrilateral X: 378 Y: 130 173.512 seconds
Quadrilateral X: 376 Y: 134 173.606 seconds
Quadrilateral X: 377 Y: 133 173.638 seconds
Quadrilateral X: 377 Y: 134 173.672 seconds