MoveTrace.cpp
上传用户:czshopping
上传日期:2022-05-22
资源大小:5430k
文件大小:22k
源码类别:

视频捕捉/采集

开发平台:

Visual C++

  1. // MoveTrace.cpp: implementation of the CMoveTrace class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "VideoMove.h"
  6. #include "MoveTrace.h"
  7. #ifdef _DEBUG
  8. #undef THIS_FILE
  9. static char THIS_FILE[]=__FILE__;
  10. #define new DEBUG_NEW
  11. #endif
  12. //////////////////////////////////////////////////////////////////////
  13. // Construction/Destruction
  14. //////////////////////////////////////////////////////////////////////
  15. CMoveTrace::CMoveTrace()
  16. {
  17. m_prect=NULL;
  18. m_pImageData=m_pGrey=m_pGrey1=m_pGrey2=m_pMosaic=NULL;
  19. }
  20. CMoveTrace::~CMoveTrace()
  21. {
  22. }
  23. bool CMoveTrace::Initialize(const int nImageWidth, const int nImageHeight, 
  24. const int nWidthCount, const int nHeightCount,
  25. const int nBitsCount)
  26. {
  27. m_nExtractWidth = m_nImageWidth  =  nImageWidth;
  28. m_nExtractHeight = m_nImageHeight =  nImageHeight;
  29. m_nX=m_nY=1;
  30. m_Count = 0; 
  31. m_rect.SetRectEmpty();
  32. m_nWidthCount = nWidthCount; //设置将屏幕分割的横向份数
  33. m_nHeightCount = nHeightCount; //设置将屏幕分割的纵向份数
  34. m_nDivisionWidth = m_nImageWidth/m_nWidthCount; //分割后的每一个小区域的宽度(象素)
  35. m_nDivisionHeight = m_nImageHeight/m_nHeightCount; //分割后的每一个小区域的高度(象素)
  36. m_prect = new CRect*[m_nHeightCount];
  37. for (int i=0;i<m_nHeightCount;++i)
  38. m_prect[i]=new CRect[nWidthCount];
  39. for(int y=0; y<m_nHeightCount; y++)
  40. {
  41. for(int x=0; x<m_nWidthCount; x++)
  42. {
  43. m_prect[y][x] = CRect(x*m_nDivisionWidth, y*m_nDivisionHeight,
  44. x*m_nDivisionWidth+m_nDivisionWidth,
  45. y*m_nDivisionHeight+m_nDivisionHeight);
  46. }
  47. }
  48. if (!m_pGrey)
  49. delete m_pGrey;
  50. m_pGrey = new BYTE[m_nImageHeight*m_nImageWidth]; 
  51. memset(m_pGrey,0,m_nImageHeight*m_nImageWidth);
  52. ////////////////////////////////////////////////
  53. if (!m_pGrey1)
  54. delete m_pGrey1;
  55. m_pGrey1 = new BYTE[m_nImageHeight*m_nImageWidth]; 
  56. memset(m_pGrey1,0,m_nImageHeight*m_nImageWidth);
  57. if (!m_pGrey2)
  58. delete m_pGrey2;
  59. m_pGrey2 = new BYTE[m_nImageHeight*m_nImageWidth]; 
  60. memset(m_pGrey2,0,m_nImageHeight*m_nImageWidth);
  61. if (!m_pMosaic)
  62. delete m_pMosaic;
  63. m_pMosaic = new BYTE[m_nImageHeight*m_nImageWidth];
  64. memset(m_pMosaic,0,m_nImageHeight*m_nImageWidth);
  65. return  m_pGrey && m_pGrey1 && m_pMosaic && m_pGrey2 && m_pImageData;
  66. }
  67. void CMoveTrace::Uninitialize()
  68. {
  69. if (m_pGrey)
  70. delete m_pGrey; 
  71. if (m_pGrey1)
  72. delete m_pGrey1;
  73. if (m_pGrey2)
  74. delete m_pGrey2;
  75. if(m_pMosaic)
  76. delete m_pMosaic;
  77. // m_prect = new CRect*[m_nHeightCount];
  78. for (int i=0;i<m_nHeightCount;++i)
  79. delete[] m_prect[i];
  80. delete[] m_prect;
  81. m_pImageData=m_pGrey=m_pGrey1=m_pGrey2=m_pMosaic=NULL;
  82. m_prect=NULL;
  83. }
  84. bool CMoveTrace::GetDIBBit(unsigned char * pImageData)
  85. {
  86. if(!pImageData)
  87. return false;
  88. m_pImageData   =  pImageData;
  89. return true;
  90. }
  91. bool CMoveTrace::Grey()
  92. {
  93. int nIndex=0,x1,y1;
  94. for(int y=0;y<m_nImageHeight;y+=m_nY)
  95. {
  96. y1=m_nImageHeight-y;
  97. for(int x=0;x<m_nImageWidth;x+=m_nX)
  98. {
  99. x1=m_nImageWidth-x;
  100. int nPos = (y1*m_nImageWidth+x1)*3;
  101. // int nTemp1 = m_pImageData[nPos];
  102. // int nTemp2 = m_pImageData[nPos+1];
  103. // int nTemp3 = m_pImageData[nPos+2];
  104. // m_pGrey1[x/m_nX+y*m_nExtractWidth/m_nY] = 
  105. m_pGrey1[nIndex++] = 
  106. static_cast<unsigned char>(m_pImageData[nPos+2]*0.3+m_pImageData[nPos+1]*0.59+m_pImageData[nPos]*0.11);
  107. }
  108. }
  109. return true;
  110. }
  111. void CMoveTrace::Dither(int nThreshold)
  112. {
  113. double dbTotalValue=0;
  114. int nTotal=m_nExtractHeight*m_nExtractWidth;
  115. int nIndex=0;
  116. for (int i=0;i<nTotal;++i)
  117. {
  118. (*(m_pMosaic+nIndex))=
  119. (*(m_pMosaic+nIndex))>nThreshold ? 255:0;
  120. ++nIndex;
  121. }
  122. }
  123. int CMoveTrace::Sobel()
  124. {
  125. int ImageValue,ImageValueX,ImageValueY;
  126. unsigned char *pImageDataTemp;
  127. pImageDataTemp=new unsigned char[m_nExtractWidth*m_nExtractHeight];
  128. if (pImageDataTemp==NULL)
  129. {
  130. return 0;//内存分配错误
  131. }
  132. memcpy(pImageDataTemp, m_pGrey1, m_nExtractWidth*m_nExtractHeight);
  133. int nPos=m_nExtractWidth;
  134. int i_end=m_nExtractHeight-1;
  135. int j_end=m_nExtractWidth-1;
  136. for (int i=1;i<i_end;++i)
  137. {
  138. for (int j=1;j<j_end;++j)
  139. {
  140. ImageValueX=-(*(pImageDataTemp+nPos-m_nExtractWidth+j-1)) 
  141. -2*(*(pImageDataTemp+nPos-m_nExtractWidth+j))
  142. -(*(pImageDataTemp+nPos-m_nExtractWidth+j+1))
  143. +(*(pImageDataTemp+nPos+m_nExtractWidth+j-1))
  144. +2*(*(pImageDataTemp+nPos+m_nExtractWidth+j))
  145. +(*(pImageDataTemp+nPos+m_nExtractWidth+j+1));
  146. ImageValueY=-(*(pImageDataTemp+nPos-m_nExtractWidth+j-1))
  147. +(*(pImageDataTemp+nPos-m_nExtractWidth+j))
  148. -2*(*(pImageDataTemp+nPos+j-1))
  149. +2*(*(pImageDataTemp+nPos+j+1))
  150. -(*(pImageDataTemp+nPos+m_nExtractWidth+j-1))
  151. +(*(pImageDataTemp+nPos+m_nExtractWidth+j+1));
  152. ImageValue=abs(max(ImageValueX,ImageValueY));
  153. if (ImageValue>255)
  154. {
  155. *(m_pGrey1+nPos+j)=255;
  156. }
  157. else
  158. {
  159. *(m_pGrey1+nPos+j)=static_cast<unsigned char>(ImageValue);
  160. }
  161. }
  162. nPos+=m_nExtractWidth;
  163. }
  164. delete [] pImageDataTemp;
  165. return 1;
  166. }
  167. BOOL CMoveTrace::FrameMinus()
  168. {
  169. for(int x=0; x<m_nExtractWidth*m_nExtractHeight; ++x)
  170. {
  171. m_pGrey[x]=abs(m_pGrey1[x] - m_pGrey2[x]);
  172. }
  173. return TRUE;
  174. }
  175. void CMoveTrace::Mosaic(int nMosaicWidth,const int nMosaicHeight)
  176. {
  177. m_nMosaicWidth = nMosaicWidth;
  178. m_nMosaicHeight = nMosaicHeight;
  179. int nW,nH;
  180. nW=m_nExtractWidth/nMosaicWidth;
  181. nH=m_nExtractHeight/nMosaicHeight;
  182. // nW=m_nImageWidth%nMosaicWidth==0 ? m_nImageWidth/nMosaicWidth : m_nImageWidth/nMosaicWidth;
  183. // nH=m_nImageHeight%nMosaicHeight==0?m_nImageHeight/nMosaicHeight : m_nImageHeight/nMosaicHeight;
  184. double dbTemp;
  185. int nTemp;
  186. int nArea=nMosaicWidth*nMosaicHeight;
  187. // unsigned char nImageValue;
  188. int i,j,ii,jj;
  189. int n_i_pos=0;
  190. int n_j_pos=0;
  191. int n_ii_pos=0;
  192. int n_jj_pos=0;
  193. for (i=0;i<nH;++i)
  194. {
  195. n_j_pos=0;
  196. for (j=0;j<nW;++j)
  197. {
  198. dbTemp=0;
  199. for (ii=0;ii<nMosaicHeight;++ii)
  200. {
  201. n_ii_pos=(n_i_pos+ii)*m_nExtractWidth+n_j_pos;
  202. for (jj=0;jj<nMosaicWidth;++jj)
  203. {
  204. dbTemp+=m_pGrey[n_ii_pos+jj];
  205. }
  206. }
  207. nTemp=static_cast<BYTE>(dbTemp/nArea);
  208. for (ii=0;ii<nMosaicHeight;++ii)
  209. {
  210. n_ii_pos=(n_i_pos+ii)*m_nExtractWidth+n_j_pos;
  211. for (jj=0;jj<nMosaicWidth;++jj)
  212. {
  213. m_pMosaic[n_ii_pos+jj]=nTemp;
  214. }
  215. }
  216. n_j_pos+=nMosaicWidth;
  217. }
  218. n_i_pos+=nMosaicHeight;
  219. }
  220. }
  221. void CMoveTrace::SaveFrame()
  222. {
  223. int nTotal=m_nExtractWidth*m_nExtractHeight;
  224. for(int x=0; x<nTotal; ++x)
  225. {
  226. m_pGrey2[x] = m_pGrey1[x];
  227. }
  228. }
  229. /*
  230. int CMoveTrace::Mean()
  231. {
  232. double dbTotalValue=0;
  233. for (int i=0;i<m_nImageHeight;++i)
  234. {
  235. for (int j=0;j<m_nImageWidth;++j)
  236. {
  237. dbTotalValue+=*(m_pImageData+i*m_nImageWidth+j);
  238. }
  239. }
  240. return static_cast<int>(dbTotalValue/(m_nImageHeight*m_nImageWidth));
  241. }
  242. */
  243. bool CMoveTrace::Rectangle(CRect &rect,const int nMaxWidth, const int nMinChange)
  244. {
  245. CRect tempRect;
  246. POINT centerPoint, tmpPoint;
  247. centerPoint.x = m_nExtractWidth/2;
  248. centerPoint.y = m_nExtractHeight/2;
  249. int i,j;
  250. bool bTopFind=false;
  251. bool bBottomFind=false;
  252. int nIndex=0;
  253. for (i=0;i<m_nExtractHeight;++i)
  254. {
  255. for (j=0;j<m_nExtractWidth;++j)
  256. {
  257. if (*(m_pMosaic+nIndex)!=0 && !bTopFind)
  258. tempRect.top=m_nExtractHeight-1-i, tempRect.left=j, bTopFind=true;
  259. else if (*(m_pMosaic+nIndex)!=0 && bTopFind && tempRect.left>j)
  260. tempRect.left=j;
  261. ++nIndex;
  262. }
  263. }
  264. nIndex=m_nExtractWidth*m_nExtractHeight-1;
  265. for (i=m_nExtractHeight-1;i>-1 && bTopFind ;--i)
  266. {
  267. for (j=m_nExtractWidth-1;j>-1;--j)
  268. {
  269. if (*(m_pMosaic+nIndex)!=0 && !bBottomFind)
  270. tempRect.bottom=m_nExtractHeight-1-i, tempRect.right=j, bBottomFind=true;
  271. else if (*(m_pMosaic+nIndex)!=0 && bBottomFind && tempRect.right<j)
  272. tempRect.right=j;
  273. --nIndex;
  274. }
  275. }
  276. //交换top和bottom的值
  277. int temp = tempRect.top;
  278. tempRect.top = tempRect.bottom;
  279. tempRect.bottom = temp;
  280. //如果发现的活动区域过大(大于分割的矩形区域)则忽略
  281. if(tempRect.Width()>=m_nDivisionWidth ||
  282. tempRect.Height()>=m_nDivisionHeight)
  283. return false;
  284. if(bTopFind && bBottomFind && m_Count==0)//发现有新的运动物体
  285. {
  286. m_rect = tempRect;
  287. rect.left = m_rect.left*m_nX;
  288. rect.right = m_rect.right*m_nX;
  289. rect.top = m_rect.top*m_nY;
  290. rect.bottom = m_rect.bottom*m_nY;
  291. m_Count = 1; //设置有运动物体的标志
  292. Forecast(rect); //求得运动物体在屏幕中的位置
  293. return true;
  294. }
  295. else if (!(bTopFind && bBottomFind) && m_Count == 1)//如果没有找到运动物体但是有运动物体
  296. {
  297. tmpPoint = m_rect.CenterPoint();
  298. BOOL bFlag = abs(tmpPoint.x-centerPoint.x)<nMaxWidth;
  299. //如果运动物体的中心到监视区域中心的距离时候小于预设值,
  300. //则认为物体没有消失,否则物体消失
  301. if(bFlag)
  302. {
  303. //将上次的框保留下来
  304. rect.left = m_rect.left*m_nX;
  305. rect.right = m_rect.right*m_nX;
  306. rect.top = m_rect.top*m_nY;
  307. rect.bottom = m_rect.bottom*m_nY;
  308. Forecast(rect);
  309. return true;
  310. }
  311. else
  312. {
  313. //认为没有运动物体,将变量复位
  314. m_Count = 0;
  315. m_rect.SetRectEmpty();
  316. return false;
  317. }
  318. }
  319. else if(m_Count == 1 && bTopFind && bBottomFind)//有物体并且检测到有运动(有白点产生)
  320. {
  321. int nChangePix = m_nMosaicWidth*nMinChange;
  322. int nH=tempRect.Height();
  323. int nW=tempRect.Width();
  324. //如果检测到物体的运动范围小于最小运动范围(nMinChange*m_nMosaicWidth)
  325. //将范围适当变大
  326. // if (min(abs(nH),abs(nW) )<nMinChange*m_nMosaicWidth )
  327. if (nH<nMinChange*m_nMosaicHeight || nW<nMinChange*m_nMosaicWidth )
  328. {
  329. tempRect.left-=m_nMosaicWidth*2;
  330. tempRect.left = (tempRect.left<0) ? 0: tempRect.left;
  331. tempRect.right+=m_nMosaicWidth*2;
  332. tempRect.right = (tempRect.right>m_nImageWidth)? m_nImageWidth : tempRect.right;
  333. tempRect.bottom+=m_nMosaicHeight*2;
  334. tempRect.bottom = (tempRect.bottom>m_nImageHeight) ? m_nImageHeight : tempRect.bottom;
  335. tempRect.top-=m_nMosaicHeight*2;
  336. tempRect.top = (tempRect.top<0) ? 0 : tempRect.top;
  337. }
  338. int ntempTop =  abs(tempRect.top - m_rect.top); //得到这次的纵向的运动范围和上次的纵向运动范围的
  339. int ntempBottom = abs(tempRect.bottom - m_rect.bottom); //和上次的纵向运动范围的绝对值
  340. //如果变化过大,则调整变化速度
  341. if( ntempTop>nChangePix || ntempBottom>nChangePix)
  342. {
  343. m_rect.left = tempRect.left;
  344. m_rect.right = tempRect.right;
  345. if(abs(tempRect.bottom-m_rect.bottom) > nChangePix)
  346. tempRect.bottom-m_rect.bottom > 0 ? m_rect.bottom+=nChangePix : m_rect.bottom-=nChangePix;
  347. if(abs(tempRect.top-m_rect.top) > nChangePix)
  348. tempRect.top-m_rect.top > 0 ? m_rect.top+=nChangePix : m_rect.top-=nChangePix;
  349. }
  350. m_rect=tempRect;
  351. rect.left = m_rect.left*m_nX;
  352. rect.right = m_rect.right*m_nX;
  353. rect.top = m_rect.top*m_nY;
  354. rect.bottom = m_rect.bottom*m_nY;
  355. Forecast(rect);
  356. return true;
  357. }
  358. return false;
  359. }
  360. bool CMoveTrace::Rectangle2(CRect &rect, const int nMaxWidth, const int nMinChange)
  361. {
  362. CRect tempRect;
  363. POINT centerPoint, tmpPoint;
  364. centerPoint.x = m_nExtractWidth/2;
  365. centerPoint.y = m_nExtractHeight/2;
  366. int nMosaicArea = m_nMosaicWidth*m_nMosaicHeight;
  367. long nWhiteCount = 1;
  368. long nTempX = 0;
  369. long nTempY = 0;
  370. for(int y=1; y<m_nExtractHeight-1; ++y)
  371. {
  372. for(int x=1; x<m_nExtractWidth-1; ++x)
  373. {
  374. if((255==m_pMosaic[x+y*m_nExtractWidth])
  375. && (255==m_pMosaic[x+m_nExtractWidth+y*m_nExtractWidth])
  376. //&& (255==lpVideo->m_pGrey1[x+1+y*lpVideo->m_iWidth])
  377. )
  378. {
  379. ++nWhiteCount;
  380. nTempX += x;
  381. nTempY += y;
  382. }
  383. }
  384. }
  385. nTempX = nTempX/nWhiteCount;
  386. nTempY = m_nExtractHeight-1-nTempY/nWhiteCount;
  387. // nTempY = nTempY/nWhiteCount;
  388. long nharfTempW = nWhiteCount/nMosaicArea/m_nX; //矩形框的半宽度
  389. long nharfTempH = nharfTempW*3; //矩形框的半高度
  390. // tempRect.left = abs(nTempX-nharfTempW);
  391. // tempRect.top = abs(nTempY-nharfTempH);
  392. (nTempX-nharfTempW)<0 ? tempRect.left = 0 : tempRect.left = nTempX-nharfTempW;
  393. (nTempY-nharfTempH)<0 ? tempRect.top = 0 : tempRect.top = nTempY-nharfTempH;
  394. (nTempX+nharfTempW)>m_nExtractWidth ? tempRect.right = m_nExtractWidth : tempRect.right = nTempX+nharfTempW;
  395. (nTempY+nharfTempH)>m_nExtractHeight ? tempRect.bottom = m_nExtractHeight : tempRect.bottom = nTempY+nharfTempH;
  396. if(tempRect.left==0  && tempRect.right==m_nExtractWidth && tempRect.top==0 && tempRect.bottom==m_nExtractHeight)
  397. return false;
  398. if(nWhiteCount>=nMosaicArea && m_rect.IsRectNull())//发现有新的运动物体
  399. {
  400. m_rect = tempRect;
  401. rect.left = m_rect.left*m_nX;
  402. rect.right = m_rect.right*m_nX;
  403. rect.top = m_rect.top*m_nY;
  404. rect.bottom = m_rect.bottom*m_nY;
  405. m_Count = 1;
  406. return true;
  407. }
  408. else if (m_Count == 1 && nWhiteCount<nMosaicArea)
  409. {
  410. tmpPoint = m_rect.CenterPoint();
  411. BOOL bFlag;
  412. bFlag = abs(tmpPoint.x-centerPoint.x) < nMaxWidth;
  413. if(bFlag)
  414. {
  415. rect.left = m_rect.left*m_nX;
  416. rect.right = m_rect.right*m_nX;
  417. rect.top = m_rect.top*m_nY;
  418. rect.bottom = m_rect.bottom*m_nY;
  419. return true;
  420. }
  421. else
  422. {
  423. m_Count = 0;
  424. m_rect.SetRectEmpty();
  425. rect = m_rect;
  426. return false;
  427. }
  428. }
  429. else if(m_Count == 1 && nWhiteCount>=nMosaicArea)
  430. {
  431. // int nH=tempRect.Height();
  432. int nW=tempRect.Width();
  433. int nChangePix = m_nMosaicWidth*nMinChange;
  434. if (nW<nMinChange*m_nMosaicWidth)// (min(nH,nW)<nMinChange*m_nMosaicWidth )
  435. {
  436. tempRect.left-=m_nMosaicWidth*2;
  437. if (tempRect.left < 0)
  438. tempRect.left=0;
  439. tempRect.right+=m_nMosaicWidth*2;
  440. if (tempRect.right > m_nExtractWidth)
  441. tempRect.right = m_nExtractWidth;
  442. tempRect.top-=m_nMosaicHeight*2;
  443. if (tempRect.top < 0)
  444. tempRect.top=0;
  445. tempRect.bottom+=m_nMosaicHeight*2;
  446. if (tempRect.bottom>m_nExtractHeight)
  447. tempRect.bottom = m_nExtractHeight;
  448. }
  449. int ntempTop =  abs(tempRect.top - m_rect.top);
  450. int ntempBottom = abs(tempRect.bottom - m_rect.bottom);
  451. if( ntempTop>nChangePix || ntempBottom>nChangePix)
  452. {
  453. // if(abs(tempRect.left-m_rect.left) > nChangePix)
  454. // tempRect.left-m_rect.left > 0 ? m_rect.left+=nChangePix : m_rect.left-=nChangePix;
  455. //
  456. // if(abs(tempRect.right-m_rect.right) > nChangePix)
  457. // tempRect.right-m_rect.right > 0 ? m_rect.right+=nChangePix : m_rect.right-=nChangePix;
  458. m_rect.left = tempRect.left;
  459. m_rect.right = tempRect.right;
  460. if(abs(tempRect.bottom-m_rect.bottom) > nChangePix)
  461. tempRect.bottom-m_rect.bottom > 0 ? m_rect.bottom+=nChangePix : m_rect.bottom-=nChangePix;
  462. if(abs(tempRect.top-m_rect.top) > nChangePix)
  463. tempRect.top-m_rect.top > 0 ? m_rect.top+=nChangePix : m_rect.top-=nChangePix;
  464. rect.left = m_rect.left*m_nX;
  465. rect.right = m_rect.right*m_nX;
  466. rect.top = m_rect.top*m_nY;
  467. rect.bottom = m_rect.bottom*m_nY;
  468. return true;
  469. }
  470. m_rect=tempRect;
  471. rect.left = m_rect.left*m_nX;
  472. rect.right = m_rect.right*m_nX;
  473. rect.top = m_rect.top*m_nY;
  474. rect.bottom = m_rect.bottom*m_nY;
  475. return true;
  476. }
  477. return false;
  478. }
  479. bool CMoveTrace::Extract(int nX, int nY)
  480. {
  481. if (nX && nY)
  482. {
  483. m_nExtractWidth=m_nImageWidth/nX;
  484. m_nExtractHeight=m_nImageHeight/nY;
  485. m_nX=nX,m_nY=nY;
  486. return true;
  487. }
  488. else
  489. return false;
  490. }
  491. void CMoveTrace::Forecast(CRect rect)
  492. {
  493. if(NULL==m_prect) AfxMessageBox("没有初始化!");
  494. int x,y;
  495. for(y=0;y<m_nHeightCount;y++)
  496. {
  497. for(x=0;x<m_nWidthCount;x++)
  498. {
  499. if( m_prect[y][x].PtInRect(CPoint(rect.left, rect.top))
  500. && m_prect[y][x].PtInRect(CPoint(rect.right, rect.top))
  501. && m_prect[y][x].PtInRect(rect.CenterPoint()) )
  502. {
  503. m_NextRect = m_CurrentRect;
  504. m_CurrentRect = m_prect[y][x];
  505. break;
  506. }
  507. else
  508. {
  509. //--------------
  510. }
  511. }
  512. }
  513. /* if(NULL==m_prect) AfxMessageBox("没有初始化!");
  514. int x,y;
  515. for(y=0;y<m_nHeightCount;y++)
  516. {
  517. for(x=0;x<m_nWidthCount;x++)
  518. {
  519. if(m_prect[y][x].PtInRect(rect.CenterPoint()))
  520. {
  521. m_NextRect = m_CurrentRect = m_prect[y][x];
  522. //判断下一个是否在左上的单元
  523. if(nIndex/m_nWidthCount>0 && nIndex%m_nWidthCount>0)
  524. {
  525. if(rect.left <= m_prect[nIndex-m_nWidthCount-1].right
  526. && rect.top <= m_prect[nIndex-m_nWidthCount-1].bottom)
  527. {
  528. m_NextRect = m_prect[nIndex-m_nWidthCount-1];
  529. break;
  530. }
  531. }
  532. //判断下一个是否在左边的单元
  533. //if(nIndex-1 >= 0)
  534. if(nIndex%m_nWidthCount>0)
  535. {
  536. if(rect.left <= m_prect[nIndex-1].right
  537. && rect.bottom < m_prect[nIndex-1].bottom
  538. && rect.top > m_prect[nIndex-1].top)
  539. {
  540. m_NextRect = m_prect[nIndex-1];
  541. break;
  542. }
  543. }
  544. //判断下一个是否在左下边的单元
  545. //if(nIndex+m_nWidthCount-1 < m_nWidthCount*m_nHeightCount)
  546. if( (nIndex/m_nWidthCount<m_nHeightCount-1) &&
  547. (nIndex%m_nWidthCount>0) )
  548. {
  549. if(rect.left <= m_prect[nIndex+m_nWidthCount-1].right
  550. && rect.bottom >= m_prect[nIndex+m_nWidthCount-1].top)
  551. {
  552. m_NextRect = m_prect[nIndex+m_nWidthCount-1];
  553. break;
  554. }
  555. }
  556. //判断下一个是否在右上边的单元
  557. if( nIndex/m_nWidthCount>0 
  558. && (nIndex%m_nWidthCount < m_nWidthCount-1) ) //该单元必须有上一排单元
  559. {
  560. if(rect.right >= m_prect[nIndex-m_nWidthCount+1].left
  561. && rect.top <= m_prect[nIndex-m_nWidthCount+1].bottom) 
  562. {
  563. m_NextRect = m_prect[nIndex-m_nWidthCount+1];
  564. break;
  565. }
  566. }
  567. //判断下一个是否在右边的单元
  568. if(nIndex%m_nWidthCount < m_nWidthCount-1)
  569. {
  570. if(rect.right >= m_prect[nIndex+1].left
  571. && rect.top > m_prect[nIndex+1].top
  572. && rect.bottom < m_prect[nIndex+1].bottom)
  573. {
  574. m_NextRect = m_prect[nIndex+1];
  575. break;
  576. }
  577. }
  578. //判断下一个是否在右下边的单元
  579. //if(nIndex+m_nWidthCount+1 < m_nWidthCount*m_nHeightCount)
  580. if( (nIndex%m_nWidthCount < m_nWidthCount-1) 
  581. && (nIndex/m_nWidthCount<m_nHeightCount-1) )
  582. {
  583. if(rect.right >= m_prect[nIndex+m_nWidthCount+1].left
  584. &&rect.bottom >= m_prect[nIndex+m_nWidthCount+1].top)
  585. {
  586. m_NextRect = m_prect[nIndex+m_nWidthCount+1];
  587. break;
  588. }
  589. }
  590. //判断下一个是否在上边的单元
  591. if( nIndex/m_nWidthCount>0 )
  592. {
  593. if(rect.top <= m_prect[nIndex-m_nWidthCount].bottom
  594. && rect.left > m_prect[nIndex-m_nWidthCount].left
  595. && rect.right < m_prect[nIndex-m_nWidthCount].right)
  596. {
  597. m_NextRect = m_prect[nIndex-m_nWidthCount];
  598. break;
  599. }
  600. }
  601. //判断下一个是否在下边的单元
  602. //if(nIndex+m_nWidthCount < m_nWidthCount*m_nHeightCount)
  603. if( nIndex/m_nWidthCount<m_nHeightCount-1 )
  604. {
  605. if(rect.bottom >= m_prect[nIndex+m_nWidthCount].top
  606. && rect.left > m_prect[nIndex+m_nWidthCount].left
  607. && rect.right < m_prect[nIndex+m_nWidthCount].right)
  608. {
  609. m_NextRect = m_prect[nIndex+m_nWidthCount];
  610. break;
  611. }
  612. }
  613. }//if(m_prect[nIndex].PtInRect(rect.CenterPoint()))
  614. nIndex++;
  615. }//for(x=0;x<m_nWidthCount;x++)
  616. }
  617. */
  618. }
  619. void CMoveTrace::JudgeAnalysis(int off)
  620. {
  621. /*int isize = m_nExtractWidth*m_nExtractHeight;//抽取后高度
  622. unsigned char* result = m_pGrey1+off*isize;
  623. int width=m_nExtractWidth;
  624. int height=m_nExtractHeight;
  625.     double variance[256];
  626. int i, j, threshold;
  627. int level, Th;
  628. double bmax=0.0;
  629. double mean, mean1, mean2;
  630. double counter, counter1, counter2;
  631. double sum, sum1, sum2;
  632. //get the maximum grey level of original image
  633.     level=-9999;
  634. int nIndex=0;
  635. for(i=0; i<height; i++) 
  636. for(j=0; j<width; j++) 
  637. {
  638. level=(level<m_pGrey1[nIndex]) ? m_pGrey1[nIndex] : level;
  639. ++nIndex;
  640. }
  641. }
  642. if(level<=1)  return ;
  643. counter=(double)isize;
  644. //get the globel mean value
  645. sum=0.0;
  646. nIndex=0;
  647. for(i=0; i<height; i++) 
  648. {
  649. for(j=0; j<width; j++) 
  650. {
  651. sum=sum+m_pGrey1[nIndex];
  652.             mean=sum/counter;
  653. ++nIndex;
  654. }
  655. }*/
  656. /********* the beginning of Th loop ********
  657. grey less than threshold Th belong to Class 1;
  658. grey more than threshold Th belong to Class 2;
  659. where Th=0, 1, 2, 3, ..., level         ************/
  660. /* for(Th=0; Th<=level; Th++)
  661. {
  662. //get the mean value of every class
  663. sum1=0.0; 
  664. sum2=0.0;
  665. counter1=0;
  666. counter2=0;
  667. for(i=0; i<height; i++) 
  668. {
  669. int line=i*width;
  670. for(j=0; j<width; j++) 
  671. {
  672. if(m_pGrey1[line+j]<Th)
  673. {
  674. counter1=counter1+1;
  675. sum1=sum1+m_pGrey1[line+j];
  676. }
  677. else
  678. {
  679. counter2=counter2+1;
  680. sum2=sum2+m_pGrey1[line+j];
  681. }
  682. }
  683. }
  684. if(counter1>0) mean1=sum1/counter1;
  685. else mean1=0;
  686.         if(counter2>0) mean2=sum2/counter2;
  687. else mean2=0;
  688. //calcuate the variance between classes
  689. variance[Th]=counter1*counter2*(mean1-mean2)*(mean1-mean2);
  690. }
  691. // get maximum variance to determine the best threshold
  692. for(Th=1; Th<=level; Th++)
  693. {
  694. if(bmax<variance[Th])
  695. {
  696. bmax=variance[Th];
  697. threshold=Th;
  698. }
  699. }
  700. ///////////////////////////////
  701. // do thresholding
  702. for(i=0; i<height-22; i++) 
  703. {
  704. int line=i*width;
  705. for(j=0; j<width; j++) 
  706. {
  707. result[line+j] = (m_pGrey1[line+j] >= threshold) ? 255: 0;
  708. }
  709. }*/
  710. ///////////////////////////
  711. }
  712. int CMoveTrace::GetThreshold(const int nMinThreshold)
  713. {
  714. //循环变量
  715. long i;
  716. //直方图数组
  717. long lHistogram[256];
  718. //阈值,最大灰度值与最小灰度值,两个区域的平均灰度值
  719. unsigned char iThreshold,iNewThreshold,iMaxGrayValue,iMinGrayValue,iMean1GrayValue,iMean2GrayValue;
  720. //用于计算区域灰度平均值的中间变量
  721. long lP1,lP2,lS1,lS2;
  722. //迭代次数
  723. int iIterationTimes;
  724. memset(lHistogram,0,sizeof(lHistogram));
  725. //获得直方图
  726. iMaxGrayValue = 0;
  727. iMinGrayValue = 255;
  728. int nIndex=0;
  729. int nTotal=m_nExtractWidth*m_nExtractHeight;
  730. for (i = 0;i < nTotal ;i++)
  731. {
  732. lHistogram[m_pGrey1[nIndex]]++;
  733. //修改最大,最小灰度值
  734. if(iMinGrayValue > m_pGrey1[nIndex])
  735. {
  736. iMinGrayValue = m_pGrey1[nIndex];
  737. }
  738. if(iMaxGrayValue < m_pGrey1[nIndex])
  739. {
  740. iMaxGrayValue = m_pGrey1[nIndex];
  741. }
  742. ++nIndex;
  743. }
  744. //迭代求最佳阈值
  745. iNewThreshold = (iMinGrayValue + iMaxGrayValue)/2;
  746. iThreshold = 0;
  747. for(iIterationTimes = 0; iThreshold != iNewThreshold && iIterationTimes < 100;iIterationTimes ++)
  748. {
  749. iThreshold = iNewThreshold;
  750. lP1 =0;
  751. lP2 =0;
  752. lS1 = 1;
  753. lS2 = 1;
  754. //求两个区域的灰度平均值
  755. for (i = iMinGrayValue;i < iThreshold;i++)
  756. {
  757. lP1 += lHistogram[i]*i;
  758. lS1 += lHistogram[i];
  759. }
  760. iMean1GrayValue = (unsigned char)(lP1 / lS1);
  761. for (i = iThreshold+1;i < iMaxGrayValue;i++)
  762. {
  763. lP2 += lHistogram[i]*i;
  764. lS2 += lHistogram[i];
  765. }
  766. iMean2GrayValue = (unsigned char)(lP2 / lS2);
  767. iNewThreshold =  (iMean1GrayValue + iMean2GrayValue)/2;
  768. }
  769. TRACE(";;;;;;;;;;;;;;;;;;;;;;;;;;;%d",iThreshold);
  770. return max(nMinThreshold, iThreshold);
  771. }