The below code aims to track objects based on their shape (by means of vertices) from a camera feed. Although this code works without error, the file which stores information about the tracked objects (position, shape, time at which data was logged) is written to only about 30 times per second. I would like to significantly improve this rate (preferably to about 100 times per second). I have tried changing the camera being used, which can capture far more than 100 fps, but this has had no impact on the aforementioned issue, and yields the same results as a 30 fps webcam. Is there something in my code that slows the process down unnecessarily, or is there something I can add to my code to speed it up? Any help is more than appreciated.
Code:
#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_;
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)
{
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;
}
}
file_ << "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;
}
}
file_ << "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;
}
}
file_ << "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;
}
}
file_ << "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)
{
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);
cv::imshow("Threshold", 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);
}
}
int main()
{
file_.open("shape_data.txt");
cv::VideoCapture cap(0); // 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()) // if not success, exit program
{
std::cout << "Cannot open the video cam\n";
return -1;
}
//cv::namedWindow("Original", CV_WINDOW_AUTOSIZE);
cv::namedWindow("Tracked", CV_WINDOW_AUTOSIZE);
// Process frames from the video stream...
for(;;) {
cv::Mat frame, result_frame;
// read a new frame from video
if (!cap.read(frame)) {
std::cout << "Cannot read a frame from video stream\n";
break;
}
process_frame(frame, result_frame);
//cv::imshow("Original", frame);
cv::imshow("Tracked", result_frame);
if (cv::waitKey(20) == 27) { // Quit on ESC
break;
}
}
return 0;
}
Sample Portion of text file being written to:
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