Opencv目标追踪Kalman结合camshift特定情况下效果不错



#include "opencv2/video/tracking.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <stdio.h>


using namespace cv;
using namespace std;


Mat image;
Point origin;
int trackObject = 0;
Rect selection;
bool selectObject = false;


static void onMouse(int event, int x, int y, int, void*)
{


if (selectObject)
{


selection.x = MIN(x, origin.x);
selection.y = MIN(y, origin.y);
selection.width = std::abs(x - origin.x);
selection.height = std::abs(y - origin.y);


selection &= Rect(0, 0, image.cols, image.rows);


}


switch (event)
{


case CV_EVENT_LBUTTONDOWN:
origin = Point(x, y);
selection = Rect(x, y, 0, 0);
selectObject = true;
break;
case CV_EVENT_LBUTTONUP:
selectObject = false;
if (selection.width > 0 && selection.height > 0)
trackObject = -1;
break;


}


}


int main(int, char**)
{


const int stateNum = 4;
const int meatureNum = 2;


Rect trackWindow;
VideoCapture cap;


cap.open("E:\\opencv-for-window\\opencv\\sources\\samples\\data\\test03.avi");


namedWindow("CamShift+Kalman", WINDOW_AUTOSIZE);
setMouseCallback("CamShift+Kalman", onMouse, 0);


KalmanFilter KF(stateNum, meatureNum, 0);
Mat state(stateNum, 1, CV_32F);
Mat processNoise(stateNum, 1, CV_32F);
Mat measurement = Mat::zeros(meatureNum, 1, CV_32F);
bool paused = false;


int hsize = 16;
float hranges[] = {
1,180
};
const float* phranges = hranges;


Mat frame, hsv, hue, mask, hist, roibackproj;


for (;;)
{


if (!paused)
{


cap >> frame;
if (frame.empty())
break;


}
frame.copyTo(image);


if (!paused)
{


cvtColor(image, hsv, CV_BGR2HSV);


if (trackObject)
{


int vmin = 10, vmax = 256, smin = 30;


inRange(hsv, Scalar(0, smin, MIN(vmin, vmax)),
Scalar(180, 256, MAX(vmin, vmax)), mask);
int ch[] = {
0, 0
};
hue.create(hsv.size(), hsv.depth());
mixChannels(&hsv, 1, &hue, 1, ch, 1);


if (trackObject < 0)
{


Mat roi(hue, selection), maskroi(mask, selection);
calcHist(&roi, 1, 0, maskroi, hist, 1, &hsize, &phranges);
normalize(hist, hist, 0, 255, CV_MINMAX);


KF.transitionMatrix = (Mat_<float>(4, 4) << 1, 0, 1, 0,
0, 1, 0, 1,
0, 0, 1, 0,
0, 0, 0, 1);


setIdentity(KF.measurementMatrix);
setIdentity(KF.processNoiseCov, Scalar::all(1e-5));
setIdentity(KF.measurementNoiseCov, Scalar::all(1e-1));
setIdentity(KF.errorCovPost, Scalar::all(1));


//statePost为校正状态,其本质就是前一时刻的状态
KF.statePost.at<int>(0) = selection.x + selection.width / 2;
KF.statePost.at<int>(1) = selection.y + selection.height / 2;


trackWindow = selection;
trackObject = 1;


}
Mat prediction = KF.predict();
Point predictPt = Point(prediction.at<int>(0) - selection.width / 2, prediction.at<int>(1) - selection.height / 2);
Rect predictWindow = Rect(predictPt, selection.size());


/*
//只对预测目标周围计算投影?????????????????问题


int m, n;
m = predictPt.x - 50;
n = predictPt.y - 50;


Rect search_window = Rect(m,n, 2*predictWindow.width, 2*predictWindow.height);
Rect img(0,0,image.cols,image.rows);
search_window &=img;
Mat roihue = hue(Rect(m,n, 2*predictWindow.width, 2*predictWindow.height));


//   roihue &= hue;
Mat roimask = mask(Rect(m,n, 2*predictWindow.width, 2*predictWindow.height));
*/
calcBackProject(&hue, 1, 0, hist, roibackproj, &phranges);
roibackproj &= mask;
CamShift(roibackproj, trackWindow, TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1));
/*
//计算camshift匹配后的trackwindow的直方图相似度
Mat hist_t, roi_t(hue, trackWindow), maskroi(mask, trackWindow);
calcHist(&roi_t, 1, 0, maskroi, hist_t, 1, &hsize, &phranges);
normalize(hist_t, hist_t, 0,255, CV_MINMAX);


double base_BH = compareHist(hist, hist_t, 3);
printf("base_BH = %f \n", base_BH);//相似度为0最高


if ( base_BH >=0.3)
{


//将此刻的直方图放入vector<Mat> img中,然后每次与容器里的每一个img比较,
//前后帧比较,尤其是遮挡或消失重现时候


}
*/


measurement.at<int>(0) = trackWindow.x + trackWindow.width / 2;
measurement.at<int>(1) = trackWindow.y + trackWindow.height / 2;


KF.correct(measurement);
Point statePt = Point(KF.statePost.at<int>(0) - selection.width / 2, KF.statePost.at<int>(1) - selection.height / 2);
Rect stateWindow = Rect(statePt, selection.size());


//预测坐标绿色
rectangle(image, predictWindow, Scalar(0, 255, 0), 3, 8);
//测量坐标红色
rectangle(image, trackWindow, Scalar(0, 0, 255), 3, 8);
//状态坐标蓝色
rectangle(image, stateWindow, Scalar(255, 0, 0), 3, 8);


}


}
else if (trackObject < 0)
paused = false;


if (selectObject && selection.width > 0 && selection.height > 0)
{


Mat roi(image, selection);
bitwise_not(roi, roi);


}
imshow("CamShift+Kalman", image);


char c = (char)waitKey(33);
if (c == 33)  break;
else if (c == 'p')  paused = !paused;


}


return 0;


}
  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值