Search code examples
opencvimage-processingopenclvideo-processing

What are the problems that changes the fps in video processing?


I am trying to detect a white color object in motion using OpenCV and OpenCL. The camera that i am using is my laptop camera of 30 fps. what i am observing is that at different locations I am getting a different fps, the camera and the code being the same. for Ex in my room when I execute the code i get a full fps of 30 while in the lab it is 22...please can anyone tell that what can be the probable reason for it and how it can be corrected...The code I have used is below...Thank You in advance...

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

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

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

   int iLowH = 0;
   int iHighH = 255;

   int iLowS = 0; 
   int iHighS = 255;

   int iLowV = 0;
   int iHighV = 255;

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

   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);

   ocl::oclMat alpha;
   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;
        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;
      }

      alpha.upload(imgOriginal);
      ocl::oclMat imgHSV;

      ocl::cvtColor(alpha, imgHSV, CV_RGB2HSV); //Convert the captured frame from BGR to HSV
      ocl::oclMat channel[4];
      ocl::split(alpha,channel);
      ocl::oclMat imgThresholded[2];

      ocl::threshold(channel[0], imgThresholded[0] , iLowH , 255 , 0 );
      ocl::threshold(channel[0], imgThresholded[1] , iHighH , 255 , 1 );
      ocl::bitwise_and(imgThresholded[0],imgThresholded[1],channel[0]);

      ocl::threshold(channel[1], imgThresholded[0] , iLowS , 255 , 0 );
      ocl::threshold(channel[1], imgThresholded[1] , iHighS , 255 , 1 );
      ocl::bitwise_and(imgThresholded[0],imgThresholded[1],channel[1]);

      ocl::threshold(channel[2], imgThresholded[0] , iLowV , 255 , 0 );
      ocl::threshold(channel[2], imgThresholded[1] , iHighV , 255 , 1 );
      ocl::bitwise_and(imgThresholded[0],imgThresholded[1],channel[2]);

      ocl::bitwise_and(channel[0],channel[1],imgThresholded[0]);
      ocl::bitwise_and(imgThresholded[0],channel[2],imgThresholded[1]);

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

      //morphological closing (fill small holes in the foreground)
      ocl::dilate( imgThresholded[1], imgThresholded[1], getStructuringElement(MORPH_ELLIPSE, Size(5, 5)) ); 
      ocl::erode(imgThresholded[1], imgThresholded[1], getStructuringElement(MORPH_ELLIPSE, Size(5, 5)) );
      int c= ocl::countNonZero(imgThresholded[1]);
      Mat result = imgThresholded[1];
      //Mat r2 = channel[0];

      imshow("Thresholded Image", result); //show the thresholded image
      //imshow("Original", r2); //show the original image
      cout<<"\t"<<c<<endl;

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

Solution

  • You are doing your image-processing inside image-capturing loop. Time of image-processing is input dependent, because for example erode operation will not be executed on every image pixel, but on these that meet certain conditions. So there should be no suprise that you are getting different execution times in different enviorments. Also I can image that laptop camera driver is performing some preprocessing operations like for example brightness-adjustement before setting the flag that frame is ready for output. You should disable such preprocessing if you are interested in constant frame rate, or use different camera which SDK unables such functionality.