均值漂移(meanshift)算法查找物体

2024-01-25 15:38

本文主要是介绍均值漂移(meanshift)算法查找物体,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

均值漂移算法以迭代的方式锁定概率函数的局部最大值,它的原理是寻找预定义窗口中数据点的重心,或者说加权平均值。将窗口重心移动到数据点的重心处,并重复这个过程直到窗口重心收敛到一个稳定点。

反投影直方图的结果是一个概率映射,作用在于替换一个输入图像中的每个像素值,使其变成归一化直方图中对应的概率值,体现了已知图像的特定内容出现在图像中特定位置的概率。

下面一个简单的例子演示如何利用meanshift算法查找物体。

主要步骤:选定ROI,计算并归一化ROI的直方图,根据得到的直方图计算出ROI在色调通道的反投影直方图,代入meanshift算法更新ROI的位置。整个过程使用HSV颜色空间的Hue通道来描述物体。

 

 
  1. #include"cv.h"

  2. #include"highgui.h"

  3. #include <iostream>

  4. using namespace std;

  5. using namespace cv;

  6.  
  7. Mat image;//最终显示图像

  8. Mat histimg = Mat(200, 300, CV_8UC3,Scalar::all(0));//最终显示直方图

  9.  
  10. const char* keys = {

  11. "{camera|camera num|0|The PC'camera number}"

  12. };

  13. string err_cp = "\n\t\topen camera failed\n\t\t";

  14. Point origin;//用于保存鼠标选择第一次单击时点的位置

  15. Rect selection;//用于保存鼠标选择的矩形框

  16. Rect trackWindow;//追踪的选择区域

  17. int trackObject = 0; //代表跟踪目标数目

  18. bool selectObject = false;//代表是否在选要跟踪的初始目标,true表示正在用鼠标选择

  19. bool showHist = true;

  20. bool pause = false;

  21. int * channels = { 0 };

  22. float range[2] = { 0, 180 };

  23. const float * hranges = range;

  24.  
  25. void mousecallback(int event,int x,int y,int flags,void* param){

  26. if (selectObject)//只有当鼠标左键按下去时才有效,然后通过if里面代码就可以确定所选择的矩形区域selection了

  27. {

  28. selection.x = MIN(x, origin.x);//矩形左上角顶点坐标

  29. selection.y = MIN(y, origin.y);

  30. selection.width = std::abs(x - origin.x);//矩形宽

  31. selection.height = std::abs(y - origin.y);//矩形高

  32. selection &= Rect(0, 0, image.cols, image.rows);//用于确保所选的矩形区域在图片范围内

  33. }

  34. switch (event){

  35. case CV_EVENT_LBUTTONDOWN:

  36. origin = Point(x, y);

  37. selection = Rect(x, y, 0, 0);//鼠标刚按下去时初始化了一个矩形区域

  38. selectObject = true;

  39. break;

  40. case CV_EVENT_LBUTTONUP:

  41. selectObject = false;

  42. trackObject = 0; //代表跟踪目标数目

  43. if (selection.width > 0 && selection.height > 0)

  44. trackObject = -1;

  45. break;

  46. }

  47. }

  48. void direct(){

  49. cout << "\n\n\t图像跟踪程序\n"

  50. << "\t\t鼠标左键选择ROI进行跟踪\n"

  51. << "\t\tq--退出程序\n"

  52. << "\t\th--显示/关闭直方图\n"

  53. << "\t\tp--程序暂停\n"

  54. << "\t\tc--清除ROI\n";

  55. }

  56. int main(int argc, char** argv){

  57. system("color 5E");

  58. direct();

  59. VideoCapture cp;

  60. Mat hsv, hue,mask, hist, backproj;

  61. CommandLineParser parser(argc, argv, keys);//命令解析器函数

  62. int cpnum = parser.get<int>("camera");

  63. cp.open(cpnum);

  64. if (!cp.isOpened()){

  65. cout << err_cp;

  66. parser.printParams();

  67. system("pause");

  68. return -1;

  69. }

  70. namedWindow("摄像头扑捉",1);

  71. Mat frame;

  72. setMouseCallback("摄像头扑捉",mousecallback);

  73. int histsize = 16;

  74.  
  75. while (1){

  76. if (!pause)

  77. cp >> frame;

  78. if (frame.empty()) break;

  79. //rectangle(frame,selection,Scalar(0,0,255),2);//测试鼠标

  80. frame.copyTo(image);

  81. cvtColor(frame,hsv,CV_BGR2HSV);

  82. //开始追踪处理

  83.  
  84. if (trackObject&&!pause){

  85. inRange(hsv,Scalar(0,10,30),Scalar(180,256,256),mask);

  86. hue.create(hsv.size(),hsv.depth());

  87. int ch[] = {0,0};

  88. mixChannels(&hsv,1,&hue,1,ch,1);

  89. //对selection的处理

  90. if (trackObject<0){

  91. Mat roi(hue, selection), maskroi(mask, selection);

  92. calcHist(&roi,1,channels,maskroi,hist,1,&histsize,&hranges);

  93. normalize(hist,hist,0,255,CV_MINMAX);

  94. histimg = Scalar::all(0);

  95. Mat color(1,histsize,CV_8UC3);//设定颜色板,显示ROI的Hist

  96. for (int i = 0; i < histsize; i++){

  97. color.at<Vec3b>(i) = Vec3b(saturate_cast<int>(hist.at<float>(i)*180/255), 255, 255);//HSV

  98. }

  99. cvtColor(color,color,CV_HSV2BGR);

  100. //显示ROI的直方图

  101. for (int i = 0; i < histsize; i++){

  102. int val = saturate_cast<int>( hist.at<float>(i)*histimg.cols/180);

  103. int w = histimg.rows / histsize;

  104. rectangle(histimg,Point(i*w,histimg.cols-val),Point((i+1)*w,histimg.cols),Scalar(color.at<Vec3b>(i)),-1);

  105.  
  106. }

  107.  
  108.  
  109. trackWindow = selection;

  110. trackObject = 1;

  111.  
  112. }

  113. calcBackProject(&hue,1,channels,hist,backproj,&hranges);

  114. backproj &= mask;

  115. meanShift(backproj,trackWindow,TermCriteria(CV_TERMCRIT_EPS|CV_TERMCRIT_ITER,10,1));

  116. rectangle(image, trackWindow, Scalar(0, 0, 255), 2);

  117.  
  118. }

  119. //没有选定矩形区域,只显示视频

  120.  
  121. if (selectObject && selection.width > 0 && selection.height > 0)//鼠标选取时的阴影

  122. {

  123. //Mat roi(image, selection);

  124. //bitwise_not(roi, roi);//bitwise_not为将每一个bit位取反

  125. rectangle(image, selection, Scalar(0, 0, 255), 2);

  126. }

  127.  
  128.  
  129. imshow("摄像头扑捉",image);

  130. if (showHist) {

  131. namedWindow("ROI直方图", 1);

  132. imshow("ROI直方图", histimg);

  133. }

  134. else

  135. destroyWindow("ROI直方图");

  136.  
  137. char c=waitKey(33);

  138. switch (c){

  139. case 'q':

  140. return 0;

  141. break;

  142. case 'h':

  143. showHist = !showHist;

  144. break;

  145. case 'p':

  146. pause = !pause;

  147. case 'c':

  148. trackObject = 0;

  149. histimg = Scalar::all(0);

  150. break;

  151.  
  152. }

  153.  
  154. }

  155.  
  156. }

