Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Improving the Rate at Which a File is Written To

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