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

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. // ************************************************************
  26. // ************************************************************
  27. // *** Main algorithm for stereo computation
  28. // ************************************************************
  29. // ************************************************************
  30. typedef unsigned char uchar;
  31. typedef unsigned short ushort;
  32. #ifdef _DEBUG
  33. #define new DEBUG_NEW
  34. #undef THIS_FILE
  35. static char THIS_FILE[] = __FILE__;
  36. #endif
  37. #define _PROCESS_AND_COMPARE_SSE2_ 
  38. ImgSubandAdd_sse2(imr8_bw , imtop8_bw +(i+k)*width , iml8_bw +(i+k) ,ptBuff , subImageSize); 
  39. sum_Row_mmx(ptBuff , ptBuff16+2*backStep, subImageSize, maskSizeX); 
  40. avg_Col_mmx(ptBuff16+backStep , ptBuff-backStep,subImageSize, width, maskSizeY); 
  41. copyMMX(ptBuff16, ptBuff16+subImageSize, 2*backStep*sizeof(short));  
  42. findMinimumCorrelation_mmx(ptBuff-backStep, i+k, imDepth8u+offset-backStep, 
  43. corrScore+offset-backStep,  corrScoreSec+offset-backStep,
  44. subImageSize);
  45. void StereoMatching::estimateStereo(const uchar* iml8_bw, 
  46. const uchar* imr8_bw,
  47. const uchar* imtop8_bw,
  48. int width, int height, int maskSizeX, int maskSizeY, 
  49. char minDiff, int nbDepth, int nbPartitions,
  50. StereoBuffer* sb, StereoImage* sdata)
  51. {
  52. // assure good partitioning (.....)
  53. while (height/nbPartitions - 2*(maskSizeY/2) <=0) {
  54. nbPartitions /= 2;
  55. }
  56. int i,j,k;
  57. int subImageSize=width*height/nbPartitions;
  58. int backStep = (maskSizeY/2)*width;
  59. uchar* ptBuff;
  60. ushort* ptBuff16;
  61. int siz;
  62. // ----------- process the first sub-images -----------
  63. for (i=0; i<nbDepth; i+=8) {
  64. ptBuff = sb->buff[i];
  65. ImgSubandAdd2(imr8_bw , imtop8_bw +i*width , iml8_bw +i , ptBuff , subImageSize, sb->buffStep, width);
  66. for (k=0; k<8; ++k) 
  67. {
  68. ptBuff = sb->buff[i+k];
  69. ptBuff16 = sb->buff16[i+k];
  70. siz = __max(0, subImageSize - 2*backStep);
  71. sum_Row_mmx(ptBuff , ptBuff16 , subImageSize,maskSizeX);
  72. avg_Col_mmx(ptBuff16+backStep, ptBuff+backStep, siz, width, maskSizeY);
  73. copyMMX(ptBuff16,ptBuff16+subImageSize-2*backStep,2*backStep*sizeof(short));
  74. if (i==0 && k==0) 
  75. initMinimumCorrelation(ptBuff, 0, sdata->imDepth8u, sb->corrScore, sb->corrScoreSec, subImageSize);
  76. else
  77. findMinimumCorrelation_mmx(ptBuff+backStep, i+k, sdata->imDepth8u+backStep, 
  78. sb->corrScore+backStep, sb->corrScoreSec+backStep,
  79. subImageSize-backStep);
  80. }
  81. }
  82. // check that there are enough diff. between best and second disp
  83. compareBestAndSecond(sb->corrScore+backStep, sb->corrScoreSec+backStep, minDiff, 
  84.  sdata->UNDEFINED_DEPTH, sdata->imDepth8u+backStep, subImageSize-backStep);
  85. int offset=subImageSize;
  86. // ----------- process the other ones -----------
  87. for (j=1; j<nbPartitions; ++j, offset+=subImageSize) 
  88. {
  89. // process depth i=0
  90. i=0;
  91. ptBuff = sb->buff[0]+offset;
  92. ptBuff16 = sb->buff16[0];
  93. // estimate absolute differences between the 3 stereo images
  94. ImgSubandAdd2(imr8_bw +offset, imtop8_bw + i*width +offset,  iml8_bw + i +offset,
  95.    ptBuff, subImageSize, sb->buffStep, width);
  96. // ptBuff16 data from [0] to [backStep] come from previous iter
  97. // sum_Row_mmx fills ptBuff16 from [2*backStep] to [2*backStep+subImageSize]
  98. sum_Row_mmx(ptBuff , ptBuff16+2*backStep, subImageSize, maskSizeX);
  99. // avg_Col_mmx process data in ptBuff16 from [0] to [subImageSize]
  100. avg_Col_mmx(ptBuff16+backStep , ptBuff-backStep,subImageSize, width, maskSizeY);
  101. // then copy ptBuff16 data [subImageSize] to [2*backStep+subImageSize]
  102. // to [0] to [2*backStep]
  103. copyMMX(ptBuff16, ptBuff16+subImageSize, 2*backStep*sizeof(short));
  104. // find minimum SAD score
  105. initMinimumCorrelation(ptBuff-backStep, 0, sdata->imDepth8u+offset-backStep, 
  106.    sb->corrScore+offset-backStep, sb->corrScoreSec+offset-backStep, subImageSize);
  107. // do stuff 7 times
  108. for (k=1; k<=7; ++k) {
  109. ptBuff+=sb->buffStep; ptBuff16+=sb->buffStep;
  110. sb->filterSAD(maskSizeX, maskSizeY, ptBuff, ptBuff16, 
  111.   backStep, subImageSize, offset);
  112. findMinimumCorrelation_mmx(ptBuff-backStep, i+k, sdata->imDepth8u+offset-backStep, 
  113.  sb->corrScore+offset-backStep, 
  114. sb->corrScoreSec+offset-backStep,
  115. subImageSize);
  116. }
  117. for (i=8; i<nbDepth; i+=8) {
  118. ptBuff = sb->buff[i]+offset;
  119. ptBuff16 = sb->buff16[i];
  120. // estimate absolute differences between the 3 stereo images
  121. ImgSubandAdd2(imr8_bw +offset, imtop8_bw + i*width +offset,  iml8_bw + i +offset,
  122. ptBuff, subImageSize, sb->buffStep, width);
  123. // process and comparison 
  124. for (k=0; k<=7; ++k) {
  125. sb->filterSAD(maskSizeX, maskSizeY, ptBuff, ptBuff16, backStep, 
  126.   subImageSize, offset);
  127. findMinimumCorrelation_mmx(ptBuff-backStep, i+k, sdata->imDepth8u+offset-backStep, 
  128.  sb->corrScore+offset-backStep, 
  129. sb->corrScoreSec+offset-backStep,
  130. subImageSize);
  131. ptBuff+=sb->buffStep; ptBuff16+=sb->buffStep;
  132. }
  133. }
  134. // check that there are enough diff. between best and second disp
  135. compareBestAndSecond(sb->corrScore+offset-backStep, sb->corrScoreSec+offset-backStep, minDiff, 
  136.   sdata->UNDEFINED_DEPTH, sdata->imDepth8u+offset-backStep, subImageSize);
  137. }
  138. }
  139. void StereoMatching::estimateStereo_sse2(const uchar* iml8_bw, 
  140. const uchar* imr8_bw,
  141. const uchar* imtop8_bw,
  142. int width, int height, int maskSizeX, int maskSizeY, 
  143. char minDiff, int nbDepth, int nbPartitions,
  144. StereoBuffer* sb, StereoImage* sdata)
  145. {
  146. // assure good partitioning (.....)
  147. while (height/nbPartitions - 2*(maskSizeY/2) <=0)
  148. {
  149. nbPartitions /= 2;
  150. }
  151. int i,j;
  152. int subImageSize=width*height/nbPartitions;
  153. int backStep = (maskSizeY/2)*width;
  154. int buffStep16 = sb->buffStep;
  155. uchar* ptBuff;
  156. ushort* ptBuff16;
  157. int siz;
  158. // ----------- process the first sub-images -----------
  159. for (i=0; i<nbDepth; i++) 
  160. {
  161. ptBuff = sb->buff[i];
  162. ptBuff16 = sb->buff16[i];
  163. ImgSubandAdd_sse2(imr8_bw , imtop8_bw +i*width , iml8_bw +i ,ptBuff , subImageSize);
  164. siz = __max(0, subImageSize - 2*backStep);
  165. sum_Row_mmx(ptBuff , ptBuff16 , subImageSize,maskSizeX);
  166. avg_Col_sse2(ptBuff16+backStep, ptBuff+backStep, siz, width, maskSizeY);
  167. copySSE(ptBuff16,ptBuff16+subImageSize-2*backStep,2*backStep*sizeof(short));
  168. if (i==0) 
  169. initMinimumCorrelation(ptBuff, 0, sdata->imDepth8u, sb->corrScore, sb->corrScoreSec, subImageSize);
  170. else
  171. findMinimumCorrelation_mmx(ptBuff+backStep, i, sdata->imDepth8u+backStep, 
  172. sb->corrScore+backStep, sb->corrScoreSec+backStep,
  173. subImageSize-backStep);
  174. }
  175. // check that there are enough diff. between best and second disp
  176. compareBestAndSecond(sb->corrScore+backStep, sb->corrScoreSec+backStep, minDiff, 
  177.  sdata->UNDEFINED_DEPTH, sdata->imDepth8u+backStep, subImageSize-backStep);
  178. int offset=subImageSize;
  179. // ----------- process the other ones -----------
  180. for (j=1; j<nbPartitions; ++j, offset+=subImageSize) 
  181. {
  182. for (i=0; i<nbDepth; i++) 
  183. {
  184. ptBuff = sb->buff[i]+offset;
  185. ptBuff16 = sb->buff16[i];
  186. // process and comparison 
  187. ImgSubandAdd_sse2(imr8_bw+offset , imtop8_bw+offset +i*width , iml8_bw+offset +i ,ptBuff , subImageSize); 
  188. // filtering
  189. sum_Row_5_mmx(ptBuff , ptBuff16+2*backStep, subImageSize); //, maskSizeX); 
  190. avg_Col_sse2(ptBuff16+backStep , ptBuff-backStep, subImageSize, width, maskSizeY); 
  191. copySSE(ptBuff16, ptBuff16+subImageSize, 2*backStep*sizeof(short));  
  192. if (i==0)
  193. initMinimumCorrelation(ptBuff-backStep, 0, sdata->imDepth8u+offset-backStep, sb->corrScore+offset-backStep, 
  194. sb->corrScoreSec+offset-backStep, subImageSize);
  195. else
  196. findMinimumCorrelation_mmx(ptBuff-backStep, i, sdata->imDepth8u+offset-backStep, 
  197. sb->corrScore+offset-backStep,  sb->corrScoreSec+offset-backStep,  subImageSize);
  198. }
  199. // check that there are enough diff. between best and second disp
  200. compareBestAndSecond(sb->corrScore+offset-backStep, sb->corrScoreSec+offset-backStep, minDiff, 
  201.   sdata->UNDEFINED_DEPTH, sdata->imDepth8u+offset-backStep, subImageSize);
  202. }
  203. }
  204. void StereoMatching::estimateStereo_Horiz(const uchar* iml8_bw, const uchar* imr8_bw,
  205. int width, int height, int maskSizeX, int maskSizeY, 
  206. char minDiff, int nbDepth, int nbPartitions,
  207. StereoBuffer* sb, StereoImage* sdata)
  208. {
  209. int i,k;
  210. int imageSize=width*height;
  211. int backStep = (maskSizeY/2)*width;
  212. uchar* ptBuff;
  213. ushort* ptBuff16;
  214. int siz = 8*(__max(0, imageSize - 2*backStep)/8);
  215. for (i=0; i<nbDepth; i+=8) {
  216. ptBuff = sb->buff[i];
  217. // compute SAD for (imr8_bw, iml8_bw+i), (imr8_bw, iml8_bw+i+1), ....
  218. // .. (imr8_bw, iml8_bw+i+7) 
  219. ImgSubandAdd_Horiz(imr8_bw, iml8_bw+i, ptBuff, imageSize, sb->buffStep, width);
  220. for (k=0; k<8; ++k) {
  221. ptBuff  = sb->buff[i+k];
  222. ptBuff16 = sb->buff16[i+k];
  223. // apply maskSizeX x maskSizeY average mask
  224. //sum_Row(ptBuff , ptBuff16,         imageSize,maskSizeX);
  225. //avg_Col(ptBuff16 +backStep, ptBuff +backStep, siz,  width, maskSizeY);
  226. sum_Row_mmx(ptBuff , ptBuff16,         imageSize,maskSizeX);
  227. avg_Col_mmx(ptBuff16 +backStep, ptBuff +backStep, siz,  width, maskSizeY);
  228. // translate data
  229. copyMMX(ptBuff16,ptBuff16+siz,2*backStep*sizeof(short));
  230. if (i==0 && k==0) 
  231. initMinimumCorrelation(ptBuff, 0,  sdata->imDepth8u, sb->corrScore,
  232. sb->corrScoreSec, imageSize);
  233. else
  234. /*findMinimumCorrelation(ptBuff+backStep, i+k, 
  235. sdata->imDepth8u+backStep, 
  236. sb->corrScore+backStep, sb->corrScoreSec+backStep,
  237. siz);*/
  238. findMinimumCorrelation_mmx(ptBuff+backStep, i+k, 
  239. sdata->imDepth8u+backStep, 
  240. sb->corrScore+backStep, sb->corrScoreSec+backStep,
  241. siz);
  242. }
  243. }
  244. // check that there are enough diff. between best and second disp
  245. compareBestAndSecond(sb->corrScore+backStep, sb->corrScoreSec+backStep, minDiff, 
  246.  sdata->UNDEFINED_DEPTH, sdata->imDepth8u+backStep, siz);
  247. }
  248. void StereoMatching::estimateStereo_Horiz_mmx(const uchar* iml8_bw, const uchar* imr8_bw,
  249.   int width, int height, int maskSizeX, int maskSizeY, 
  250.   char minDiff, int nbDepth, int nbPartitions,
  251. StereoBuffer* sb, StereoImage* sdata)
  252. {
  253. // assure good partitioning (.....)
  254. while (height/nbPartitions - 2*(maskSizeY/2) <=0)
  255. {
  256. nbPartitions /= 2;
  257. }
  258. int i,j,k;
  259. int subImageSize=width*height/nbPartitions;
  260. int backStep = (maskSizeY/2)*width;
  261. uchar* ptBuff;
  262. ushort* ptBuff16;
  263. int siz = __max(0, subImageSize - 2*backStep);
  264. // ----------- process the first sub-images -----------
  265. for (i=0; i<nbDepth; i+=8) {
  266. ptBuff = sb->buff[i];
  267. // compute SAD for (imr8_bw, iml8_bw+i), (imr8_bw, iml8_bw+i+1), ....
  268. // .. (imr8_bw, iml8_bw+i+7) 
  269. ImgSubandAdd_Horiz(imr8_bw, iml8_bw+i, ptBuff, subImageSize, sb->buffStep, width);
  270. for (k=0; k<8; ++k) {
  271. ptBuff  = sb->buff[i+k];
  272. ptBuff16 = sb->buff16[i+k];
  273. // apply maskSizeX x maskSizeY avergae mask
  274. sum_Row_mmx(ptBuff , ptBuff16,         subImageSize,maskSizeX);
  275. avg_Col_mmx(ptBuff16 +backStep, ptBuff +backStep, siz,  width, maskSizeY);
  276. // translate data
  277. copyMMX(ptBuff16,ptBuff16+subImageSize-2*backStep,2*backStep*sizeof(short));
  278. if (i==0 && k==0) 
  279. initMinimumCorrelation(ptBuff, 0,  sdata->imDepth8u, sb->corrScore,
  280. sb->corrScoreSec, subImageSize);
  281. else
  282. findMinimumCorrelation_mmx(ptBuff+backStep, i+k, 
  283. sdata->imDepth8u+backStep, 
  284. sb->corrScore+backStep, sb->corrScoreSec+backStep,
  285. subImageSize-backStep);
  286. }
  287. }
  288. // check that there are enough diff. between best and second disp
  289. compareBestAndSecond(sb->corrScore+backStep, sb->corrScoreSec+backStep, minDiff, 
  290.  sdata->UNDEFINED_DEPTH, sdata->imDepth8u+backStep, subImageSize-backStep);
  291. int offset=subImageSize;
  292. // ----------- process the other ones -----------
  293. for (j=1; j<nbPartitions; ++j, offset+=subImageSize) {
  294. // process depth i=0
  295. i=0;
  296. ptBuff = sb->buff[0]+offset;
  297. // estimate absolute differences between the stereo images
  298. ImgSubandAdd_Horiz(imr8_bw +offset, iml8_bw +i +offset, ptBuff,
  299.    subImageSize, sb->buffStep, width);
  300. ptBuff16 = sb->buff16[0];
  301. sb->filterSAD(maskSizeX, maskSizeY, ptBuff, ptBuff16, 
  302.   backStep, subImageSize, offset);
  303. initMinimumCorrelation(ptBuff-backStep, 0, sdata->imDepth8u+offset-backStep, 
  304. sb->corrScore+offset-backStep,
  305. sb->corrScoreSec+offset-backStep, subImageSize);
  306. // process and comparison 
  307. for (int k=1; k<=7; ++k) {
  308. ptBuff  +=sb->buffStep; 
  309. ptBuff16+=sb->buffStep;
  310.     sb->filterSAD(maskSizeX, maskSizeY, ptBuff, ptBuff16, 
  311.   backStep, subImageSize, offset);
  312. findMinimumCorrelation_mmx(ptBuff-backStep, i+k,   sdata->imDepth8u+offset-backStep, 
  313.    sb->corrScore+offset-backStep,  sb->corrScoreSec+offset-backStep,
  314.    subImageSize);
  315. }
  316. for (i=8; i<nbDepth; i+=8) {
  317. ptBuff = sb->buff[i]+offset;
  318. // estimate absolute differences between the 3 stereo images
  319. ImgSubandAdd_Horiz(imr8_bw +offset, iml8_bw + i +offset, ptBuff,
  320. subImageSize, sb->buffStep, width);
  321. ptBuff16 = sb->buff16[i];
  322. // process and comparison 
  323. for (int k=0; k<=7; ++k) {
  324. ptBuff  +=sb->buffStep; 
  325. ptBuff16+=sb->buffStep;
  326. sb->filterSAD(maskSizeX, maskSizeY, ptBuff, ptBuff16, 
  327.  backStep, subImageSize, offset);
  328. findMinimumCorrelation_mmx(ptBuff-backStep, i+k, sdata->imDepth8u+offset-backStep, 
  329.    sb->corrScore+offset-backStep, 
  330.    sb->corrScoreSec+offset-backStep,
  331.    subImageSize);
  332. }
  333. }
  334. // check that there are enough diff. between best and second disp
  335. compareBestAndSecond(sb->corrScore+offset-backStep, 
  336.  sb->corrScoreSec+offset-backStep, minDiff, 
  337.   sdata->UNDEFINED_DEPTH, 
  338.   sdata->imDepth8u+offset-backStep, subImageSize);
  339. }
  340. }