当我在154行插入cout输出点坐标后,原本能跑三秒多的视频现在跑不到两秒,能否帮忙看下如何才能让这个代码去跑长视频
#include <time.h>
#include <opencv2/opencv.hpp>
#include <math.h>
#include <iostream>
#include<vector>
using namespace std;
using namespace cv;
int main()
{
clock_t start,finish;
double totaltime, heights[16];
int hi = 0;
VideoCapture capture("步兵素材蓝车后面-ev--3.MOV"); //功能:创建一个VideoCapture类的实例,如果传入对应的参数,可以直接打开视频文件或者要调用的摄像头。
//VideoCapture capture(0); //打开摄像头
Mat frame, binary; //定义两个图片 frame(原图) 和 binary(二值化)
RotatedRect RA[16], R[16]; //RotatedRect表示旋转矩形
int stateNum = 4; //状态编号
int measureNum = 2; //测量编号
KalmanFilter KF(stateNum, measureNum, 0); //卡尔曼滤波
//Mat processNoise(stateNum, 1, CV_32F); //图像过程噪音
Mat measurement = Mat::zeros(measureNum, 1, CV_32F); //相当于创建一张黑色的图,每个像素的每个通道都为0,Scalar(0,0,0)
KF.transitionMatrix = (Mat_<float>(stateNum, stateNum) <<
1, 0, 1, 0,
0, 1, 0, 1,
0, 0, 1, 0,
0, 0, 0, 1);//A 状态转移矩阵,//这里没有设置控制矩阵B,默认为零
setIdentity(KF.measurementMatrix);//H=[1,0,0,0;0,1,0,0] 测量矩阵
setIdentity(KF.processNoiseCov, Scalar::all(1e-5));//Q高斯白噪声,单位阵
setIdentity(KF.measurementNoiseCov, Scalar::all(1e-1));//R高斯白噪声,单位阵
setIdentity(KF.errorCovPost, Scalar::all(1));//P后验误差估计协方差矩阵,初始化为单位阵
randn(KF.statePost, Scalar::all(0), Scalar::all(0.1));//初始化状态为随机值
for(;;)
{
start = clock(); //返回从程序执行起 ( 一般为程序的开头),处理器时钟所使用的时间
capture>> frame; //将视频帧读取到cv::Mat矩阵中
frame.copyTo(binary); //得到一个和frame相同的矩阵binary
cvtColor(frame,frame,COLOR_BGR2GRAY); //将输入图像从一个色彩空间转换到另一个色彩空间,此处将frame从BGR转换为GRAY
threshold(frame, frame, 160, 255,cv::THRESH_BINARY);//调阈值就差不多了,去掉噪,例如过滤很小或很大像素值的图像点,原图像为frame,得到的结果图像为frame,最小阈值为160,最大阈值为255,阈值类型为THRESH_BINARY
// 找出阈值图像中所有的轮廓
vector<vector<Point>> contours; //创建一个动态的数组(未知数组大小)名为contours(轮廓)
imshow("end",frame); //输出图片frame名为end
findContours(frame, contours, RETR_LIST, CHAIN_APPROX_NONE); //检测出物体的轮廓 ,物体边界上所有连续的轮廓点到contours向量内
for (size_t i = 0; i < contours.size(); i++) //用sizeof操作得到变量i的大小,这是一个size_t类型的值
{
vector<Point> points; //创建一个points的动态数组
double area = contourArea(contours[i]); //计算轮廓contours[i]的面积将计算结果存到area中
if (area < 20 || 1e3 < area) continue; //如果area小于20或者le3<area时
drawContours(frame, contours, static_cast<int>(i), Scalar(0), 2); //轮廓绘制 static_cast:将i转换为整型,指定绘制轮廓的下标(若为负数,则绘制所有轮廓) Scalar(0)表示颜色,只有一个参数表示三个通道数值都一样
double high; //定义一个高度high
points = contours[i]; //points= 物体边界上所有连续的轮廓点
RotatedRect rrect = fitEllipse(points); //用最小椭圆将points包起来 RotatedRect该类表示平面上的旋转矩形 ,rrect表示一个名字 fitEllipse:二维点集的椭圆拟合,,用椭圆将二维点包含起来
cv::Point2f* vertices = new cv::Point2f[4]; //获取旋转矩形的四个顶点 Point2f(x,y)中的x代表在图像中的列,y代表图像中的行
rrect.points(vertices); //获取旋转矩形的四个顶点
for (int j = 0; j < 4; j++) //画出旋转矩形的外框
{
cv::line(binary, vertices[j], vertices[(j + 1) % 4], cv::Scalar(0, 255, 0),4);
}
//ellipse(binary,rrect,Scalar(0)); //绘制椭圆
high = rrect.size.height; //high=最小椭圆的高度
for(size_t j = 1;j < contours.size();j++) //用sizeof获取j的值,返回j=sizeof(j)
{
vector<Point> pointsA; //创建一个pointsA的动态数组
double area = contourArea(contours[j]); //计算轮廓contours[j]的面积将计算结果存到area中
if (area < 20 || 1e3 < area) continue; //如果area小于20或者le3<area时
double highA, distance; //定义highA和distance
double slop ; //定义slop
pointsA = contours[j]; //pointsA = 物体边界上所有连续的轮廓点
RotatedRect rrectA = fitEllipse(pointsA); //用最小椭圆将pointsA包起来
slop = abs(rrect.angle - rrectA.angle); //abs()求整型数据的绝对值 两个椭圆角度相减
highA = rrectA.size.height; //highA = rrectA椭圆的高度
distance =sqrt((rrect.center.x-rrectA.center.x)*(rrect.center.x-rrectA.center.x)+
(rrect.center.y-rrectA.center.y)*(rrect.center.y-rrectA.center.y));//求两个椭圆的距离
double max_height, min_height; //定义高度的最大值和最小值
if( rrect.size.height> rrectA.size.height)//取高度的最大值和最小值
{
max_height = rrect.size.height;
min_height = rrectA.size.height;
}
else
{
max_height = rrectA.size.height;
min_height = rrect.size.height;
}
double line_x = abs(rrect.center.x-rrectA.center.x); //line_x表示x轴的距离
double difference = max_height - min_height; //difference表示高度的差异
double aim = distance/((highA+high)/2);
double difference3 = abs(rrect.size.width -rrectA.size.width); //difference3表示宽度差
double height = (rrect.size.height+rrectA.size.height)/200; //height表示高度
double slop_low = abs(rrect.angle + rrectA.angle)/2; //slop_low表示角度的平均值
if((aim < 3.0 - height && aim > 2.0 - height //小装甲板
&& slop <= 5 && difference <=8 && difference3 <= 5
&&(slop_low <= 30 || slop_low >=150) && line_x >0.6*distance)
|| (aim < 5.0-height && aim > 3.2 - height //大装甲板
&& slop <= 7 && difference <=15 && difference3 <= 8
&&(slop_low <= 30 || slop_low >=150) && line_x >0.7*distance)){
heights[hi] = (rrect.size.height+rrectA.size.height)/2;
R[hi] = rrect;
RA[hi] = rrectA;
hi++;
}
}
}
double max = 0;
int mark;
for(int i = 0;i < hi;i++){ //多个目标存在,打更近装甲板
if(heights[i] >= max){
max = heights[i];
mark = i;
}
}
if(hi != 0){
cv::circle(binary,Point((R[mark].center.x+RA[mark].center.x)/2,
(R[mark].center.y+RA[mark].center.y)/2),
15,cv::Scalar(0,0,255),4);
double center_x = (R[mark].center.x+RA[mark].center.x)/2;
double center_y = (R[mark].center.y+RA[mark].center.y)/2;
Mat prediction = KF.predict();
Point predict_pt = Point((int)prediction.at<float>(0), (int)prediction.at<float>(1));
measurement.at<float>(0) = (float)center_x;
measurement.at<float>(1) = (float)center_y;
KF.correct(measurement);
circle(binary, predict_pt, 3, Scalar(34, 255, 255), -1);
center_x = (int)prediction.at<float>(0);
center_y = (int)prediction.at<float>(1);
double lessx = 320 - center_x; //坐标差
double lessy = 240 - center_y;
// cout << lessx << " " << lessy << " " << down <<endl;
}
imshow("okey",binary);
waitKey(2);
hi = 0;
}
}
换个视频文件再试试。