2016-06-26 16 views
0

Ich arbeite gerade an einem Projekt, bei dem ich eine verarbeitete Live-Videoaufnahme anzeigen muss. Deshalb verwende ich etwas Ähnliches wie folgt aus:Probleme beim Erfassen und Verarbeiten eines Videos

cv::VideoCapture cap(0); 
if (!cap.isOpened()) 
    return -1; 

cap.set(CV_CAP_PROP_FRAME_WIDTH, 1280); 
cap.set(CV_CAP_PROP_FRAME_HEIGHT, 720); 

cv::namedWindow("Current Capture"); 
for (;;) 
{ 
    cv::Mat frame; 
    cap >> frame;  
    cv::Mat mirrored; 
    cv::flip(frame, mirrored, 1); 
    cv::imshow("Current Capture", process_image(mirrored)); 

    if (cv::waitKey(30) >= 0) break; 
} 

Das Problem, das ich habe, ist, dass process_image, die einen Kreis Erkennung im Bild perfomes, einige Zeit zu beenden muss und bewirkt, dass die Anzeige eher eine Diashow sein dann ein Video.

Meine Frage ist: Wie kann ich die Verarbeitung beschleunigen ohne die process_image Funktion manipulieren?

Ich dachte über die Bildbearbeitung in einem anderen Thread, aber ich bin mir nicht sicher, wie ich anfangen soll. Hast du noch eine andere Idee?

PS .: Ich bin nicht erwarten Sie Code für mich zu schreiben, ich brauche nur einen Punkt aus zu starten;)

EDIT:

Ok, wenn es nichts ich tun kann, über die Leistung während der Erfassung, muss ich die process_image Funktion ändern.

cv::Mat process_image(cv::Mat img) 
{ 
    cv::Mat hsv; 
    cv::medianBlur(img, img, 7); 
    cv::cvtColor(img, hsv, cv::COLOR_BGR2HSV); 

    cv::Mat lower_hue_range; // lower and upper hue range in case of red color 
    cv::Mat upper_hue_range; 
    cv::inRange(hsv, cv::Scalar(LOWER_HUE1, 100, 100), cv::Scalar(UPPER_HUE1, 255, 255), lower_hue_range); 
    cv::inRange(hsv, cv::Scalar(LOWER_HUE2, 100, 100), cv::Scalar(UPPER_HUE1, 255, 255), upper_hue_range); 

    /// Combine the above two images 
    cv::Mat hue_image; 
    cv::addWeighted(lower_hue_range, 1.0, upper_hue_range, 1.0, 0.0, hue_image); 

    /// Reduce the noise so we avoid false circle detection 
    cv::GaussianBlur(hue_image, hue_image, cv::Size(13, 13), 2, 2); 

    /// store all found circles here 
    std::vector<cv::Vec3f> circles; 
    cv::HoughCircles(hue_image, circles, CV_HOUGH_GRADIENT, 1, hue_image.rows/8, 100, 20, 0, 0); 

    for (size_t i = 0; i < circles.size(); i++) 
    { 
     /// circle center 
     cv::circle(hsv, cv::Point(circles[i][0], circles[i][1]), 3, cv::Scalar(0, 255, 0), -1, 8, 0); 
     /// circle outline 
     cv::circle(hsv, cv::Point(circles[i][0], circles[i][1]), circles[i][2], cv::Scalar(0, 0, 255), 3, 8, 0); 
    } 

    cv::Mat newI; 
    cv::cvtColor(hsv, newI, cv::COLOR_HSV2BGR); 

    return newI; 
} 

Gibt es ein großes Leistungsproblem, über das ich etwas machen kann?

+0

1ms ist ziemlich kurz, nicht überraschend, dass Sie Leistungsprobleme haben. –

+0

Oh Entschuldigung, das war etwas, was ich ausprobiert habe. Ich habe es ursprünglich mit 30ms probiert. Bearbeitete die Frage. – muXXmit2X

Antwort

1

Wenn Sie sicher sind, dass die Funktion process_image den Flaschenhals in Ihrem Programm verursacht, aber nicht geändert werden kann, können Sie nicht viel tun. Wenn diese Funktion länger dauert als die Dauer eines Videoframes, erhalten Sie nie das, was Sie brauchen.

Wie wäre es, die Qualität der Videoaufnahme zu reduzieren oder die Größe zu reduzieren? Im Moment kann ich sehen, dass Sie es auf 1280 * 720 eingestellt haben. Wenn die Funktion process_image weniger Daten zum Arbeiten hat, sollte sie schneller ausgeführt werden.

+0

Hmm. Okay, das ist tatsächlich, was ich dachte ... die Reduzierung der Auflösung funktioniert, aber es reduziert auch die resultierende Qualität. Ich werde versuchen, auf den Code von 'process_image' zuzugreifen. Vielleicht kann es optimiert werden. – muXXmit2X

Verwandte Themen