Ask Your Question

Crazed's profile - activity

2017-07-28 16:00:51 -0600 asked a question 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 ...
(more)
2017-07-26 12:15:25 -0600 commented question VS2010 C++ OpenCV Tracking Shapes in Motion not Working Correctly

Just for learning's sake: Why would just threshold have an issue because of the libs used, and why does it behave this way in this code when I have used the same function (threshold) in a different project with the same property sheets and compiler?

2017-07-26 12:10:40 -0600 commented question VS2010 C++ OpenCV Tracking Shapes in Motion not Working Correctly

No - I'm using vc14 libs from OpenCV 3.2.0 off the SourceForge download link. I tried using Cmake and didn't get very far. I am using Debug libs in Debug and Release libs in Release, however.

2017-07-25 21:07:02 -0600 asked a question VS2010 C++ OpenCV Tracking Shapes in Motion not Working Correctly

The below code attempts to track shapes in motion, and runs without error - however, it does not work as intended. It's purpose is to draw a perimeter around the polygons detected in the camera feed for ever frame, with the perimeter color dependent on the number of vertices (i.e. the shape). However, as depicted by the cout statements in and above the for loop in the processFrame method, no contours are ever detected by the program. Why might this be? Are there other issues hindering this code from fulfilling its objective? Any help is more than appreciated.

ALSO: threshold is commented out because it triggers a breakpoint when run.

ALSO: I'm pretty sure threshold is the reason my code doesn't work - no contours are found without thresholding, but thresholding triggers a breakpoint.

ALSO: Console window output is an infinite steam of 0, one on each line (this is the number of contours detected).

#include <sstream>
#include <string>
#include <iostream>
#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;

void process_contour(cv::Mat& frame, std::vector<cv::Point> const& contour)
{
    cv::Scalar TRIANGLE_COLOR(255, 0, 0);
    cv::Scalar QUADRILATERAL_COLOR(0, 255, 0);
    cv::Scalar HEPTAGON_COLOR(0, 0, 255);

    cv::Scalar colour;
    if (contour.size() == 3) {
        colour = TRIANGLE_COLOR;
    } else if (contour.size() == 4) {
        colour = QUADRILATERAL_COLOR;
    } else if (contour.size() == 7) {
        colour = HEPTAGON_COLOR;
    } else {
        return;
    }

    cv::Point const* points(&contour[0]);
    int n_points(static_cast<int>(contour.size()));

    polylines(frame, &points, &n_points, 1, true, colour, 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);
    //cv::inRange(feedGrayScale,cv::Scalar(25,130,105),cv::Scalar(40,195,150),feedGrayScale);
    frame.copyTo(result_frame);

    //thresholding the grayscale image to get better results
    //cv::threshold(feedGrayScale, feedGrayScale, 128, 255, cv::THRESH_BINARY);
    cv::findContours(feedGrayScale, contours, hierarchy, CV_RETR_TREE,CV_CHAIN_APPROX_SIMPLE );
    std::cout << contours.size() << std::endl;

    for (size_t k(0); k < contours.size(); ++k) {
        std::cout << "IT WORKS!" << std::endl;
        std::vector<cv::Point> approx_contour;
        cv::approxPolyDP(cv::Mat(contours[k]), approx_contour, 3, true);
        process_contour(result_frame, approx_contour);
    }
}

int main()
{
    cv::VideoCapture cap(0); // open the video camera no. 0

    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;
}
2017-07-25 18:16:38 -0600 received badge  Organizer (source)