8
#include "normxcorr_hw_msg.h"
11
#define USE_UNDOCUMENTED
12
//#define VALIDATE_LSUM
13
//#define VALIDATE_PEAK
18
ACTION_COMPUTE_BASE_FRAGMENT = 2,
19
#endif /* VALIDAT_LSUM */
20
ACTION_SET_BASE_POINTS = 3,
21
ACTION_COMPUTE_BASE = 4,
23
ACTION_COMPUTE_FRAGMENT = 11,
24
ACTION_GET_CORRECTIONS = 15,
25
#endif /* VALIDATE_PEAK */
26
ACTION_SET_POINTS = 12,
28
ACTION_GET_POINTS = 14,
32
static DICTContext pstate = NULL;
33
static mxArray *coords = NULL; // Matlab array with current coordinates
37
#define EXTERN_C extern "C"
39
#define EXTERN_C extern
43
#ifdef USE_UNDOCUMENTED
44
EXTERN_C mxArray *mxCreateSharedDataCopy(const mxArray *pr);
45
#endif /* USE_UNDOCUMENTED */
48
static void selfClean() {
50
reportMessage("cleaning normxcorr_hw instance");
52
dictDestroyContext(pstate);
57
mxDestroyArray(coords);
62
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
69
static int32_t id = 0;
71
static int width, height;
88
#endif /* VALIDATE_LSUM */
93
reportMessage("Initializing normxcorr_hw instance");
96
reportError("You should accept a single result from initialization call");
100
idMatrix = mxCreateNumericMatrix(1, 1, mxINT32_CLASS, mxREAL);
102
reportError("Initialization is failed");
106
dictSetLogger(reportError, reportMessage);
109
dictDestroyContext(pstate);
110
pstate = dictCreateContext();
112
id = dictDetectHardware();
114
pstate = dictCreateContext();
119
mexAtExit(selfClean);
121
reportError("Context initialization has failed");
125
idPtr = (int32_t*)mxGetData(idMatrix);
132
reportError("normxcorr_hw should be initialized first");
145
action = (TAction)int(mxGetScalar((mxArray*)prhs[1]));
147
// reportMessage("Executing normxcorr_hw action: %u", action);
152
reportError("Compute action expects 1 argument, but %i is passed", nrhs - 2);
158
if (mxGetNumberOfDimensions(input) != 2) {
159
reportError("Invalid dimensionality of base matrix, 2D matrix is expected");
163
if (mxGetClassID(input) != mxUINT8_CLASS) {
164
reportError("Invalid type of image data, should be 8bit integers");
168
if ((mxGetN(input) != width)||(mxGetM(input) != height)) {
169
reportError("Invalid size of image (%ix%i), but (%ix%i) is expected", mxGetN(input), mxGetM(input), width, height);
173
dictLoadImage(ps, (unsigned char*)mxGetData(input));
175
case ACTION_COMPUTE_BASE:
177
reportError("ComputeBase action expects 1 argument, but %i is passed", nrhs - 2);
183
if (mxGetNumberOfDimensions(base) != 2) {
184
reportError("Invalid dimensionality of base matrix, 2D matrix is expected");
188
if (mxGetClassID(base) != mxUINT8_CLASS) {
189
reportError("Invalid matrix. The data type (%s) is not supported", mxGetClassName(base));
193
width = mxGetN(base);
194
height = mxGetM(base);
196
dictLoadTemplateImage(ps, (unsigned char*)mxGetData(base), width, height);
198
case ACTION_SET_BASE_POINTS:
200
reportError("SET_POINTS action expects two arrays with 'x' and 'y' coordinates of control points");
207
if ( (mxGetClassID(x) != mxSINGLE_CLASS)||
208
(mxGetClassID(y) != mxSINGLE_CLASS)||
209
(mxGetN(x)*mxGetM(x) != ncp)||
210
(mxGetN(y)*mxGetM(y) != ncp)
212
reportError("Invalid control points are specified");
216
dictSetTemplatePoints(ps, (float*)mxGetData(x), (float*)mxGetData(y));
218
case ACTION_SET_POINTS:
220
reportError("SET_POINTS action expects two arrays with 'x' and 'y' coordinates of control points");
227
if ( (mxGetClassID(x) != mxSINGLE_CLASS)||
228
(mxGetClassID(y) != mxSINGLE_CLASS)||
229
(mxGetN(x)*mxGetM(x) != ncp)||
230
(mxGetN(y)*mxGetM(y) != ncp)
232
reportError("Invalid control points are specified");
236
dictSetCurrentPoints(ps, (float*)mxGetData(x), (float*)mxGetData(y));
238
case ACTION_GET_POINTS:
240
reportError("GetPoints action do not expect any arguments");
244
reportError("GetPoints action returns a single matrix");
249
reportError("normxcorr is not properly initialized, the result matrix is not allocated");
255
#ifdef USE_UNDOCUMENTED
256
plhs[0] = mxCreateSharedDataCopy(coords);
257
// mxArray *mxCreateSharedDataCopy(const mxArray *pr);
258
// bool mxUnshareArray(const mxArray *pr, const bool noDeepCopy); // true if not successful
259
// mxArray *mxUnreference(const mxArray *pr);
260
#else /* USE_UNDOCUMENTED */
261
plhs[0] = mxDuplicateArray(coords);
262
#endif /* USE_UNDOCUMENTED */
266
reportError("SETUP action expects 'ncp', 'corrsize', 'precision', and 'optimization level' parameters");
270
ncp = (int)mxGetScalar(prhs[2]);
271
corr_size = (int)mxGetScalar(prhs[3]);
272
iprop = (int)mxGetScalar(prhs[4]);
274
err = dictSetup(ps, ncp, corr_size, (int)mxGetScalar(prhs[4]), (iprop>3)?DICT_FLAGS_DEFAULT:DICT_FLAGS_FIXED_FFT_SIZE);
277
if (coords) mxDestroyArray(coords);
278
coords = mxCreateNumericMatrix(ncp, 2, mxSINGLE_CLASS, mxREAL);
279
if (coords) mexMakeArrayPersistent(coords);
281
reportError("Allocation of result matrix of size %u*float bytes is failed", ncp);
282
err = DICT_ERROR_MALLOC;
287
points = (float*)mxGetData(coords);
288
dictSetPointsBuffer(ps, points, points + ncp);
291
//mexMakeMemoryPersistent(ps->coords);
292
//mexLock() mexUnlock()
295
idMatrix = mxCreateNumericMatrix(1, 1, mxINT64_CLASS, mxREAL);
297
errPtr = (int64_t*)mxGetData(idMatrix);
301
reportError("Initialization of result matrix is failed");
307
case ACTION_COMPUTE_FRAGMENT:
309
icp = (unsigned int)mxGetScalar(prhs[2]) - 1;
310
idMatrix = mxCreateNumericMatrix(size, size, mxSINGLE_CLASS, mxREAL);
312
dictProcessFragment(ps, icp, 1, prhs[3]);
313
dictGetCorrelations(ps, icp, (float*)mxGetPr(idMatrix));
318
case ACTION_GET_CORRECTIONS:
320
idMatrix = mxCreateNumericMatrix(ncp, 2, mxSINGLE_CLASS, mxREAL);
321
float *points = (float*)mxGetData(idMatrix);
323
dictGetCorrections(ps, points, points + ncp);
328
#endif /* VALIDATE_PEAK */
330
case ACTION_COMPUTE_BASE_FRAGMENT:
332
reportError("ComputeBaseFragment action expects 2 arguments, but %i is passed", nrhs - 2);
336
icp = (unsigned int)mxGetScalar(prhs[2]) - 1;
337
if (icp >= ps->ncp) {
338
reportError("The control point (%i) is out of range (0-%u)", icp, ps->ncp - 1);
344
if (mxGetNumberOfDimensions(base) != 2) {
345
reportError("Invalid dimensionality of base matrix, 2D matrix is expected");
349
if (mxGetClassID(base) != mxUINT8_CLASS) {
350
reportError("Invalid matrix. The data type (%s) is not supported", mxGetClassName(base));
354
fft_size = 6 * corr_size + 1;
355
if (nlhs > 0) lsum = mxCreateNumericMatrix(fft_size, fft_size, mxSINGLE_CLASS, mxREAL);
357
if (nlhs > 1) denom = mxCreateNumericMatrix(fft_size, fft_size, mxSINGLE_CLASS, mxREAL);
360
dictSetDimensions(ps, GetN(base), GetM(base));
361
dictLoadTemplateFragment(ps, icp, 1, base);
362
dictGetLocalSum(ps, icp, lsum, denom);
366
if (nlhs > 1) plhs[1] = denom;
369
#endif /* VALIDATE_LSUM */
372
reportError("Unknown request %i", action);