2014-09-06 4 views
1

OpenCV 및 Visual Studio 2012를 사용하여이 간단한 색상 추적 이미지 처리 프로그램을 컴파일했습니다. 먼저 CPU를 사용하여 컴파일했습니다. 프로그램 : 내 카메라 (16) 의 FPS를주고 있었다OpenCL 및 GPU를 사용하면 카메라의 fps 성능이 향상되지 않습니다

#include <iostream> 
#include "opencv2/highgui/highgui.hpp" 
#include "opencv2/imgproc/imgproc.hpp" 
#include <time.h> 

using namespace cv; 
using namespace std; 

int main(int argc, char** argv) 
{ 
    time_t t= time(0); 
    VideoCapture cap(0); //capture the video from web cam 

    if (!cap.isOpened()) // if not success, exit program 
    { 
     cout << "Cannot open the web cam" << endl; 
     return -1; 
    } 
    double dWidth = cap.get(CV_CAP_PROP_FRAME_WIDTH); //get the width of frames of the video 
    double dHeight = cap.get(CV_CAP_PROP_FRAME_HEIGHT); //get the height of frames of the video 

    cout << "Frame size : " << dWidth << " x " << dHeight << endl; 

    namedWindow("Control", CV_WINDOW_AUTOSIZE); //create a window called "Control" 

    int iLowH = 0; 
int iHighH = 179; 

    int iLowS = 0; 
int iHighS = 255; 

    int iLowV = 0; 
int iHighV = 255; 

    //Create track bars in "Control" window 
cvCreateTrackbar("LowH", "Control", &iLowH, 179); //Hue (0 - 179) 
cvCreateTrackbar("HighH", "Control", &iHighH, 179); 

    cvCreateTrackbar("LowS", "Control", &iLowS, 255); //Saturation (0 - 255) 
cvCreateTrackbar("HighS", "Control", &iHighS, 255); 

    cvCreateTrackbar("LowV", "Control", &iLowV, 255); //Value (0 - 255) 
cvCreateTrackbar("HighV", "Control", &iHighV, 255); 

    int fps=0; 
    int cur=0; 
    while (true) 
    { 
    fps++; 
     t=time(0); 
     struct tm *tmp = gmtime(&t); 

     int h= (t/360) %24; 
     int m= (t/60) %60; 
     int s = t%60; 
     if(cur !=s) 
     { 
      cout<<fps<<endl; 
      fps=0; 
      cur=s; 
     } 
     Mat imgOriginal; 

     bool bSuccess = cap.read(imgOriginal); // read a new frame from video 

     if (!bSuccess) //if not success, break loop 
     { 
      cout << "Cannot read a frame from video stream" << endl; 
      break; 
     } 

    Mat imgHSV; 

    cvtColor(imgOriginal, imgHSV, COLOR_BGR2HSV); //Convert the captured frame from BGR to HSV 

    Mat imgThresholded; 

    inRange(imgHSV, Scalar(iLowH, iLowS, iLowV), Scalar(iHighH, iHighS, iHighV), imgThresholded); //Threshold the image 

    //morphological opening (remove small objects from the foreground) 
    erode(imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5))); 
    dilate(imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5))); 

    //morphological closing (fill small holes in the foreground) 
    dilate(imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5))); 
    erode(imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5))); 

    imshow("Thresholded Image", imgThresholded); //show the thresholded image 
    imshow("Original", imgOriginal); //show the original image 

     if (waitKey(30) == 27) //wait for 'esc' key press for 30ms. If 'esc' key is pressed, break loop 
     { 
      cout << "esc key is pressed by user" << endl; 
      break; 
     } 
    } 

    return 0; 

} 

은 그 때 나는 오픈 CL (GPU 지원)를 사용하여이 프로그램을 컴파일. 프로그램 :

#include <iostream> 
#include "opencv2/highgui/highgui.hpp" 
#include "opencv2/imgproc/imgproc.hpp" 
#include <opencv2/ocl/ocl.hpp> 
#include <time.h> 

using namespace cv; 
using namespace std; 

