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. //*Delta += dd;
  40. *Delta += ((*scoreNext-*scorePrev)/(*scoreInit-(*scoreNext+*scorePrev)/2));
  41. } else *Delta=0;
  42. }
  43. return 1;
  44. }
  45. int subpixelDisparity_mmx(float *scorePrev, float *scoreInit, float* scoreNext,
  46.   float *Delta,  int l)
  47. {
  48. const float two_float = -2.0f;
  49. if (l < 8) return 0;              // image size must be at least 8 bytes 
  50.   __asm 
  51.   {
  52.    // make 4 copies of the constant 'radius' in xmm0
  53. movss xmm0, two_float
  54. movss xmm1, xmm0
  55. unpcklps xmm0, xmm1        
  56. movlhps xmm0, xmm0
  57.         mov eax, scorePrev     
  58.         mov ebx, scoreInit
  59. mov ecx, scoreNext
  60.         mov edi, Delta    
  61.         mov edx, l   
  62.         shr edx, 2
  63. align 16
  64. inner_loop:
  65. movaps xmm1,[eax] // xmm1=scorePrev
  66. movaps xmm3,[ecx] // xmm3=scoreNext
  67. movaps  xmm4, xmm1  // xmm4 = scorePrev
  68. movaps xmm2,[ebx] // xmm2=scoreInit
  69. subps   xmm4, xmm3 // xmm4 = scorePrev - scoreNext
  70. // xmm4 = delta = scorePrev - scoreNext
  71. // scoreInit = -2*(scorePrev + scoreNext -2*scoreInit)
  72. movaps  xmm5, [edi]
  73. mulps   xmm2, xmm0 // nspsbMpy1(-2.0, scoreInit, nbPoints);
  74. addps   xmm2, xmm1 // nspsbAdd2(scorePrev, scoreInit, nbPoints);
  75. addps   xmm2, xmm3 // nspsbAdd2(scoreNext, scoreInit, nbPoints);
  76. mulps   xmm2, xmm0 // warning : nspsbMpy1(-2.0, scoreInit, nbPoints);
  77. // delta = delta/scoreInit
  78. divps  xmm4, xmm2
  79. // delta += dispFloat
  80. subps xmm5, xmm4
  81. movaps  [edi], xmm5
  82.         add eax,16         
  83.         add ebx,16    
  84. add ecx, 16
  85.         add edi,16
  86.         dec edx      
  87.         jnz inner_loop    
  88.         emms   
  89.   }
  90.   return 1;
  91. }
  92. void StereoMatching::getList_subPixel(StereoImage* sdata, int sc, const StereoBuffer* sb)
  93. {
  94. if (sb==NULL) sb = sbuffer+sc;
  95. // create idx list of valid  pixels
  96. sdata->createValidPixelsList(maskSizeY/2+1);
  97. // estimate subpixel disparities for each valid pixel
  98. getList_subPixel(sdata->x, sdata->y, 
  99.  sdata->depth_float_list, sdata->m_nGood3DPoints,
  100.  sb, sdata->imDepth8u, sc);
  101. // build imDepth32f from x, y, depth_float_list and m_nGood3DPoints
  102. sdata->generateDepth32f();
  103. sdata->generateDepth8uFromDepth32f();
  104. }
  105. // does not check whether disp is in the good range
  106. // estimate 'delta', sub-pixels disparities of pixel lists (x,y) of image depth
  107. void StereoMatching::getList_subPixel(const short* x, const short* y, 
  108.   float* depth_list, int nbPoints,
  109.   const StereoBuffer* sb, uchar* imDepth_used,
  110.   int sc)
  111. {
  112. if (nbPoints>0) {
  113. int i, idx;
  114. int maxDisparity = (int)(nbDepth/pow(2.0f, sc));
  115. float* ptPrev=scorePrev, *ptInit=scoreInit, *ptNext=scoreNext;
  116. uchar disp;
  117. float* ptDelta = depth_list;
  118. // -----------------------------------------
  119. // prepare lists of disparity and SAD scores
  120. for (i=0; i<nbPoints; ++i,++x,++y,++ptPrev,++ptInit,++ptNext,++ptDelta) {
  121. // set index
  122. idx = *x + sb->width*(*y);
  123. // set current disparity
  124. *ptDelta = disp = __max(0, __min( maxDisparity-1, *(imDepth_used + idx)));
  125. // set SAD scores for (disp-1, disp and disp+1)
  126. *ptInit = *(sb->buff[disp] + idx);
  127. *ptPrev = *(sb->buff[__max(disp-1,0)] + idx);
  128. *ptNext = *(sb->buff[__min(disp+1,maxDisparity-1)] + idx);
  129. /*if ((*ptInit)*2 >= (*ptPrev + *ptNext)) {
  130. *ptPrev = *ptNext = *ptInit+20;
  131. }*/
  132. }
  133. // -----------------------------------------
  134. // compute sub-pixel disparities
  135. subpixelDisparity(scorePrev, scoreInit, scoreNext, depth_list, nbPoints);
  136. }
  137. }