2017-07-28 6 views
1

Der folgende Code zielt darauf ab, Objekte basierend auf ihrer Form (mittels Scheitelpunkte) von einem Kamera-Feed zu verfolgen. Obwohl dieser Code ohne Fehler funktioniert, wird die Datei, die Informationen über die verfolgten Objekte speichert (Position, Form, Zeitpunkt, zu dem Daten protokolliert wurden) nur etwa 30 Mal pro Sekunde geschrieben. Ich möchte diese Rate signifikant verbessern (vorzugsweise auf ungefähr 100 Mal pro Sekunde). Ich habe versucht, die verwendete Kamera zu ändern, die weit mehr als 100 fps erfassen kann, aber dies hatte keine Auswirkungen auf das oben genannte Problem und führt zu den gleichen Ergebnissen wie eine 30 fps Webcam. Gibt es etwas in meinem Code, das den Prozess unnötig verlangsamt oder gibt es etwas, das ich meinem Code hinzufügen kann, um es zu beschleunigen? Jede Hilfe wird mehr als geschätzt.Optimierung eines Shape-Tracking-Programms - C++ OpenCV

EDIT: Ich komplett vergessen - Kredite an Dan Mašek für das Schreiben einer Mehrheit der folgenden Code.

EDIT:Here ist ein Video des Tracking, in diesem Fall nur ein Viereck auf einer Kugeloberfläche.

EDIT: Im Moment ist mein Ziel, den "Zentroid" der Formen, die von diesem Programm bezeichnet werden, in einer Datei so genau wie möglich zu verfolgen (die ich implementiert habe), mit vorzugsweise mindestens 100 protokollierte Datenpunkte pro Sekunde (mit denen ich weiterhin zu kämpfen habe).

BEARBEITEN: Geänderter Code, um zwei Kameras einzuschließen, jedes schreibt zu einer unterschiedlichen Textdatei. Momentan schreiben beide an shape_data1.txt, also funktioniert das nicht richtig. Außerdem wurde findPos() entfernt, da die Position nicht wirklich protokolliert wurde, sondern nur der Millisekundenwert der aktuellen CPU-Zeit.

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_; 
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; 
} 

Probenteil der Textdatei geschrieben werden:

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 
+0

Kommentare sind nicht für längere Diskussion; Diese Konversation wurde [in den Chat verschoben] (http://chat.stackoverflow.com/rooms/150868/discussion-on-question-by-crazed-optimization-of-a-shape-tracking-program-c). –

+0

(Bewegung zum Chat angefordert von Fragesteller.) –

Antwort

0

Datei zu beschleunigen schreibt versuchen, Dateien mit boost Memory Mapped (aus dieser Frage: c++ boost write memory mapped file).

Ich glaube, Sie brauchen die Verarbeitung in einem Arbeitsthread Hof aus (siehe diese http://en.cppreference.com/w/cpp/thread für STL und eine große Ressource ist die C++ Concurrency in Aktion Buch von Anthony Williams)

Um Sie messen müssen optimieren Der Google Benchmarker (https://github.com/google/benchmark) ist einer der besten, die ich jemals gesehen habe. Sie können es für Ihre Funktionen mit Dummy-Daten verwenden, um an ihrer Optimierung einzeln und dann als Gruppe zu arbeiten, bis Sie die tatsächlichen Engpässe gefunden haben.

+1

So nah wie ich sagen kann, nur minimale Textausgabe wird hier geschrieben, mit Feature-Identifizierung und/oder Video-Capture sind die wahrscheinlichsten Engpässe. Außerdem scheint der mit einem Speicherabbild verknüpfte Dateiwrapper, mit dem verlinkt wird, anscheinend keinen Fehlerhandler zur Fehlerbehandlung zu installieren. Auf jeden Fall würde ich empfehlen, mit der Profilerstellung der Anwendung zu beginnen, um keine Annahmen über die Engpässe treffen zu müssen. – doynax