int main(int argc, char** argv) 
{ 
    time_t t= time(0); 
    VideoCapture cap(0); //capture the video from web cam 

    if (!cap.isOpened()) // if not success, exit program 
    { 
     cout << "Cannot open the web cam" << endl; 
     return -1; 
    } 
    double dWidth = cap.get(CV_CAP_PROP_FRAME_WIDTH); //get the width of frames of the video 
    double dHeight = cap.get(CV_CAP_PROP_FRAME_HEIGHT); //get the height of frames of the video 

    cout << "Frame size : " << dWidth << " x " << dHeight << endl; 

    namedWindow("Control", CV_WINDOW_AUTOSIZE); //create a window called "Control" 

    int iLowH = 0; 
int iHighH = 179; 

    int iLowS = 0; 
int iHighS = 255; 

    int iLowV = 0; 
int iHighV = 255; 

    //Create track bars in "Control" window 
cvCreateTrackbar("LowH", "Control", &iLowH, 179); //Hue (0 - 179) 
cvCreateTrackbar("HighH", "Control", &iHighH, 179); 

    cvCreateTrackbar("LowS", "Control", &iLowS, 255); //Saturation (0 - 255) 
cvCreateTrackbar("HighS", "Control", &iHighS, 255); 

    cvCreateTrackbar("LowV", "Control", &iLowV, 255); //Value (0 - 255) 
cvCreateTrackbar("HighV", "Control", &iHighV, 255); 

    int fps=0; 
    int cur=0; 
    while (true) 
    { 
    fps++; 
     t=time(0); 
     struct tm *tmp = gmtime(&t); 

     int h= (t/360) %24; 
     int m= (t/60) %60; 
     int s = t%60; 
     if(cur !=s) 
     { 
      cout<<fps<<endl; 
      fps=0; 
      cur=s; 
     } 
     Mat imgOriginal; 

     bool bSuccess = cap.read(imgOriginal); // read a new frame from video 

     if (!bSuccess) //if not success, break loop 
     { 
      cout << "Cannot read a frame from video stream" << endl; 
      break; 
     } 

    Mat imgHSV; 

    cvtColor(imgOriginal, imgHSV, COLOR_BGR2HSV); //Convert the captured frame from BGR to HSV 

    Mat imgThresholded; 

    inRange(imgHSV, Scalar(iLowH, iLowS, iLowV), Scalar(iHighH, iHighS, iHighV), imgThresholded); //Threshold the image 

    //morphological opening (remove small objects from the foreground) 
    ocl::oclMat alpha(imgThresholded); 
    ocl::erode(alpha,alpha, getStructuringElement(MORPH_ELLIPSE, Size(5, 5))); 
    ocl::dilate(alpha, alpha, getStructuringElement(MORPH_ELLIPSE, Size(5, 5))); 

    //morphological closing (fill small holes in the foreground) 
    ocl::dilate(alpha, alpha, getStructuringElement(MORPH_ELLIPSE, Size(5, 5))); 
    ocl::erode(alpha, alpha, getStructuringElement(MORPH_ELLIPSE, Size(5, 5))); 
    imgThresholded = Mat(alpha); 
    imshow("Thresholded Image", imgThresholded); //show the thresholded image 
    imshow("Original", imgOriginal); //show the original image 

     if (waitKey(30) == 27) //wait for 'esc' key press for 30ms. If 'esc' key is pressed, break loop 
     { 
      cout << "esc key is pressed by user" << endl; 
      break; 
     } 
    } 

    return 0; 

} 

하지만 지금은 FPS = 10을 얻고있다. 누군가가 왜 이런 일이 일어나는지 말할 수 있습니까? GPU 지원이 fps 성능을 향상시키는 곳을 읽었습니다. 사용중인 그래픽 카드는 AMD RAEDON입니다.

+0

if (waitKey (30) == 27), 30ms는 이미 최대 33FPS를 의미합니다. 5ms도 작동해야하고 더 많은 fps –

+0

gpu 줄래? HD7730 GDDR3 또는 R9-295x2? –

+0

HD 8730M @huseyintugrulbuyukisik –

답변

2

GPU는 막대한 처리량을 위해 설계되었지만 CPU 메모리에서 GPU 메모리로 데이터를 이동하는 데 많은 시간이 필요합니다. GPU가 항상 fps를 증가시키고 있다고 생각해서는 안됩니다. 그것은 모두 GPU의 힘이 얼마나 잘 수집되었는지에 달려 있습니다.

귀하의 경우에는 각 프레임마다 아주 적은 작업을하고있는 것처럼 보입니다. 제 추측으로는 시스템이 GPU로 프레임을 이동하고 결과를 다시 이동시키는 대부분의 시간을 사용하고 있다는 것입니다.

+0

내 fps를 높이기 위해 내가 할 수있는 다른 것에 대한 제안. –

+0

한 번에 여러 프레임 전송 – Austin

+0

GPU가 이전 프레임에서 작동하는 동안 CPU로 비디오에서 새 프레임을 읽을 수도 있습니다. 프레임 읽기 코드를 마지막'ocl :: erode' 다음에, 그리고 읽기'Mat (alpha)'를 막기 전에 움직여보십시오. 이것은 컴파일러가 코드를 움직일 수 있기 때문에 절대적인 방법은 아니지만 귀하의 경우에 시도 할 것이 분명합니다. – maZZZu

1

(maZZZu가 댓글을 달았 음)

직렬 계산을 수행하고 있습니다. 파이프 라이닝을 추가하십시오. 그런 다음 프레임이 캡처되면 동시에 마지막 프레임 하나가 opencl에 의해 계산됩니다.

  • 컴퓨팅
  • 시각화 CPU에 도착 GPU에

    • GET 비디오 데이터
    • 사본 : 당신은 같은 더 많은 단계를 중복 수 있을까?

    FPS에서 가장 많은 시간이 소요되는 단계 만 표시됩니다. gpu로 복사하는 데 20ms가 걸리면 다른 프로그램이 숨겨져 프로그램에 50FPS가 표시됩니다. GPU에 복사가 45 %를 소요하고 다시 결과를 얻는 것은 시간의 45 %를 소요 그렇다면

    - Time 1: get video data 1 
    - (Time 2: get video data 2) and (copy data 1 to gpu) 
    - (Time 3: get video data 3) and (copy data 2 to gpu) and (compute data 1) 
    - (Time 4: get video data 4) and (copy data 3 to gpu) and (compute data 2) and .. 
    - (Time 5: get video data 5) and (copy data 4 to gpu) and (compute data 3) and .. 
    - (Time 6: get video data 6) and (copy data 5 to gpu) and (compute data 4) and .. 
    - (Time 7: get video data 8) and (copy data 6 to gpu) and (compute data 5) and .. 
    

    , FPS는 다른 뒤에 그 중 하나를 숨기고으로 90 % 증가한다.

  • 관련 문제