我正在寻找一个来自网络摄像头的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 ++&amp; OpenCV 2.4.10
答案 0 :(得分:3)
您可以在while(true)
循环之前使用线程。当然,从相机读取帧并显示它们必须序列化。
我看到你正在使用C ++ std :: vector,所以我建议你使用C ++ 11线程和互斥锁。我能想到的最有效的方法是在启动时打开所有线程(在while(true)
循环之前),然后生成接收主线程捕获的帧。所有线程都将锁定在同一个互斥锁上以读取帧队列,并锁定在第二个互斥锁上以显示它。帧队列可以实现为:
struct frameQueue{
std::vector<Mat> frames;
std::mutex mtx;
};
根据项目的大小和副作用,它甚至可能被声明为全局。
答案 1 :(得分:2)
我使用stackoverflow上的另一个解决方案解决了这个问题。 这是我的完整代码:
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