FPS是测量用于保存、显示动态视频的信息数量。通俗来讲就是指每秒变化的画面数。
在计算FPS时,需要使用的主要函数有getTickCount、getTickFrequency。而在输出图像上显示FPS水印则是使用函数putText,他们的简单介绍如下:
getTickCount函数
它返回从操作系统启动到当前所经的计时周期数。
getTickFrequency函数:
返回每秒的计时周期数。
计算一帧用时多少秒方法:
t=(double)getTickCount() capture>>frame;
t=((double)getTickCount()-t) / getTickFrequency() //就得到经过一帧用多少秒。
则 FPS=1.0/t; //1秒除以t, 就得到一秒变换多少帧即
首先将摄像头的视频流经过灰度化、中值滤波、二值化、形态学滤波和开运算,保证识别率
随后将处理过的视频流进行轮廓提取
效果如下
#include "1.h"
int main() {
VideoCapture capture(0);
if (!capture.isOpened())
{
printf("Can not open a camera\n");
return -1;
}
while (1) {
Mat srcImg;
capture >> srcImg;
Mat midImg;
Mat dstImg = srcImg.clone();
double t = (double)getTickCount();//获得当前系统的计时间周期数
t = ((double)getTickCount() - t) / getTickFrequency();
double fps = 1.0 / t;//求倒数得到每秒经过多少帧,即帧率
string s = "FPS:";
s += to_string(fps);//得到字符串FPS
putText(dstImg, s, Point(5, 20), FONT_HERSHEY_COMPLEX, 0.5, Scalar(0, 0, 0));//输入到帧frame上
// 灰度化
cvtColor(srcImg, midImg, COLOR_BGR2GRAY);
// 中值滤波
medianBlur(midImg, midImg, 9);
// 二值化
threshold(midImg, midImg, 80, 255, 0);
// 形态学滤波,开运算
Mat element = getStructuringElement(MORPH_RECT, Size(10, 10));
morphologyEx(midImg, midImg, MORPH_OPEN, element);
//降噪
dilate(midImg, midImg, element, Point(-1, -1), 3);
erode(midImg, midImg, element, Point(-1, -1), 3);
// 轮廓提取
vector> contours;
findContours(midImg, contours, RETR_CCOMP, CHAIN_APPROX_SIMPLE);
Mat midImg1 = Mat::zeros(midImg.rows, midImg.cols, CV_8UC3);
for (int i = 0; i < contours.size(); i++) {
//每个轮廓
vector points = contours[i];
//对给定的2D点集,寻找最小面积的包围矩形
RotatedRect box = minAreaRect(Mat(points));
Point2f vertex[4];
//将box 中存储的4 个顶点的坐标 存储到vertex[0]~vertex[3]中去
box.points(vertex);
//打印中心点位置及外接矩形角度
cout << "中心点位置(第" << i << "条轮廓):" << box.center << endl;
cout << "外接矩形角度(第" << i << "条轮廓):" << box.angle << endl;
//绘制出最小面积的包围矩形
line(dstImg, vertex[0], vertex[1], Scalar(200, 255, 200), 3, LINE_AA);
line(dstImg, vertex[1], vertex[2], Scalar(200, 255, 200), 3, LINE_AA);
line(dstImg, vertex[2], vertex[3], Scalar(200, 255, 200), 3, LINE_AA);
line(dstImg, vertex[3], vertex[0], Scalar(200, 255, 200), 3, LINE_AA);
imshow("test", dstImg);
}
if(waitKey(30) == 27){
break;
}
}
destroyAllWindows();
return 0;
}
可以看到效果并不是太好,可能还需要进一步的降噪
参考文章:
OpenCV4学习笔记(2):显示相机视频流的帧率_风吹落叶花飘荡的博客-CSDN博客_opencv显示帧率
OpenCV(C++) 入门示例 - 传统方法目标检测_Tab_2021的博客-CSDN博客_c++ opencv 目标检测