1.Frameback多项式拓展算法
void visionagin:: Myframeback()
{
VideoCapture capture("C:\\Users\\86176\\Downloads\\visionimage\\detect.mp4");
if (!capture.isOpened())
{
cout << "open failed !" << endl;
}
Mat preframe, pregray;
capture.read(preframe);
cvtColor(preframe, pregray, COLOR_BGR2GRAY);
while (true)
{
Mat nextframe, nextgry;
if (!capture.read(nextframe))
{
break;
}
imshow("frame", nextframe);
cvtColor(nextframe, nextgry, COLOR_BGR2GRAY);
//建立光流结果矩阵
Mat_flow;
calcOpticalFlowFarneback(pregray, nextgry, flow, 0.5, 3, 15, 3, 5,1.2,0);
//x,y方向上的速度
Mat vx = Mat::zeros(preframe.size(), CV_32FC1);
Mat vy = Mat::zeros(preframe.size(), CV_32FC1);
//取flow x,y作为两方向上的速度
for (int i = 0; i < flow.rows; ++i)
{
for (int j = 0; j < flow.cols; ++j)
{
Point2f temp = flow.at(i,j);
vx.at(i,j) = temp.x;
vy.at(i, j) = temp.y;
}
}
//将x,y方向上的速度合成
//幅值和角度
Mat magnitude, angle;
cartToPolar(vx, vy, magnitude, angle);
angle = angle * 180.0 / CV_PI / 20.0;
//将幅值归一化到0-255,便于显示
normalize(magnitude, magnitude, 0, 255, NORM_MINMAX);
convertScaleAbs(magnitude, magnitude);
convertScaleAbs(angle, angle);
//将运动的幅值和角度转化到HSV颜色空间的图像
vectorresult;
Mat hsv = Mat::zeros(preframe.size(), preframe.type());
split(hsv, result);
result[0]=angle;//angle决定图像颜色
result[1]=Scalar(255);
result[2]=magnitude;//幅值决定图像形状
//合成
merge(result, hsv);
//将HSV转到bgr
Mat bgrimg;
cvtColor(hsv, bgrimg, COLOR_HSV2BGR);
imshow("detect", bgrimg);
nextgry.copyTo(pregray);
int c = waitKey(50);
if (27 == c)
{
break;
}
}
}
2.基于LK稀疏光流法的物体跟踪
void lkdrawlines(vector p1, vector p2, Mat& img)
{
vector color_lut;
RNG rng(10086);
if (color_lut.size() < p1.size())
{
for (int i = 0; i < p1.size(); ++i)
{
color_lut.push_back(Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)));
}
}
for (int j = 0; j < p1.size(); ++j)
{
line(img, p1[j], p2[j], color_lut[j], 1);
}
}
void visionagin:: MyLKdetect()
{
VideoCapture capture("C:\\Users\\86176\\Downloads\\visionimage\\detect.mp4");
if (!capture.isOpened())
{
cout << "open failed !" << endl;
}
Mat preframe, pregray;
capture.read(preframe);
cvtColor(preframe, pregray, COLOR_BGR2GRAY);
//角点检测参数设置
vector conners;
int numofconnners = 5000;
double quiltylevel = 0.01;
double mindist = 10;
goodFeaturesToTrack(pregray, conners, numofconnners, quiltylevel, mindist,Mat(),3,false);
//初始状态的角点
vectorinitpoints;
initpoints.insert(initpoints.end(), conners.begin(), conners.end());
//LK算法参数
//前一帧图像角点
vectorprepoints;
prepoints.insert(prepoints.end(), conners.begin(), conners.end());
//当前帧图像角点
vectornextpoints;
vectorisitem;
vector err;
TermCriteria T = TermCriteria(TermCriteria::COUNT |TermCriteria::EPS, 30, 0.1);
while (true)
{
Mat nextframe, nextgray;
if (!capture.read(nextframe))
{
break;
}
imshow("frame", nextframe);
cvtColor(nextframe, nextgray, COLOR_BGR2GRAY);
//LK光流跟踪
calcOpticalFlowPyrLK(pregray, nextgray, prepoints, nextpoints, isitem, err, Size(31, 31), 3, T,0.5,0);
//判断角点是否移动,不移动就删除
size_t i, k;
for (i = k = 0; i < nextpoints.size(); ++i)
{
double dist = abs(nextpoints[i].x - prepoints[i].x) + abs(nextpoints[i].y - prepoints[i].y);
if (isitem[i] && dist > 2)
{
prepoints[k] = prepoints[i];
initpoints[k] = initpoints[i];
nextpoints[k++] = nextpoints[i];
circle(nextframe, nextpoints[i], 3, Scalar(0, 255, 0), -1, 8);
}
}
//更新角点数目
prepoints.resize(k);
initpoints.resize(k);
nextpoints.resize(k);
//绘制轨迹
//for (size_t t = 0; t < nextpoints.size(); ++t)
//{
// line(nextframe,initpoints[t], nextpoints[t],Scalar(0,0,255) ,1);
//}
lkdrawlines(nextpoints, initpoints, nextframe);
imshow("result", nextframe);
//更新前后图像及角点
swap( nextpoints, prepoints);
nextframe.copyTo(preframe);
cout<<"pre size is ::"<< prepoints.size() << endl;
//如果角点数目小于30,重新检测
if (initpoints.size() < 30)
{
goodFeaturesToTrack(pregray, conners, numofconnners, quiltylevel, mindist, Mat(), 3, false);
initpoints.insert(initpoints.end(), conners.begin(), conners.end());
prepoints.insert(prepoints.end(), conners.begin(), conners.end());
cout << "total prepoints size is : " << prepoints.size() << endl;
}
int c = waitKey(50);
if (27 == c)
{
break;
}
}
}