/src/+cv/findCirclesGrid.cpp

http://github.com/kyamagu/mexopencv · C++ · 169 lines · 137 code · 6 blank · 26 comment · 83 complexity · b7c85d1dff6b600ebea133212f0ec3e2 MD5 · raw file

  1. /**
  2. * @file findCirclesGrid.cpp
  3. * @brief mex interface for cv::findCirclesGrid
  4. * @ingroup calib3d
  5. * @author Kota Yamaguchi
  6. * @date 2011
  7. */
  8. #include "mexopencv.hpp"
  9. #include "mexopencv_features2d.hpp" // createFeatureDetector
  10. #include "opencv2/calib3d.hpp"
  11. using namespace std;
  12. using namespace cv;
  13. namespace {
  14. /// grid types for option processing
  15. const ConstMap<string,cv::CirclesGridFinderParameters::GridType> GridTypesMap =
  16. ConstMap<string,cv::CirclesGridFinderParameters::GridType>
  17. ("Symmetric", cv::CirclesGridFinderParameters::SYMMETRIC_GRID)
  18. ("Asymmetric", cv::CirclesGridFinderParameters::ASYMMETRIC_GRID);
  19. /** Convert MxArray to cv::CirclesGridFinderParameters2
  20. * @param arr MxArray object. In one of the following forms:
  21. * - a scalar struct
  22. * - a cell-array of the form: <tt>{GridType, ...}</tt> starting with the grid
  23. * type ("Symmetric" or "Asymmetric") followed by pairs of key-value options
  24. * @return instance of CirclesGridFinderParameters2 object
  25. */
  26. CirclesGridFinderParameters2 MxArrayToFinderParameters(const MxArray &arr)
  27. {
  28. CirclesGridFinderParameters2 params;
  29. if (arr.isStruct()) {
  30. params.gridType = GridTypesMap[arr.at("gridType").toString()];
  31. if (arr.isField("densityNeighborhoodSize"))
  32. params.densityNeighborhoodSize = arr.at("densityNeighborhoodSize").toSize_<float>();
  33. if (arr.isField("minDensity"))
  34. params.minDensity = arr.at("minDensity").toFloat();
  35. if (arr.isField("kmeansAttempts"))
  36. params.kmeansAttempts = arr.at("kmeansAttempts").toInt();
  37. if (arr.isField("minDistanceToAddKeypoint"))
  38. params.minDistanceToAddKeypoint = arr.at("minDistanceToAddKeypoint").toInt();
  39. if (arr.isField("keypointScale"))
  40. params.keypointScale = arr.at("keypointScale").toInt();
  41. if (arr.isField("minGraphConfidence"))
  42. params.minGraphConfidence = arr.at("minGraphConfidence").toFloat();
  43. if (arr.isField("vertexGain"))
  44. params.vertexGain = arr.at("vertexGain").toFloat();
  45. if (arr.isField("vertexPenalty"))
  46. params.vertexPenalty = arr.at("vertexPenalty").toFloat();
  47. if (arr.isField("existingVertexGain"))
  48. params.existingVertexGain = arr.at("existingVertexGain").toFloat();
  49. if (arr.isField("edgeGain"))
  50. params.edgeGain = arr.at("edgeGain").toFloat();
  51. if (arr.isField("edgePenalty"))
  52. params.edgePenalty = arr.at("edgePenalty").toFloat();
  53. if (arr.isField("convexHullFactor"))
  54. params.convexHullFactor = arr.at("convexHullFactor").toFloat();
  55. if (arr.isField("minRNGEdgeSwitchDist"))
  56. params.minRNGEdgeSwitchDist = arr.at("minRNGEdgeSwitchDist").toFloat();
  57. if (arr.isField("squareSize"))
  58. params.squareSize = arr.at("squareSize").toFloat();
  59. if (arr.isField("maxRectifiedDistance"))
  60. params.maxRectifiedDistance = arr.at("maxRectifiedDistance").toFloat();
  61. }
  62. else {
  63. vector<MxArray> args(arr.toVector<MxArray>());
  64. nargchk(args.size() >= 1 && (args.size()%2)==1);
  65. params.gridType = GridTypesMap[args[0].toString()];
  66. for (size_t i = 1; i < args.size(); i+=2) {
  67. string key(args[i].toString());
  68. if (key == "DensityNeighborhoodSize")
  69. params.densityNeighborhoodSize = args[i+1].toSize_<float>();
  70. else if (key == "MinDensity")
  71. params.minDensity = args[i+1].toFloat();
  72. else if (key == "KmeansAttempts")
  73. params.kmeansAttempts = args[i+1].toInt();
  74. else if (key == "MinDistanceToAddKeypoint")
  75. params.minDistanceToAddKeypoint = args[i+1].toInt();
  76. else if (key == "KeypointScale")
  77. params.keypointScale = args[i+1].toInt();
  78. else if (key == "MinGraphConfidence")
  79. params.minGraphConfidence = args[i+1].toFloat();
  80. else if (key == "VertexGain")
  81. params.vertexGain = args[i+1].toFloat();
  82. else if (key == "VertexPenalty")
  83. params.vertexPenalty = args[i+1].toFloat();
  84. else if (key == "ExistingVertexGain")
  85. params.existingVertexGain = args[i+1].toFloat();
  86. else if (key == "EdgeGain")
  87. params.edgeGain = args[i+1].toFloat();
  88. else if (key == "EdgePenalty")
  89. params.edgePenalty = args[i+1].toFloat();
  90. else if (key == "ConvexHullFactor")
  91. params.convexHullFactor = args[i+1].toFloat();
  92. else if (key == "MinRNGEdgeSwitchDist")
  93. params.minRNGEdgeSwitchDist = args[i+1].toFloat();
  94. else if (key == "SquareSize")
  95. params.squareSize = args[i+1].toFloat();
  96. else if (key == "MaxRectifiedDistance")
  97. params.maxRectifiedDistance = args[i+1].toFloat();
  98. else
  99. mexErrMsgIdAndTxt("mexopencv:error",
  100. "Unrecognized CirclesGridFinderParameters2 option %s", key.c_str());
  101. }
  102. }
  103. return params;
  104. }
  105. }
  106. /**
  107. * Main entry called from Matlab
  108. * @param nlhs number of left-hand-side arguments
  109. * @param plhs pointers to mxArrays in the left-hand-side
  110. * @param nrhs number of right-hand-side arguments
  111. * @param prhs pointers to mxArrays in the right-hand-side
  112. */
  113. void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
  114. {
  115. // Check the number of arguments
  116. nargchk(nrhs>=2 && (nrhs%2)==0 && nlhs<=2);
  117. // Argument vector
  118. vector<MxArray> rhs(prhs, prhs+nrhs);
  119. // Option processing
  120. bool symmetricGrid = true;
  121. bool clustering = false;
  122. Ptr<FeatureDetector> blobDetector;
  123. CirclesGridFinderParameters2 params;
  124. for (int i=2; i<nrhs; i+=2) {
  125. string key(rhs[i].toString());
  126. if (key == "SymmetricGrid")
  127. symmetricGrid = rhs[i+1].toBool();
  128. else if (key == "Clustering")
  129. clustering = rhs[i+1].toBool();
  130. else if (key == "BlobDetector") {
  131. if (rhs[i+1].isChar())
  132. blobDetector = createFeatureDetector(rhs[i+1].toString(),
  133. rhs.end(), rhs.end());
  134. else if (rhs[i+1].isCell() && rhs[i+1].numel() >= 2) {
  135. vector<MxArray> args(rhs[i+1].toVector<MxArray>());
  136. blobDetector = createFeatureDetector(args[0].toString(),
  137. args.begin() + 1, args.end());
  138. }
  139. else
  140. mexErrMsgIdAndTxt("mexopencv:error",
  141. "Invalid detector arguments");
  142. }
  143. else if (key == "FinderParameters")
  144. params = MxArrayToFinderParameters(rhs[i+1]);
  145. else
  146. mexErrMsgIdAndTxt("mexopencv:error",
  147. "Unrecognized option %s", key.c_str());
  148. }
  149. int flags = (symmetricGrid ? cv::CALIB_CB_SYMMETRIC_GRID :
  150. cv::CALIB_CB_ASYMMETRIC_GRID) |
  151. (clustering ? cv::CALIB_CB_CLUSTERING : 0);
  152. if (blobDetector.empty())
  153. blobDetector = SimpleBlobDetector::create();
  154. // Process
  155. Mat image(rhs[0].toMat(CV_8U));
  156. Size patternSize(rhs[1].toSize());
  157. vector<Point2f> centers;
  158. bool patternFound = findCirclesGrid2(image, patternSize, centers, flags,
  159. blobDetector, params);
  160. plhs[0] = MxArray(centers);
  161. if (nlhs > 1)
  162. plhs[1] = MxArray(patternFound);
  163. }