[英]OpenCV display and processing webcam stream
I was looking for process a stream with opencv coming from webcam. 我正在寻找使用来自摄像头的opencv处理流。 My goal is to detect rectangles for each frames.
我的目标是为每个帧检测矩形。 I'm able to display the result but the framerate is really slow, ~1 fps.
我可以显示结果,但是帧速率确实很慢,约为1 fps。
Here is an overview of my source code: 这是我的源代码的概述:
int main( int argc, char** argv ) {
CvCapture* cap=cvCreateCameraCapture(0);
cvNamedWindow("LiveFeed",CV_WINDOW_AUTOSIZE);
while(true) {
frame=cvQueryFrame(cap);
if(!frame)
printf("\n no");
else {
Mat mat_img(frame);
std::vector<std::vector<cv::Point>> rectangle = findSquaresInImage(mat_img);
rectangle=filterRectangleSimilaire(rectangle,20.0);
Mat res=debugSquares(rectangle,mat_img);
cvShowImage("LiveFeed",new IplImage(res));//new IplImage(res));
}
char c=cvWaitKey(33);
if(c==27)
break;
}
cvReleaseCapture(&cap);
cvDestroyAllWindows();
return 0;
}
I would like to know if it's possible to make it threaded to gain at least 30fps ? 我想知道是否有可能使其线程至少获得30fps?
I'm working on windows 8.1, Visual 2010, c++ & OpenCV 2.4.10 我正在Windows 8.1,Visual 2010,C ++和OpenCV 2.4.10上工作
You could use threads before while(true)
loop. 您可以在
while(true)
循环之前使用线程。 Of course, reading frames from the camera and displaying them would have to be serialized. 当然,必须从相机读取帧并将其显示出来。
I see you're using C++ std::vector, so I would suggest you use C++11 threads and mutex. 我看到您使用的是C ++ std :: vector,因此建议您使用C ++ 11线程和互斥量。 The most performatic way I can think of is openning all threads at startup (before the
while(true)
loop) and make then receive the frames captured by the main thread. 我能想到的最有效的方法是在启动时打开所有线程(在
while(true)
循环之前),然后使它们接收由主线程捕获的帧。 All threads would be locked on the same mutex for reading the frame queue and on a second mutex for displaying it. 所有线程将锁定在同一互斥锁上以读取帧队列,并锁定在另一个互斥锁上以显示帧队列。 The frame queue may be implemented as:
帧队列可以实现为:
struct frameQueue{
std::vector<Mat> frames;
std::mutex mtx;
};
Depending on the size of your project and side effects, it may even be declared global. 根据项目的大小和副作用,它甚至可能被声明为全局的。
I fixed this issue using another solution found on stackoverflow. 我使用在stackoverflow上找到的另一个解决方案解决了此问题。 Here is my complete code:
这是我完整的代码:
Mat mat_img(frame);
Mat gray_mat_img, threshold_mat_img, detected_edges;
std::vector<std::vector<cv::Point>> contours;
vector<Vec4i> hierarchy;
cvtColor(mat_img, gray_mat_img, CV_BGR2GRAY);
blur(gray_mat_img, gray_mat_img, Size(10,10));
cv::threshold(gray_mat_img, threshold_mat_img, 140, 255, cv::THRESH_BINARY | cv::THRESH_OTSU);
Canny(threshold_mat_img, detected_edges, 100, 100, 3);
cv::findContours(detected_edges, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
RNG rng(12345);
//contours = filterRectangleSimilaire(contours, 10);
//if (contours.size() < 5) {
vector<Rect> boundRect( contours.size() );
vector<Point> approx;
for (size_t i = 0; i < contours.size(); i++) {
approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true)*0.02, true);
if (approx.size() == 4 && fabs(contourArea(Mat(approx))) > 100 && isContourConvex(Mat(approx))) {
double maxCosine = 0;
for (int j = 2; j < 5; j++) {
double cosine = fabs(angle(approx[j%4], approx[j-2], approx[j-1]));
maxCosine = MAX(maxCosine, cosine);
}
if (maxCosine < 0.3) {
Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255));
boundRect[i] = boundingRect( Mat(approx) );
rectangle( mat_img, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0 );
drawContours(mat_img, contours, i, color, 2, 8, hierarchy, 0, Point());
}
}
}
Here is my reference: OpenCV C++/Obj-C: Detecting a sheet of paper / Square Detection 这是我的参考: OpenCV C ++ / Obj-C:检测一张纸/正方形检测
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.