CPU Usage (optical flow)
Hello,
I want to detect faces with OpenCV and apply an optical flow to follow the face. My code works but it is expensive for the CPU (the CPU runs at 20%).
I capture an image at with "capture >> frame" (which gives a new image at each 30ms). Running only this requires 5% of the CPU. However, if I add the code for optical flow "cv::calcOpticalFlowPyrLK(prevGray, gray, prevPoints, currPoints, status, err, winSize, 3, termcrit, 0, 0.001);", running the program leads to a constant CPU usage of 20% for the program. I would very much like to reduce this CPU usage even if my program takes more time to operate.
cv::setNumThreads(2) helps a lot (CPU 10%) but I would like to see other possible methods to optimize.
Here is the code I use (the feature points for the optical flow are pre-generated to simplify the code):
Thank you so much !
Alex
int main(int argc, char *argv[])
{
//cv::setNumThreads(2);
cv::Mat frame;
cv::Mat frametemp;
cv::Mat gray;
cv::Mat prevGray;
cv::vector<cv::Point2f> prevPoints;
cv::vector<uchar> status;
cv::vector<float> err;
cv::VideoCapture capture(0);
float landmarks[68][2];
while (true)
{
capture >> frame;
if (!frame.empty())
{
for (int i = 0; i < 68; i++)
{
landmarks[i][0] = i*5;
landmarks[i][1] = i*5;
}
frame.copyTo(frametemp);
cvtColor(frametemp, gray, cv::COLOR_BGR2GRAY);
if (prevGray.empty())
{
gray.copyTo(prevGray);
}
cv::vector<cv::Point2f> currPoints;
for (int k = 0; k < 68; k++)
{
currPoints.push_back(cv::Point2f(landmarks[k][0], landmarks[k][1]));
}
if (!prevPoints.empty())
{
cv::calcOpticalFlowPyrLK(prevGray, gray, prevPoints, currPoints, status, err, winSize, 3, termcrit, 0, 0.01);
}
std::swap(currPoints, prevPoints);
cv::swap(prevGray, gray);
}
else
{
printf(" --(!) No captured frame -- Break!"); break;
}
//Sleep(3);
}
return 0;
}
You could try running two threads, a capture thread that stores the camera images to a thread-safe buffer and an optical flow thread that reads images from the thread safe buffer and processes them. This may decrease latency and increase frame rate, but it won't reduce cpu usage and might even increase it. Another thing to try is reducing the image resolution. Many cameras capture at VGA, but it is often acceptable to perform all operations at QVGA. You can always up-res with guided filters to get results at VGA and still save on computation.