subPixel.cpp
上传用户:fengshi120
上传日期:2014-07-17
资源大小:6155k
文件大小:5k
源码类别:

3D图形编程

开发平台:

C/C++

  1. /*************************************************************************** 
  2. *
  3. * Copyright 2000 by David Demirdjian.   All rights reserved. 
  4. *  
  5. * Developed  by David Demirdjian
  6. *  
  7. * Permission to use, copy, or modify this software and  its documentation 
  8. * for  educational  and  research purposes only and without fee  is hereby 
  9. * granted, provided  that this copyright notice and the original authors's 
  10. * names appear  on all copies and supporting documentation.  If individual 
  11. * files are  separated from  this  distribution directory  structure, this 
  12. * copyright notice must be included.  For any other uses of this software, 
  13. * in original or  modified form, including but not limited to distribution 
  14. * in whole or in  part, specific  prior permission  must be  obtained from 
  15. * MIT.  These programs shall not  be  used, rewritten, or  adapted as  the 
  16. * basis  of  a  commercial  software  or  hardware product  without  first 
  17. * obtaining appropriate  licenses from David Demirdjian.  The author makes 
  18. * no representations about the suitability of this software for any purpose.  
  19. * It is provided "as is" without express or implied warranty. 
  20. *  
  21. **************************************************************************/
  22. #include "stdafx.h"
  23. #include "stereoMatching.h"
  24. #include "processingMMX.h"
  25. #include <stdio.h>
  26. #ifdef _DEBUG
  27. #define new DEBUG_NEW
  28. #undef THIS_FILE
  29. static char THIS_FILE[] = __FILE__;
  30. #endif
  31. int subpixelDisparity(float *scorePrev, float *scoreInit, float* scoreNext,
  32.   float *Delta,  int l)
  33. {
  34. for (int i=0; i<l; ++i,++scorePrev,++scoreInit,++scoreNext,++Delta) {
  35. if (*Delta>0) {
  36. float A2 = *scoreNext-*scoreInit;
  37. float A0 = *scoreInit-*scorePrev;
  38. float dd = 0.5f*(A0+A2)/(A0-A2);
  39. /*if (fabs(dd)>1)  {
  40. float err0 = *scorePrev;
  41. float err1 = *scoreInit;
  42. float err2 = *scoreNext;
  43. float err4 = 1.0f;
  44. }*/
  45. *Delta += dd;
  46. } else *Delta=0;
  47. }
  48. return 1;
  49. }
  50. int subpixelDisparity_mmx(float *scorePrev, float *scoreInit, float* scoreNext,
  51.   float *Delta,  int l)
  52. {
  53. const float two_float = -2.0f;
  54. if (l < 8) return 0;              // image size must be at least 8 bytes 
  55.   __asm 
  56.   {
  57.    // make 4 copies of the constant 'radius' in xmm0
  58. movss xmm0, two_float
  59. movss xmm1, xmm0
  60. unpcklps xmm0, xmm1        
  61. movlhps xmm0, xmm0
  62.         mov eax, scorePrev     
  63.         mov ebx, scoreInit
  64. mov ecx, scoreNext
  65.         mov edi, Delta    
  66.         mov edx, l   
  67.         shr edx, 2
  68. align 16
  69. inner_loop:
  70. movaps xmm1,[eax] // xmm1=scorePrev
  71. movaps xmm3,[ecx] // xmm3=scoreNext
  72. movaps  xmm4, xmm1  // xmm4 = scorePrev
  73. movaps xmm2,[ebx] // xmm2=scoreInit
  74. subps   xmm4, xmm3 // xmm4 = scorePrev - scoreNext
  75. // xmm4 = delta = scorePrev - scoreNext
  76. // scoreInit = -2*(scorePrev + scoreNext -2*scoreInit)
  77. movaps  xmm5, [edi]
  78. mulps   xmm2, xmm0 // nspsbMpy1(-2.0, scoreInit, nbPoints);
  79. addps   xmm2, xmm1 // nspsbAdd2(scorePrev, scoreInit, nbPoints);
  80. addps   xmm2, xmm3 // nspsbAdd2(scoreNext, scoreInit, nbPoints);
  81. mulps   xmm2, xmm0 // warning : nspsbMpy1(-2.0, scoreInit, nbPoints);
  82. // delta = delta/scoreInit
  83. divps  xmm4, xmm2
  84. // delta += dispFloat
  85. subps xmm5, xmm4
  86. movaps  [edi], xmm5
  87.         add eax,16         
  88.         add ebx,16    
  89. add ecx, 16
  90.         add edi,16
  91.         dec edx      
  92.         jnz inner_loop    
  93.         emms   
  94.   }
  95.   return 1;
  96. }
  97. void StereoMatching::getList_subPixel(StereoImage* sdata, int sc, const StereoBuffer* sb)
  98. {
  99. if (sb==NULL) sb = sbuffer+sc;
  100. // create idx list of valid  pixels
  101. sdata->createValidPixelsList(maskSizeY/2+1);
  102. // estimate subpixel disparities for each valid pixel
  103. getList_subPixel(sdata->x, sdata->y, 
  104.  sdata->depth_float_list, sdata->m_nGood3DPoints,
  105.  sb, sdata->imDepth8u, sc);
  106. // build imDepth32f from x, y, depth_float_list and m_nGood3DPoints
  107. sdata->generateDepth32f();
  108. sdata->generateDepth8uFromDepth32f();
  109. }
  110. // does not check whether disp is in the good range
  111. // estimate 'delta', sub-pixels disparities of pixel lists (x,y) of image depth
  112. void StereoMatching::getList_subPixel(const short* x, const short* y, 
  113.   float* depth_list, int nbPoints,
  114.   const StereoBuffer* sb, uchar* imDepth_used,
  115.   int sc)
  116. {
  117. if (nbPoints>0) {
  118. int i, idx;
  119. int maxDisparity = (int)(nbDepth/pow(2, sc));
  120. float* ptPrev=scorePrev, *ptInit=scoreInit, *ptNext=scoreNext;
  121. uchar disp;
  122. float* ptDelta = depth_list;
  123. // -----------------------------------------
  124. // prepare lists of disparity and SAD scores
  125. for (i=0; i<nbPoints; ++i,++x,++y,++ptPrev,++ptInit,++ptNext,++ptDelta) {
  126. // set index
  127. idx = *x + sb->width*(*y);
  128. // set current disparity
  129. *ptDelta = disp = __max(0, __min( maxDisparity-1, *(imDepth_used + idx)));
  130. // set SAD scores for (disp-1, disp and disp+1)
  131. *ptInit = *(sb->buff[disp] + idx);
  132. *ptPrev = *(sb->buff[__max(disp-1,0)] + idx);
  133. *ptNext = *(sb->buff[__min(disp+1,maxDisparity-1)] + idx);
  134. /*if ((*ptInit)*2 >= (*ptPrev + *ptNext)) {
  135. *ptPrev = *ptNext = *ptInit+20;
  136. }*/
  137. }
  138. // -----------------------------------------
  139. // compute sub-pixel disparities
  140. subpixelDisparity(scorePrev, scoreInit, scoreNext, depth_list, nbPoints);
  141. }
  142. }