OpenCV 显示和处理网络摄像头流
Posted
技术标签:
【中文标题】OpenCV 显示和处理网络摄像头流【英文标题】:OpenCV display and processing webcam stream 【发布时间】:2015-01-21 15:49:12 【问题描述】:我正在寻找使用来自网络摄像头的 opencv 处理流。我的目标是检测每个帧的矩形。我可以显示结果,但帧率真的很慢,~1 fps。
这里是我的源代码的概述:
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;
我想知道是否可以使其线程化以获得至少 30fps 的速度?
我正在使用 Windows 8.1、Visual 2010、c++ 和 OpenCV 2.4.10
【问题讨论】:
【参考方案1】:您可以在while(true)
循环之前使用线程。当然,从相机读取帧并显示它们必须是序列化的。
我看到您正在使用 C++ std::vector,所以我建议您使用 C++11 线程和互斥锁。我能想到的最高效的方式是在启动时打开所有线程(在while(true)
循环之前),然后接收主线程捕获的帧。所有线程将被锁定在同一个互斥体上以读取帧队列,并锁定在第二个互斥体上以显示它。帧队列可以实现为:
struct frameQueue
std::vector<Mat> frames;
std::mutex mtx;
;
根据项目的大小和副作用,它甚至可以声明为全局。
【讨论】:
我假设您正在体验这个解决方案,它应该可以工作。我询问了线程解决方案,但我从 stacoverflow 优化/找到了一些用于图像处理的不同代码,现在我至少有 30 fps。无论如何,感谢您的解决方案 有用的建议!【参考方案2】:我使用 *** 上的另一个解决方案解决了这个问题。 这是我的完整代码:
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());
这是我的参考资料:OpenCV C++/Obj-C: Detecting a sheet of paper / Square Detection
【讨论】:
以上是关于OpenCV 显示和处理网络摄像头流的主要内容,如果未能解决你的问题,请参考以下文章
QImage OpenCV - setPixel 只有绿色和黑色
发送到 pyvirtualcam 的网络摄像头输入为蓝色(使用 pyvirtualcam 和 opencv)