capsinpattern.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. /*M///////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
  4. //
  5. // By downloading, copying, installing or using the software you agree to this license.
  6. // If you do not agree to this license, do not download, install,
  7. // copy or use the software.
  8. //
  9. //
  10. // License Agreement
  11. // For Open Source Computer Vision Library
  12. //
  13. // Copyright (C) 2015, OpenCV Foundation, all rights reserved.
  14. // Third party copyrights are property of their respective owners.
  15. //
  16. // Redistribution and use in source and binary forms, with or without modification,
  17. // are permitted provided that the following conditions are met:
  18. //
  19. // * Redistribution's of source code must retain the above copyright notice,
  20. // this list of conditions and the following disclaimer.
  21. //
  22. // * Redistribution's in binary form must reproduce the above copyright notice,
  23. // this list of conditions and the following disclaimer in the documentation
  24. // and/or other materials provided with the distribution.
  25. //
  26. // * The name of the copyright holders may not be used to endorse or promote products
  27. // derived from this software without specific prior written permission.
  28. //
  29. // This software is provided by the copyright holders and contributors "as is" and
  30. // any express or implied warranties, including, but not limited to, the implied
  31. // warranties of merchantability and fitness for a particular purpose are disclaimed.
  32. // In no event shall the Intel Corporation or contributors be liable for any direct,
  33. // indirect, incidental, special, exemplary, or consequential damages
  34. // (including, but not limited to, procurement of substitute goods or services;
  35. // loss of use, data, or profits; or business interruption) however caused
  36. // and on any theory of liability, whether in contract, strict liability,
  37. // or tort (including negligence or otherwise) arising in any way out of
  38. // the use of this software, even if advised of the possibility of such damage.
  39. //
  40. //M*/
  41. #include <opencv2/highgui.hpp>
  42. #include <vector>
  43. #include <iostream>
  44. #include <fstream>
  45. #include <opencv2/core.hpp>
  46. #include <opencv2/core/utility.hpp>
  47. #include <opencv2/imgproc.hpp>
  48. #include <opencv2/calib3d.hpp>
  49. #include <opencv2/structured_light.hpp>
  50. #include <opencv2/phase_unwrapping.hpp>
  51. using namespace cv;
  52. using namespace std;
  53. static const char* keys =
  54. {
  55. "{@width | | Projector width}"
  56. "{@height | | Projector height}"
  57. "{@periods | | Number of periods}"
  58. "{@setMarkers | | Patterns with or without markers}"
  59. "{@horizontal | | Patterns are horizontal}"
  60. "{@methodId | | Method to be used}"
  61. "{@outputPatternPath | | Path to save patterns}"
  62. "{@outputWrappedPhasePath | | Path to save wrapped phase map}"
  63. "{@outputUnwrappedPhasePath | | Path to save unwrapped phase map}"
  64. "{@outputCapturePath | | Path to save the captures}"
  65. "{@reliabilitiesPath | | Path to save reliabilities}"
  66. };
  67. static void help()
  68. {
  69. cout << "\nThis example generates sinusoidal patterns" << endl;
  70. cout << "To call: ./example_structured_light_createsinuspattern <width> <height>"
  71. " <number_of_period> <set_marker>(bool) <horizontal_patterns>(bool) <method_id>"
  72. " <output_captures_path> <output_pattern_path>(optional) <output_wrapped_phase_path> (optional)"
  73. " <output_unwrapped_phase_path>" << endl;
  74. }
  75. int main(int argc, char **argv)
  76. {
  77. if( argc < 2 )
  78. {
  79. help();
  80. return -1;
  81. }
  82. structured_light::SinusoidalPattern::Params params;
  83. phase_unwrapping::HistogramPhaseUnwrapping::Params paramsUnwrapping;
  84. // Retrieve parameters written in the command line
  85. CommandLineParser parser(argc, argv, keys);
  86. params.width = parser.get<int>(0);
  87. params.height = parser.get<int>(1);
  88. params.nbrOfPeriods = parser.get<int>(2);
  89. params.setMarkers = parser.get<bool>(3);
  90. params.horizontal = parser.get<bool>(4);
  91. params.methodId = parser.get<int>(5);
  92. String outputCapturePath = parser.get<String>(6);
  93. params.shiftValue = static_cast<float>(2 * CV_PI / 3);
  94. params.nbrOfPixelsBetweenMarkers = 70;
  95. String outputPatternPath = parser.get<String>(7);
  96. String outputWrappedPhasePath = parser.get<String>(8);
  97. String outputUnwrappedPhasePath = parser.get<String>(9);
  98. String reliabilitiesPath = parser.get<String>(10);
  99. Ptr<structured_light::SinusoidalPattern> sinus =
  100. structured_light::SinusoidalPattern::create(makePtr<structured_light::SinusoidalPattern::Params>(params));
  101. Ptr<phase_unwrapping::HistogramPhaseUnwrapping> phaseUnwrapping;
  102. vector<Mat> patterns;
  103. Mat shadowMask;
  104. Mat unwrappedPhaseMap, unwrappedPhaseMap8;
  105. Mat wrappedPhaseMap, wrappedPhaseMap8;
  106. //Generate sinusoidal patterns
  107. sinus->generate(patterns);
  108. VideoCapture cap(CAP_PVAPI);
  109. if( !cap.isOpened() )
  110. {
  111. cout << "Camera could not be opened" << endl;
  112. return -1;
  113. }
  114. cap.set(CAP_PROP_PVAPI_PIXELFORMAT, CAP_PVAPI_PIXELFORMAT_MONO8);
  115. namedWindow("pattern", WINDOW_NORMAL);
  116. setWindowProperty("pattern", WND_PROP_FULLSCREEN, WINDOW_FULLSCREEN);
  117. imshow("pattern", patterns[0]);
  118. cout << "Press any key when ready" << endl;
  119. waitKey(0);
  120. int nbrOfImages = 30;
  121. int count = 0;
  122. vector<Mat> img(nbrOfImages);
  123. Size camSize(-1, -1);
  124. while( count < nbrOfImages )
  125. {
  126. for(int i = 0; i < (int)patterns.size(); ++i )
  127. {
  128. imshow("pattern", patterns[i]);
  129. waitKey(300);
  130. cap >> img[count];
  131. count += 1;
  132. }
  133. }
  134. cout << "press enter when ready" << endl;
  135. bool loop = true;
  136. while ( loop )
  137. {
  138. char c = (char) waitKey(0);
  139. if( c == 10 )
  140. {
  141. loop = false;
  142. }
  143. }
  144. switch(params.methodId)
  145. {
  146. case structured_light::FTP:
  147. for( int i = 0; i < nbrOfImages; ++i )
  148. {
  149. /*We need three images to compute the shadow mask, as described in the reference paper
  150. * even if the phase map is computed from one pattern only
  151. */
  152. vector<Mat> captures;
  153. if( i == nbrOfImages - 2 )
  154. {
  155. captures.push_back(img[i]);
  156. captures.push_back(img[i-1]);
  157. captures.push_back(img[i+1]);
  158. }
  159. else if( i == nbrOfImages - 1 )
  160. {
  161. captures.push_back(img[i]);
  162. captures.push_back(img[i-1]);
  163. captures.push_back(img[i-2]);
  164. }
  165. else
  166. {
  167. captures.push_back(img[i]);
  168. captures.push_back(img[i+1]);
  169. captures.push_back(img[i+2]);
  170. }
  171. sinus->computePhaseMap(captures, wrappedPhaseMap, shadowMask);
  172. if( camSize.height == -1 )
  173. {
  174. camSize.height = img[i].rows;
  175. camSize.width = img[i].cols;
  176. paramsUnwrapping.height = camSize.height;
  177. paramsUnwrapping.width = camSize.width;
  178. phaseUnwrapping =
  179. phase_unwrapping::HistogramPhaseUnwrapping::create(paramsUnwrapping);
  180. }
  181. sinus->unwrapPhaseMap(wrappedPhaseMap, unwrappedPhaseMap, camSize, shadowMask);
  182. phaseUnwrapping->unwrapPhaseMap(wrappedPhaseMap, unwrappedPhaseMap, shadowMask);
  183. Mat reliabilities, reliabilities8;
  184. phaseUnwrapping->getInverseReliabilityMap(reliabilities);
  185. reliabilities.convertTo(reliabilities8, CV_8U, 255,128);
  186. ostringstream tt;
  187. tt << i;
  188. imwrite(reliabilitiesPath + tt.str() + ".png", reliabilities8);
  189. unwrappedPhaseMap.convertTo(unwrappedPhaseMap8, CV_8U, 1, 128);
  190. wrappedPhaseMap.convertTo(wrappedPhaseMap8, CV_8U, 255, 128);
  191. if( !outputUnwrappedPhasePath.empty() )
  192. {
  193. ostringstream name;
  194. name << i;
  195. imwrite(outputUnwrappedPhasePath + "_FTP_" + name.str() + ".png", unwrappedPhaseMap8);
  196. }
  197. if( !outputWrappedPhasePath.empty() )
  198. {
  199. ostringstream name;
  200. name << i;
  201. imwrite(outputWrappedPhasePath + "_FTP_" + name.str() + ".png", wrappedPhaseMap8);
  202. }
  203. }
  204. break;
  205. case structured_light::PSP:
  206. case structured_light::FAPS:
  207. for( int i = 0; i < nbrOfImages - 2; ++i )
  208. {
  209. vector<Mat> captures;
  210. captures.push_back(img[i]);
  211. captures.push_back(img[i+1]);
  212. captures.push_back(img[i+2]);
  213. sinus->computePhaseMap(captures, wrappedPhaseMap, shadowMask);
  214. if( camSize.height == -1 )
  215. {
  216. camSize.height = img[i].rows;
  217. camSize.width = img[i].cols;
  218. paramsUnwrapping.height = camSize.height;
  219. paramsUnwrapping.width = camSize.width;
  220. phaseUnwrapping =
  221. phase_unwrapping::HistogramPhaseUnwrapping::create(paramsUnwrapping);
  222. }
  223. sinus->unwrapPhaseMap(wrappedPhaseMap, unwrappedPhaseMap, camSize, shadowMask);
  224. unwrappedPhaseMap.convertTo(unwrappedPhaseMap8, CV_8U, 1, 128);
  225. wrappedPhaseMap.convertTo(wrappedPhaseMap8, CV_8U, 255, 128);
  226. phaseUnwrapping->unwrapPhaseMap(wrappedPhaseMap, unwrappedPhaseMap, shadowMask);
  227. Mat reliabilities, reliabilities8;
  228. phaseUnwrapping->getInverseReliabilityMap(reliabilities);
  229. reliabilities.convertTo(reliabilities8, CV_8U, 255,128);
  230. ostringstream tt;
  231. tt << i;
  232. imwrite(reliabilitiesPath + tt.str() + ".png", reliabilities8);
  233. if( !outputUnwrappedPhasePath.empty() )
  234. {
  235. ostringstream name;
  236. name << i;
  237. if( params.methodId == structured_light::PSP )
  238. imwrite(outputUnwrappedPhasePath + "_PSP_" + name.str() + ".png", unwrappedPhaseMap8);
  239. else
  240. imwrite(outputUnwrappedPhasePath + "_FAPS_" + name.str() + ".png", unwrappedPhaseMap8);
  241. }
  242. if( !outputWrappedPhasePath.empty() )
  243. {
  244. ostringstream name;
  245. name << i;
  246. if( params.methodId == structured_light::PSP )
  247. imwrite(outputWrappedPhasePath + "_PSP_" + name.str() + ".png", wrappedPhaseMap8);
  248. else
  249. imwrite(outputWrappedPhasePath + "_FAPS_" + name.str() + ".png", wrappedPhaseMap8);
  250. }
  251. if( !outputCapturePath.empty() )
  252. {
  253. ostringstream name;
  254. name << i;
  255. if( params.methodId == structured_light::PSP )
  256. imwrite(outputCapturePath + "_PSP_" + name.str() + ".png", img[i]);
  257. else
  258. imwrite(outputCapturePath + "_FAPS_" + name.str() + ".png", img[i]);
  259. if( i == nbrOfImages - 3 )
  260. {
  261. if( params.methodId == structured_light::PSP )
  262. {
  263. ostringstream nameBis;
  264. nameBis << i+1;
  265. ostringstream nameTer;
  266. nameTer << i+2;
  267. imwrite(outputCapturePath + "_PSP_" + nameBis.str() + ".png", img[i+1]);
  268. imwrite(outputCapturePath + "_PSP_" + nameTer.str() + ".png", img[i+2]);
  269. }
  270. else
  271. {
  272. ostringstream nameBis;
  273. nameBis << i+1;
  274. ostringstream nameTer;
  275. nameTer << i+2;
  276. imwrite(outputCapturePath + "_FAPS_" + nameBis.str() + ".png", img[i+1]);
  277. imwrite(outputCapturePath + "_FAPS_" + nameTer.str() + ".png", img[i+2]);
  278. }
  279. }
  280. }
  281. }
  282. break;
  283. default:
  284. cout << "error" << endl;
  285. }
  286. cout << "done" << endl;
  287. if( !outputPatternPath.empty() )
  288. {
  289. for( int i = 0; i < 3; ++ i )
  290. {
  291. ostringstream name;
  292. name << i + 1;
  293. imwrite(outputPatternPath + name.str() + ".png", patterns[i]);
  294. }
  295. }
  296. loop = true;
  297. while( loop )
  298. {
  299. char key = (char) waitKey(0);
  300. if( key == 27 )
  301. {
  302. loop = false;
  303. }
  304. }
  305. return 0;
  306. }