运行截图

这篇关于均值漂移(meanshift)算法查找物体的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/643730

相关文章

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

秋招最新大模型算法面试,熬夜都要肝完它

💥大家在面试大模型LLM这个板块的时候,不知道面试完会不会复盘、总结,做笔记的习惯,这份大模型算法岗面试八股笔记也帮助不少人拿到过offer ✨对于面试大模型算法工程师会有一定的帮助,都附有完整答案,熬夜也要看完,祝大家一臂之力 这份《大模型算法工程师面试题》已经上传CSDN,还有完整版的大模型 AI 学习资料,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

dp算法练习题【8】

不同二叉搜索树 96. 不同的二叉搜索树 给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。 示例 1: 输入:n = 3输出:5 示例 2: 输入:n = 1输出:1 class Solution {public int numTrees(int n) {int[] dp = new int

Codeforces Round #240 (Div. 2) E分治算法探究1

Codeforces Round #240 (Div. 2) E  http://codeforces.com/contest/415/problem/E 2^n个数,每次操作将其分成2^q份,对于每一份内部的数进行翻转(逆序),每次操作完后输出操作后新序列的逆序对数。 图一:  划分子问题。 图二: 分而治之,=>  合并 。 图三: 回溯:

最大公因数:欧几里得算法

简述         求两个数字 m和n 的最大公因数,假设r是m%n的余数,只要n不等于0,就一直执行 m=n,n=r 举例 以18和12为例 m n r18 % 12 = 612 % 6 = 06 0所以最大公因数为:6 代码实现 #include<iostream>using namespace std;/