MeanShiftSegger.cpp
上传用户:smdfuse
上传日期:2015-11-06
资源大小:98k
文件大小:7k
源码类别:

图形图象

开发平台:

Visual C++

  1. #include "MeanShiftSegger.h"
  2. #include "math.h"
  3. int max(int x,int y)
  4. {
  5. if(x > y)
  6. return x;
  7. return y;
  8. }
  9. int min(int x,int y)
  10. {
  11. if(x > y)
  12. return y;
  13. return x;
  14. }
  15. /***********************************************************************
  16. * 函数名称:
  17. *     MeanShiftSegger()
  18. *
  19. *说明:构造函数 
  20. ***********************************************************************/
  21. MeanShiftSegger::MeanShiftSegger():
  22. imgWidth(0),imgHeight(0){
  23.     for(int i = 0; i < HISTOGRAM_LENGTH; i ++)
  24. currHistogram[i] = 0;
  25.     for(i = 0; i < HISTOGRAM_LENGTH; i ++)
  26. tempHistogram[i] = 0;
  27. //memset(currHistogram,0,sizeof(float) * HISTOGRAM_LENGTH);
  28. //memset(tempHistogram,0,sizeof(float) * HISTOGRAM_LENGTH);
  29. //SetZeroHistogram(currHistogram);
  30. //SetZeroHistogram(tempHistogram);
  31. return;
  32. }
  33. /***********************************************************************
  34. * 函数名称:
  35. *     ~MeanShiftSegger()
  36. * 说明:
  37. *     析构函数
  38. ***********************************************************************/
  39. MeanShiftSegger::~MeanShiftSegger(){
  40. }
  41. /***********************************************************************
  42. * 函数名称:
  43. *     InitMeanShiftTracker()
  44. * 参数:
  45. *     unsigned char * firstFrame 第一帧缓冲
  46. *     int frameWidth-帧宽度
  47. *     int frameHeight-帧高度
  48. *     int targetPosX-目标位置横坐标
  49. *     int targetPosY-目标位置纵坐标
  50. *     int targetWidth-目标宽度
  51. *     int targetHeight-目标高度
  52. * 说明:MeanShift过程跟踪初始化程序
  53. ***********************************************************************/
  54. void MeanShiftSegger::InitMeanShiftTracker(unsigned char*  firstFrame,int frameWidth,int frameHeight,int targetPosX,int targetPosY,int targetWidth,int targetHeight){
  55. this->imgWidth = frameWidth;
  56. this->imgHeight = frameHeight;
  57. this->currentX = targetPosX;
  58. this->currentY = targetPosY;
  59. this->trackWinHeight = targetHeight;
  60. this->trackWinWidth = targetWidth;
  61. }
  62. /***********************************************************************
  63. * 函数名称:
  64. *     CalculateHistogramSp
  65. * 参数:
  66. *     image frame-当前输入帧
  67. *     char kernel-核类型选择(目前只支持Uniform核)
  68. *     float * histogram-直方图缓冲
  69. * 说明:统计直方图,建立区域模型(无参数概率密度估计)
  70. ***********************************************************************/
  71. int MeanShiftSegger::CalculateHistogramSp(unsigned char*  frame,char kernel, float *histogram){
  72. int pxValue = 0;
  73. for(int i = 0 ; i < HISTOGRAM_LENGTH; i++)
  74. histogram[i] = 0;
  75. if(kernel == 'U')
  76. {
  77. for(int j = max(0,currentY - trackWinHeight / 2);j < min(currentY + trackWinHeight / 2,imgHeight - 1); j ++){
  78. for(int i = max(0,currentX - trackWinWidth / 2); i < min(currentX + trackWinWidth / 2,imgWidth - 1);i ++){
  79. pixel r = frame[j * imgWidth * 3 + i * 3] / 16;
  80. pixel g = frame[j * imgWidth * 3 + i * 3 + 1] / 16;
  81. pixel b = frame[j * imgWidth * 3 + i * 3 + 2] / 16;
  82. histogram[256 * (int)r + 16 * (int)g + (int)b] += 1;
  83. pxValue ++;
  84. }
  85. }
  86. for(int i = 0; i < HISTOGRAM_LENGTH; i ++)
  87. histogram[i] /= pxValue;
  88. }
  89. else
  90. {
  91. return 0;
  92. }
  93. return pxValue;
  94. }
  95. /***********************************************************************
  96. * 函数名称:
  97. *     MeanShiftTrackerProcess
  98. * 参数:
  99. *     unsigned char *frame-当前帧缓冲
  100. * 说明:跟踪中的MeanShift过程
  101. ***********************************************************************/
  102. void MeanShiftSegger::MeanShiftProcessSp(unsigned char * frame){
  103. float weights[HISTOGRAM_LENGTH];
  104. float newX = 0.0;
  105. float newY = 0.0;
  106. for (int i=0;i<HISTOGRAM_LENGTH;i++)
  107. {
  108. if (currHistogram[i] >0.0 )
  109. weights[i] = (float)tempHistogram[i]/(float)currHistogram[i];
  110. //目标模板直方图/当前直方图
  111. else
  112. weights[i] = 0;
  113. }
  114. float sumOfWeights = 0.0;
  115. for(int j = max(0,currentY - trackWinHeight / 2);j < min(currentY + trackWinHeight / 2,imgHeight - 1); j ++){
  116. for(int i = max(0,currentX - trackWinWidth / 2); i < min(currentX + trackWinWidth / 2,imgWidth - 1);i ++){
  117. pixel r = frame[j * imgWidth * 3 + i * 3] / 16;
  118. pixel g = frame[j * imgWidth * 3 + i * 3 + 1] / 16;
  119. pixel b = frame[j * imgWidth * 3 + i * 3 + 2] / 16;
  120. int ptr = (int)(256 * (int)r + 16 * (int)g + (int)b);
  121. newX += (weights[ptr] * (float)i);
  122. newY += (weights[ptr] * (float)j);
  123. sumOfWeights += weights[ptr];
  124. }
  125. }
  126. if(sumOfWeights != 0){
  127. currentX = int((newX/sumOfWeights) + 0.5);
  128. currentY = int((newY/sumOfWeights) + 0.5);
  129. }
  130. return;
  131. }
  132. /***********************************************************************
  133. * 函数名称
  134. *     MeanShiftTrackProcess 
  135. * 参数:
  136. *     image frame-当前输入帧
  137. *     int frameNumber-输入帧号
  138. * 说明:MeanShift跟踪主调用过程
  139. ***********************************************************************/
  140. void MeanShiftSegger::MeanShiftTrackProcess(unsigned char*  frame,int frameNumber)
  141. {
  142. if(frameNumber == 0){
  143. //在指定位置建立目标模型
  144. CalculateHistogramSp(frame,'U',this->tempHistogram);
  145. }
  146. else
  147. {
  148. int stopThreshold = 10;
  149. int iteratorCoumt = 0;
  150. while(iteratorCoumt < stopThreshold){
  151. //在后续帧中检测目标新位置
  152. CalculateHistogramSp(frame,'U',this->currHistogram);
  153. MeanShiftProcessSp(frame); //获得新位置
  154. //更新直方图
  155. iteratorCoumt++;
  156. }
  157. DrawTrackBox(frame);
  158. }
  159. }
  160. /***********************************************************************
  161. * 函数名称:
  162. *     DrawTrackBox
  163. * 参数:
  164. *     unsigned char * frame-当前帧缓冲
  165. * 说明:在输出中画跟踪窗口
  166. ***********************************************************************/
  167. void MeanShiftSegger::DrawTrackBox(unsigned char*  frame)
  168. {
  169. for(int i = currentX; i < min(imgWidth,currentX + trackWinWidth); i ++)
  170. {
  171. frame[currentY * imgWidth * 3 + i * 3 + 0] = 0;
  172. frame[currentY * imgWidth * 3 + i * 3 + 1] = 0;
  173. frame[currentY * imgWidth * 3 + i * 3 + 2] = 255;
  174. frame[min(imgHeight - 1,currentY + trackWinHeight) * imgWidth * 3 + i * 3 + 0] = 0;
  175. frame[min(imgHeight - 1,currentY + trackWinHeight) * imgWidth * 3 + i * 3 + 1] = 0;
  176. frame[min(imgHeight - 1,currentY + trackWinHeight) * imgWidth * 3 + i * 3 + 2] = 255;
  177. }
  178. for(int j = currentY; j < min(imgHeight - 1,currentY + trackWinHeight); j ++)
  179. {
  180. frame[j * imgWidth * 3 + currentX * 3 + 0] = 0;
  181. frame[j * imgWidth * 3 + currentX * 3 + 1] = 0;
  182. frame[j * imgWidth * 3 + currentX * 3 + 2] = 255;
  183. frame[j * imgWidth * 3 + min(imgWidth - 1,currentX + trackWinWidth) * 3 + 0] = 0;
  184. frame[j * imgWidth * 3 + min(imgWidth - 1,currentX + trackWinWidth) * 3 + 1] = 0;
  185. frame[j * imgWidth * 3 + min(imgWidth - 1,currentX + trackWinWidth) * 3 + 2] = 255;
  186. }
  187. }
  188. /***********************************************************************
  189. * 函数名称:
  190. *     CalculateBhattacharyya
  191. * 说明:计算Bhattachryya
  192. ***********************************************************************/
  193. float MeanShiftSegger::CalculateBhattacharyya(float initHistogram [HISTOGRAM_LENGTH],float tempHistogram[HISTOGRAM_LENGTH]){
  194. float dis = 0;
  195. for(int i = 0;i < HISTOGRAM_LENGTH ;i ++)
  196. dis += float(sqrt(double(currHistogram[i] * tempHistogram[i])));
  197. return dis;
  198. }