mexopencv  3.4.1
MEX interface for OpenCV library
Stitcher_.cpp
Go to the documentation of this file.
1 
8 #include "mexopencv.hpp"
10 #include "opencv2/stitching.hpp"
11 using namespace std;
12 using namespace cv;
13 using namespace cv::detail;
14 
15 // Persistent objects
16 namespace {
18 int last_id = 0;
21 
24  ("Orig", cv::Stitcher::ORIG_RESOL);
25 
28  ("Panorama", cv::Stitcher::PANORAMA)
29  ("Scans", cv::Stitcher::SCANS);
30 }
31 
39 void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
40 {
41  // Check the number of arguments
42  nargchk(nrhs>=2 && nlhs<=2);
43 
44  // Argument vector
45  vector<MxArray> rhs(prhs, prhs+nrhs);
46  int id = rhs[0].toInt();
47  string method(rhs[1].toString());
48 
49  // Constructor is called. Create a new object from argument
50  if (method == "new") {
51  nargchk(nrhs>=2 && (nrhs%2)==0 && nlhs<=1);
53  bool try_use_gpu = false;
54  for (int i=2; i<nrhs; i+=2) {
55  string key(rhs[i].toString());
56  if (key == "Mode")
57  mode = ModesMap[rhs[i+1].toString()];
58  else if (key == "TryUseGPU")
59  try_use_gpu = rhs[i+1].toBool();
60  else
61  mexErrMsgIdAndTxt("mexopencv:error",
62  "Unrecognized option %s", key.c_str());
63  }
64  obj_[++last_id] = Stitcher::create(mode, try_use_gpu);
65  plhs[0] = MxArray(last_id);
66  mexLock();
67  return;
68  }
69 
70  // Big operation switch
71  Ptr<Stitcher> obj = obj_[id];
72  if (obj.empty())
73  mexErrMsgIdAndTxt("mexopencv:error", "Object not found id=%d", id);
74  if (method == "delete") {
75  nargchk(nrhs==2 && nlhs==0);
76  obj_.erase(id);
77  mexUnlock();
78  }
79  else if (method == "stitch") {
80  nargchk((nrhs==3 || nrhs==4) && nlhs<=2);
81  vector<Mat> images(rhs[2].toVector<Mat>());
82  Mat pano;
83  Stitcher::Status status;
84  if (nrhs == 4) {
85  //vector<vector<Rect> > rois(rhs[3].toVector<vector<Rect>>());
86  vector<vector<Rect> > rois(rhs[3].toVector(
87  const_mem_fun_ref_t<vector<Rect>, MxArray>(
88  &MxArray::toVector<Rect>)));
89  status = obj->stitch(images, rois, pano);
90  }
91  else
92  status = obj->stitch(images, pano);
93  if (nlhs > 1)
94  plhs[1] = MxArray(StitcherStatusInvMap[status]);
95  else if (status != cv::Stitcher::OK)
96  mexErrMsgIdAndTxt("mexopencv:error",
97  "Stitcher error: %s", StitcherStatusInvMap[status].c_str());
98  plhs[0] = MxArray(pano);
99  }
100  else if (method == "estimateTransform") {
101  nargchk((nrhs==3 || nrhs==4) && nlhs<=1);
102  vector<Mat> images(rhs[2].toVector<Mat>());
103  Mat pano;
104  Stitcher::Status status;
105  if (nrhs == 4) {
106  //vector<vector<Rect> > rois(rhs[3].toVector<vector<Rect>>());
107  vector<vector<Rect> > rois(rhs[3].toVector(
108  const_mem_fun_ref_t<vector<Rect>, MxArray>(
109  &MxArray::toVector<Rect>)));
110  status = obj->estimateTransform(images, rois);
111  }
112  else
113  status = obj->estimateTransform(images);
114  if (nlhs > 0)
115  plhs[0] = MxArray(StitcherStatusInvMap[status]);
116  else if (status != cv::Stitcher::OK)
117  mexErrMsgIdAndTxt("mexopencv:error",
118  "Stitcher error: %s", StitcherStatusInvMap[status].c_str());
119  }
120  else if (method == "composePanorama") {
121  nargchk((nrhs==2 || nrhs==3) && nlhs<=2);
122  Mat pano;
123  Stitcher::Status status;
124  if (nrhs == 3) {
125  vector<Mat> images(rhs[2].toVector<Mat>());
126  status = obj->composePanorama(images, pano);
127  }
128  else
129  status = obj->composePanorama(pano);
130  if (nlhs > 1)
131  plhs[1] = MxArray(StitcherStatusInvMap[status]);
132  else if (status != cv::Stitcher::OK)
133  mexErrMsgIdAndTxt("mexopencv:error",
134  "Stitcher error: %s", StitcherStatusInvMap[status].c_str());
135  plhs[0] = MxArray(pano);
136  }
137  else if (method == "setFeaturesFinder") {
138  nargchk(nrhs>=3 && nlhs==0);
140  rhs[2].toString(), rhs.begin() + 3, rhs.end());
141  obj->setFeaturesFinder(p);
142  }
143  else if (method == "setFeaturesMatcher") {
144  nargchk(nrhs>=3 && nlhs==0);
146  rhs[2].toString(), rhs.begin() + 3, rhs.end());
147  obj->setFeaturesMatcher(p);
148  }
149  /*
150  else if (method == "setEstimator") {
151  nargchk(nrhs>=3 && nlhs==0);
152  Ptr<Estimator> p = createEstimator(
153  rhs[2].toString(), rhs.begin() + 3, rhs.end());
154  obj->setEstimator(p);
155  }
156  */
157  else if (method == "setBundleAdjuster") {
158  nargchk(nrhs>=3 && nlhs==0);
160  rhs[2].toString(), rhs.begin() + 3, rhs.end());
161  obj->setBundleAdjuster(p);
162  }
163  else if (method == "setWarper") {
164  nargchk(nrhs>=3 && nlhs==0);
166  rhs[2].toString(), rhs.begin() + 3, rhs.end());
167  obj->setWarper(p);
168  }
169  else if (method == "setExposureCompensator") {
170  nargchk(nrhs>=3 && nlhs==0);
172  rhs[2].toString(), rhs.begin() + 3, rhs.end());
173  obj->setExposureCompensator(p);
174  }
175  else if (method == "setSeamFinder") {
176  nargchk(nrhs>=3 && nlhs==0);
178  rhs[2].toString(), rhs.begin() + 3, rhs.end());
179  obj->setSeamFinder(p);
180  }
181  else if (method == "setBlender") {
182  nargchk(nrhs>=3 && nlhs==0);
184  rhs[2].toString(), rhs.begin() + 3, rhs.end());
185  obj->setBlender(p);
186  }
187  else if (method == "getFeaturesFinder") {
188  nargchk(nrhs==2 && nlhs<=1);
189  const Ptr<FeaturesFinder> p = obj->featuresFinder();
190  plhs[0] = toStruct(p);
191  }
192  else if (method == "getFeaturesMatcher") {
193  nargchk(nrhs==2 && nlhs<=1);
194  const Ptr<FeaturesMatcher> p = obj->featuresMatcher();
195  plhs[0] = toStruct(p);
196  }
197  /*
198  else if (method == "getEstimator") {
199  nargchk(nrhs==2 && nlhs<=1);
200  const Ptr<Estimator> p = obj->estimator();
201  plhs[0] = toStruct(p);
202  }
203  */
204  else if (method == "getBundleAdjuster") {
205  nargchk(nrhs==2 && nlhs<=1);
206  const Ptr<BundleAdjusterBase> p = obj->bundleAdjuster();
207  plhs[0] = toStruct(p);
208  }
209  else if (method == "getWarper") {
210  nargchk(nrhs==2 && nlhs<=1);
211  const Ptr<WarperCreator> p = obj->warper();
212  plhs[0] = toStruct(p);
213  }
214  else if (method == "getExposureCompensator") {
215  nargchk(nrhs==2 && nlhs<=1);
217  plhs[0] = toStruct(p);
218  }
219  else if (method == "getSeamFinder") {
220  nargchk(nrhs==2 && nlhs<=1);
221  const Ptr<SeamFinder> p = obj->seamFinder();
222  plhs[0] = toStruct(p);
223  }
224  else if (method == "getBlender") {
225  nargchk(nrhs==2 && nlhs<=1);
226  const Ptr<Blender> p = obj->blender();
227  plhs[0] = toStruct(p);
228  }
229  else if (method == "component") {
230  nargchk(nrhs==2 && nlhs<=1);
231  vector<int> indices(obj->component());
232  plhs[0] = MxArray(indices);
233  }
234  else if (method == "cameras") {
235  nargchk(nrhs==2 && nlhs<=1);
236  vector<CameraParams> params(obj->cameras());
237  plhs[0] = toStruct(params);
238  }
239  else if (method == "workScale") {
240  nargchk(nrhs==2 && nlhs<=1);
241  double wscale = obj->workScale();
242  plhs[0] = MxArray(wscale);
243  }
244  else if (method == "getMatchingMask") {
245  nargchk(nrhs==2 && nlhs<=1);
246  Mat mask(obj->matchingMask().getMat(ACCESS_READ));
247  plhs[0] = MxArray(mask);
248  }
249  else if (method == "setMatchingMask") {
250  nargchk(nrhs==3 && nlhs==0);
251  Mat mask(rhs[2].toMat(CV_8U));
252  obj->setMatchingMask(mask.getUMat(ACCESS_READ));
253  }
254  else if (method == "get") {
255  nargchk(nrhs==3 && nlhs<=1);
256  string prop(rhs[2].toString());
257  if (prop == "RegistrationResol")
258  plhs[0] = MxArray(obj->registrationResol());
259  else if (prop == "SeamEstimationResol")
260  plhs[0] = MxArray(obj->seamEstimationResol());
261  else if (prop == "CompositingResol")
262  plhs[0] = MxArray(obj->compositingResol());
263  else if (prop == "PanoConfidenceThresh")
264  plhs[0] = MxArray(obj->panoConfidenceThresh());
265  else if (prop == "WaveCorrection")
266  plhs[0] = MxArray(obj->waveCorrection());
267  else if (prop == "WaveCorrectKind")
268  plhs[0] = MxArray(WaveCorrectionInvMap[obj->waveCorrectKind()]);
269  else
270  mexErrMsgIdAndTxt("mexopencv:error",
271  "Unrecognized property %s", prop.c_str());
272  }
273  else if (method == "set") {
274  nargchk(nrhs==4 && nlhs==0);
275  string prop(rhs[2].toString());
276  if (prop == "RegistrationResol")
277  obj->setRegistrationResol(rhs[3].toDouble());
278  else if (prop == "SeamEstimationResol")
279  obj->setSeamEstimationResol(rhs[3].toDouble());
280  else if (prop == "CompositingResol")
281  obj->setCompositingResol(rhs[3].isChar() ?
282  ComposeResolMap[rhs[3].toString()] : rhs[3].toDouble());
283  else if (prop == "PanoConfidenceThresh")
284  obj->setPanoConfidenceThresh(rhs[3].toDouble());
285  else if (prop == "WaveCorrection")
286  obj->setWaveCorrection(rhs[3].toBool());
287  else if (prop == "WaveCorrectKind")
288  obj->setWaveCorrectKind(WaveCorrectionMap[rhs[3].toString()]);
289  else
290  mexErrMsgIdAndTxt("mexopencv:error",
291  "Unrecognized property %s", prop.c_str());
292  }
293  else
294  mexErrMsgIdAndTxt("mexopencv:error",
295  "Unrecognized operation %s", method.c_str());
296 }
cv::Ptr< cv::detail::FeaturesFinder > createFeaturesFinder(const std::string &type, std::vector< MxArray >::const_iterator first, std::vector< MxArray >::const_iterator last)
Create an instance of FeaturesFinder using options in arguments.
void setPanoConfidenceThresh(double conf_thresh)
const ConstMap< cv::detail::WaveCorrectKind, std::string > WaveCorrectionInvMap
inverse wave correction kinds
void setFeaturesFinder(Ptr< detail::FeaturesFinder > features_finder)
Common definitions for the stitching module.
void setWarper(Ptr< WarperCreator > creator)
LIBMWMEX_API_EXTERN_C void mexLock(void)
Lock a MEX-function so that it cannot be cleared from memory.
void setBlender(Ptr< detail::Blender > b)
cv::Ptr< cv::detail::ExposureCompensator > createExposureCompensator(const std::string &type, std::vector< MxArray >::const_iterator first, std::vector< MxArray >::const_iterator last)
Create an instance of ExposureCompensator using options in arguments.
#define CV_8U
Ptr< detail::Blender > blender()
double registrationResol() const
const ConstMap< string, Stitcher::Mode > ModesMap
stitching mode types
Definition: Stitcher_.cpp:27
Ptr< detail::SeamFinder > seamFinder()
void setSeamEstimationResol(double resol_mpx)
STL namespace.
T end(T... args)
void setSeamFinder(Ptr< detail::SeamFinder > seam_finder)
void setCompositingResol(double resol_mpx)
Status estimateTransform(InputArrayOfArrays images)
struct mxArray_tag mxArray
Forward declaration for mxArray.
Definition: matrix.h:259
void setMatchingMask(const cv::UMat &mask)
STL class.
cv::Ptr< cv::detail::Blender > createBlender(const std::string &type, std::vector< MxArray >::const_iterator first, std::vector< MxArray >::const_iterator last)
Create an instance of Blender using options in arguments.
const ConstMap< string, int > ComposeResolMap
compositing resolution types
Definition: Stitcher_.cpp:23
bool waveCorrection() const
MxArray toStruct(const std::vector< cv::ml::DTrees::Node > &nodes)
Convert tree nodes to struct array.
Mat getMat(int flags) const
Ptr< detail::ExposureCompensator > exposureCompensator()
Ptr< detail::FeaturesFinder > featuresFinder()
cv::Ptr< cv::detail::SeamFinder > createSeamFinder(const std::string &type, std::vector< MxArray >::const_iterator first, std::vector< MxArray >::const_iterator last)
Create an instance of SeamFinder using options in arguments.
std::vector< int > component() const
double workScale() const
void setBundleAdjuster(Ptr< detail::BundleAdjusterBase > bundle_adjuster)
int last_id
Last object id to allocate.
Definition: Stitcher_.cpp:18
LIBMWMEX_API_EXTERN_C void mexErrMsgIdAndTxt(const char *identifier, const char *err_msg,...)
Issue formatted error message with corresponding error identifier and return to MATLAB prompt...
LIBMWMEX_API_EXTERN_C void mexUnlock(void)
Unlock a locked MEX-function so that it can be cleared from memory.
double panoConfidenceThresh() const
mxArray object wrapper for data conversion and manipulation.
Definition: MxArray.hpp:123
Status stitch(InputArrayOfArrays images, OutputArray pano)
void nargchk(bool cond)
Alias for input/output arguments number check.
Definition: mexopencv.hpp:181
void setWaveCorrection(bool flag)
const ConstMap< std::string, cv::detail::WaveCorrectKind > WaveCorrectionMap
wave correction kinds
STL class.
bool empty() const
cv::Ptr< cv::WarperCreator > createWarperCreator(const std::string &type, std::vector< MxArray >::const_iterator first, std::vector< MxArray >::const_iterator last)
Create an instance of WarperCreator using options in arguments.
void setFeaturesMatcher(Ptr< detail::FeaturesMatcher > features_matcher)
Global constant definitions.
T begin(T... args)
ACCESS_READ
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
Main entry called from Matlab.
Definition: Stitcher_.cpp:39
T c_str(T... args)
double compositingResol() const
Status composePanorama(OutputArray pano)
void setExposureCompensator(Ptr< detail::ExposureCompensator > exposure_comp)
Ptr< detail::BundleAdjusterBase > bundleAdjuster()
Ptr< detail::FeaturesMatcher > featuresMatcher()
std::vector< detail::CameraParams > cameras() const
UMat getUMat(int accessFlags, UMatUsageFlags usageFlags=USAGE_DEFAULT) const
const cv::UMat & matchingMask() const
double seamEstimationResol() const
std::map wrapper with one-line initialization and lookup method.
Definition: MxArray.hpp:927
Ptr< WarperCreator > warper()
void setRegistrationResol(double resol_mpx)
cv::Ptr< cv::detail::FeaturesMatcher > createFeaturesMatcher(const std::string &type, std::vector< MxArray >::const_iterator first, std::vector< MxArray >::const_iterator last)
Create an instance of FeaturesMatcher using options in arguments.
detail::WaveCorrectKind waveCorrectKind() const
void create(int arows, int acols, int atype, Target target=ARRAY_BUFFER, bool autoRelease=false)
cv::Mat toMat() const
cv::Ptr< cv::detail::BundleAdjusterBase > createBundleAdjusterBase(const std::string &type, std::vector< MxArray >::const_iterator first, std::vector< MxArray >::const_iterator last)
Create an instance of BundleAdjusterBase using options in arguments.
map< int, Ptr< Stitcher > > obj_
Object container.
Definition: Stitcher_.cpp:20
const ConstMap< cv::Stitcher::Status, std::string > StitcherStatusInvMap
Stitcher error status types.
void setWaveCorrectKind(detail::WaveCorrectKind kind)