MeanShift的目标跟踪算法opencv c++接口代码 VS2015+opencv3.2
来源:互联网 发布:用intent传递数据 编辑:程序博客网 时间:2024/06/17 22:52
MeanShift的目标跟踪算法
这几天在学meanshift跟踪的原理和实现,虽然还不是特别明白,但总想先找个程序跑一下试一下效果,网上的程序多是基于c接口的老的opencv程序,在借鉴大神思路的基础上,对其代码进行了一些小的改动升级,变成了c++接口。大神‘taotao1233’的原meanshift讲解与源代码网址:http://blog.csdn.net/jinshengtao/article/details/30258833。
ps:虽然代码可用,但对于代码算法具体原理及实现还未掌握透彻,有待进一步学习。
1.这是根据原有作者的c接口opencv升级的c++接口程序,适用于opencv 接口2.0版本,开发环境为VS2015+opencv3.2。
2.程序视频的默认路径为”E\\dd4.mp4“。”
3.视频启动后按 s 键进行暂停,然后用鼠标选取需要跟踪的矩形框,再次按 s 视频启动进行跟踪。
4.程序有个bug,视频播放完毕会报错。
2.程序视频的默认路径为”E\\dd4.mp4“。”
3.视频启动后按 s 键进行暂停,然后用鼠标选取需要跟踪的矩形框,再次按 s 视频启动进行跟踪。
4.程序有个bug,视频播放完毕会报错。
5.程序中有imwrite函数,opencv本身bug存在,建议编译时选择release选项。
//#include "stdafx.h" //#include "cv.h" //#include "highgui.h" #include<opencv.hpp>#define u_char unsigned char #define DIST 0.5 #define NUM 20 using namespace std;using namespace cv;//全局变量 bool pause = false;bool is_tracking = false;Rect drawing_box;Mat current;double *hist1, *hist2;double *m_wei;double C = 0.0;bool xx = false;bool g_bDrawingBox = false;Mat tempImage;void ShowHelpText();void init_target(double *hist1, double *m_wei, Mat current){int t_h, t_w, t_x, t_y;double h, dist;int i, j;int q_r, q_g, q_b, q_temp;t_h = drawing_box.height;t_w = drawing_box.width;t_x = drawing_box.x;t_y = drawing_box.y;h = pow(((double)t_w) / 2, 2) + pow(((double)t_h) / 2, 2); //带宽 Mat pic_hist = Mat(300, 200, CV_8UC3); //生成直方图图像 for (i = 0; i < t_w*t_h; i++){m_wei[i] = 0.0;}for (i = 0; i < 4096; i++){hist1[i] = 0.0;}for (i = 0; i < t_h; i++){for (j = 0; j < t_w; j++){dist = pow(i - (double)t_h / 2, 2) + pow(j - (double)t_w / 2, 2);m_wei[i * t_w + j] = 1 - dist / h;//printf("%f\n",m_wei[i * t_w + j]); C += m_wei[i * t_w + j];}}//计算目标权值直方 for (i = t_y; i < t_y + t_h; i++){for (j = t_x; j < t_x + t_w; j++){//rgb颜色空间量化为16*16*16 bins /*q_r = ((u_char)current.at(i + j * 3 + 2) / 16;q_g = ((u_char)current->imageData[i * current->widthStep + j * 3 + 1]) / 16;q_b = ((u_char)current->imageData[i * current->widthStep + j * 3 + 0]) / 16;*/q_r = current.at<Vec3b>(i, j)[2] / 16;q_g = current.at<Vec3b>(i, j)[1] / 16;q_b = current.at<Vec3b>(i, j)[0] / 16;q_temp = q_r * 256 + q_g * 16 + q_b;hist1[q_temp] = hist1[q_temp] + m_wei[(i - t_y) * t_w + (j - t_x)];}}//归一化直方图 for (i = 0; i < 4096; i++){hist1[i] = hist1[i] / C;//printf("%f\n",hist1[i]); }//生成目标直方图 double temp_max = 0.0;for (i = 0; i < 4096; i++) //求直方图最大值,为了归一化 {//printf("%f\n",val_hist[i]); if (temp_max < hist1[i]){temp_max = hist1[i];}}//画直方图 Point p1, p2;double bin_width = pic_hist.cols / 4096;double bin_unith = pic_hist.rows / temp_max;for (i = 0; i < 4096; i++){p1.x = i * bin_width;p1.y = pic_hist.rows;p2.x = (i + 1)*bin_width;p2.y = pic_hist.rows - hist1[i] * bin_unith;//printf("%d,%d,%d,%d\n",p1.x,p1.y,p2.x,p2.y); rectangle(pic_hist, p1, p2, Scalar(0, 255, 0), -1, 8, 0);}imwrite("hist1.jpg", pic_hist);//cvReleaseImage(&pic_hist);}void MeanShift_Tracking(Mat current){int num = 0, i = 0, j = 0;int t_w = 0, t_h = 0, t_x = 0, t_y = 0;double *w = 0, *hist2 = 0;double sum_w = 0, x1 = 0, x2 = 0, y1 = 2.0, y2 = 2.0;int q_r, q_g, q_b;int *q_temp;//Mat pic_hist;t_w = drawing_box.width;t_h = drawing_box.height;Mat pic_hist = Mat(300, 200, CV_8UC3); //生成直方图图像 hist2 = (double *)malloc(sizeof(double) * 4096);w = (double *)malloc(sizeof(double) * 4096);q_temp = (int *)malloc(sizeof(int)*t_w*t_h);while ((pow(y2, 2) + pow(y1, 2) > 0.5) && (num < NUM)){num++;t_x = drawing_box.x;t_y = drawing_box.y;memset(q_temp, 0, sizeof(int)*t_w*t_h);for (i = 0; i < 4096; i++){w[i] = 0.0;hist2[i] = 0.0;}for (i = t_y; i < t_h + t_y; i++){for (j = t_x; j < t_w + t_x; j++){//rgb颜色空间量化为16*16*16 bins /*q_r = ((u_char)current->imageData[i * current->widthStep + j * 3 + 2]) / 16;q_g = ((u_char)current->imageData[i * current->widthStep + j * 3 + 1]) / 16;q_b = ((u_char)current->imageData[i * current->widthStep + j * 3 + 0]) / 16;*/q_r = current.at<Vec3b>(i, j)[2] / 16;q_g = current.at<Vec3b>(i, j)[1] / 16;q_b = current.at<Vec3b>(i, j)[0] / 16;q_temp[(i - t_y) *t_w + j - t_x] = q_r * 256 + q_g * 16 + q_b;hist2[q_temp[(i - t_y) *t_w + j - t_x]] = hist2[q_temp[(i - t_y) *t_w + j - t_x]] + m_wei[(i - t_y) * t_w + j - t_x];}}//归一化直方图 for (i = 0; i < 4096; i++){hist2[i] = hist2[i] / C;//printf("%f\n",hist2[i]); }//生成目标直方图 double temp_max = 0.0;for (i = 0; i < 4096; i++) //求直方图最大值,为了归一化 {if (temp_max < hist2[i]){temp_max = hist2[i];}}//画直方图 Point p1, p2;double bin_width = pic_hist.cols / (4368);double bin_unith = pic_hist.rows / temp_max;for (i = 0; i < 4096; i++){p1.x = i * bin_width;p1.y = pic_hist.cols;p2.x = (i + 1)*bin_width;p2.y = pic_hist.rows - hist2[i] * bin_unith;rectangle(pic_hist, p1, p2, Scalar(0, 255, 0), -1, 8, 0);}imwrite("hist2.jpg", pic_hist);for (i = 0; i < 4096; i++){if (hist2[i] != 0){w[i] = sqrt(hist1[i] / hist2[i]);}else{w[i] = 0;}}sum_w = 0.0;x1 = 0.0;x2 = 0.0;for (i = 0; i < t_h; i++){for (j = 0; j < t_w; j++){//printf("%d\n",q_temp[i * t_w + j]); sum_w = sum_w + w[q_temp[i * t_w + j]];x1 = x1 + w[q_temp[i * t_w + j]] * (i - t_h / 2);x2 = x2 + w[q_temp[i * t_w + j]] * (j - t_w / 2);}}y1 = x1 / sum_w;y2 = x2 / sum_w;//中心点位置更新 drawing_box.x += y2;drawing_box.y += y1;}rectangle(current, Point(drawing_box.x, drawing_box.y), Point(drawing_box.x + drawing_box.width, drawing_box.y + drawing_box.height), Scalar(255, 0, 0), 2);imshow("Meanshift", current);}void onMouse(int event, int x, int y, int flags, void *param){if (pause){switch (event){case EVENT_MOUSEMOVE:if (g_bDrawingBox){drawing_box.width = x - drawing_box.x;drawing_box.height = y - drawing_box.y;}break;case CV_EVENT_LBUTTONDOWN:g_bDrawingBox = true;drawing_box = Rect(x, y, 0, 0);//记录起始点//the left up point of the rect //drawing_box.x = x;//drawing_box.y = y;break;case CV_EVENT_LBUTTONUP://finish drawing the rect (use color green for finish) g_bDrawingBox = false;xx = true;drawing_box.width = x - drawing_box.x;drawing_box.height = y - drawing_box.y;rectangle(current, drawing_box.tl(), drawing_box.br(), Scalar(255, 0, 0), 2);//目标初始化 hist1 = (double *)malloc(sizeof(double) * 16 * 16 * 16);m_wei = (double *)malloc(sizeof(double)*drawing_box.height*drawing_box.width);init_target(hist1, m_wei, current);is_tracking = true;//imshow("Meanshift", current);break;}imshow("Meanshift", current);return;}}int main(){ShowHelpText();VideoCapture capture("E://dd4.mp4");capture.grab(); //从视频文件或捕获设备获取下一帧 capture.retrieve(current);//解码并返回抓取了的视频帧 while (1){if (is_tracking){MeanShift_Tracking(current);}int c = waitKey(1);//暂停 if (c == 's'){while (1){pause = true;setMouseCallback("Meanshift", onMouse, 0);current.copyTo(tempImage);if (g_bDrawingBox)rectangle(tempImage, drawing_box.tl(), drawing_box.br(), Scalar(255, 0, 0), 2);if (xx == true)break;waitKey(2);imshow("Meanshift", tempImage);}}while (pause){if (waitKey(0) == 's')pause = false;}//if (current.size != 0)try { imshow("Meanshift", current); }catch (exception& e) { cout << "视频播放完毕"; return 0; }//else//break;capture.grab(); //从视频文件或捕获设备获取下一帧 capture.retrieve(current);//解码并返回抓取了的视频帧 }namedWindow("Meanshift", 1);return 0;}void ShowHelpText(){//输出欢迎信息和OpenCV版本printf("\n1.这是根据原有作者的c接口opencv升级的c++接口程序,适用于opencv2.0版本,开发环境为VS2015+opencv3.2\n");printf("\n2.程序视频的默认路径为(E\\dd4.mp4)\n");printf("\n3.视频启动后按 s 键进行暂停,然后用鼠标选取需要跟踪的矩形框,再次按 s 视频启动进行跟踪\n");printf("\n4.程序有个bug,视频播放完毕会报错");//printf("\n\n ----------------------------------------------------------------------------\n");//输出一些帮助信息//printf("\n\n\n\t欢迎来到【鼠标交互演示】示例程序\n");//printf("\n\n\t请在窗口中点击鼠标左键并拖动以绘制矩形\n");}
阅读全文
0 0
- MeanShift的目标跟踪算法opencv c++接口代码 VS2015+opencv3.2
- MeanShift的目标跟踪算法
- MeanShift的目标跟踪算法
- MeanShift的目标跟踪算法
- 基于MeanShift的视频目标跟踪算法及代码实现
- MeanShift 目标跟踪算法
- meanShift算法用于目标跟踪的优缺点
- meanShift算法用于目标跟踪的优缺点
- 基于MeanShift的目标跟踪算法
- 基于MeanShift的目标跟踪算法、实现
- OpenCV meanshift目标跟踪总结
- OpenCV meanshift目标跟踪总结
- Opencv目标跟踪—CamShift和meanshift算法
- 基于Opencv的MeanShift跟踪算法实现
- 基于Opencv的MeanShift跟踪算法实现
- 基于Opencv的MeanShift跟踪算法实现
- 基于Opencv的MeanShift跟踪算法实现
- 基于Opencv的MeanShift跟踪算法实现
- C++之类和对象
- 架构闲聊之:伪架构过度设计有多可怕
- STM32——中断
- tensorflow学习笔记之简单自编码器实现
- 原来IC是这样设计的,竟然90%的人都不知道!
- MeanShift的目标跟踪算法opencv c++接口代码 VS2015+opencv3.2
- 计蒜客-等和的分隔子集
- Ceph的Paxos源码注释
- 向函数传递结构体
- 第八届蓝桥杯省赛真题
- Scala学习笔记
- linux下使用gdb调试崩溃丶死锁实例
- 表单的三种提交方式
- Odd Palindromes Two Pointers