forked from xiaodongyang/SNV
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgetPolyNormals.c
117 lines (97 loc) · 3.05 KB
/
getPolyNormals.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include "mex.h"
#include "matrix.h"
void mexFunction(int nout, mxArray *out[], int nin, const mxArray *in[]) {
// index of input and output variables
enum {DX, DY, DT, LR, LC, LT};
enum {PN, ROW, COL, FRM};
// input matrix dimensions and pointers
const int* ndims = mxGetDimensions(in[DX]);
int nrows = ndims[0];
int ncols = ndims[1];
int nfrms = ndims[2];
const double* dx = mxGetPr(in[DX]);
const double* dy = mxGetPr(in[DY]);
const double* dt = mxGetPr(in[DT]);
// local neighborhood size
int lr = (int) *mxGetPr(in[LR]);
int lc = (int) *mxGetPr(in[LC]);
int lt = (int) *mxGetPr(in[LT]);
// iteration index and range
int ridx = 0; int cidx = 0;
int r, c, t, ir, ic, it;
int rs = lr / 2; int re = nrows - (lr / 2);
int cs = lc / 2; int ce = ncols - (lc / 2);
int ts = lt / 2; int te = nfrms - (lt / 2);
int lrs = -lr / 2; int lre = lr / 2;
int lcs = -lc / 2; int lce = lc / 2;
int lts = -lt / 2; int lte = lt / 2;
// output matrix dimensions and pointers
int nnorms = 3 * lr * lc * lt;
int nelems = (nrows - 2 * (lr / 2)) * (ncols - 2 * (lc / 2)) * (nfrms - 2 * (lt / 2));
double *pn, *row, *col, *frm;
// check argument numbers
if (nin < 6)
mexErrMsgTxt("At least six arguments are required!");
else if (nout > 4)
mexErrMsgTxt("Too many output arguments!");
// initialize ouput matrix without nullifying
out[PN] = mxCreateDoubleMatrix(0, 0, mxREAL);
mxSetM(out[PN], nelems);
mxSetN(out[PN], nnorms);
mxSetData(out[PN], mxMalloc(sizeof(double) * nelems * nnorms));
pn = mxGetPr(out[PN]);
out[ROW] = mxCreateDoubleMatrix(0, 0, mxREAL);
mxSetM(out[ROW], nelems);
mxSetN(out[ROW], 1);
mxSetData(out[ROW], mxMalloc(sizeof(double) * nelems));
row = mxGetPr(out[ROW]);
out[COL] = mxCreateDoubleMatrix(0, 0, mxREAL);
mxSetM(out[COL], nelems);
mxSetN(out[COL], 1);
mxSetData(out[COL], mxMalloc(sizeof(double) * nelems));
col = mxGetPr(out[COL]);
out[FRM] = mxCreateDoubleMatrix(0, 0, mxREAL);
mxSetM(out[FRM], nelems);
mxSetN(out[FRM], 1);
mxSetData(out[FRM], mxMalloc(sizeof(double) * nelems));
frm = mxGetPr(out[FRM]);
// get polynormals
for (r = rs; r < re; ++r) {
for (c = cs; c < ce; ++c) {
for (t = ts; t < te; ++t) {
cidx = 0;
// from dx
for (it = lts; it <= lte; ++it) {
for (ic = lcs; ic <= lce; ++ic) {
for (ir = lrs; ir <= lre; ++ir) {
pn[ridx + cidx++ * nelems] = dx[(t + it) * (nrows * ncols) + (c + ic) * nrows + (r + ir)];
}
}
}
// from dy
for (it = lts; it <= lte; ++it) {
for (ic = lcs; ic <= lce; ++ic) {
for (ir = lrs; ir <= lre; ++ir) {
pn[ridx + cidx++ * nelems] = dy[(t + it) * (nrows * ncols) + (c + ic) * nrows + (r + ir)];
}
}
}
// from dt
for (it = lts; it <= lte; ++it) {
for (ic = lcs; ic <= lce; ++ic) {
for (ir = lrs; ir <= lre; ++ir) {
pn[ridx + cidx++ * nelems] = dt[(t + it) * (nrows * ncols) + (c + ic) * nrows + (r + ir)];
}
}
}
// fill in position
row[ridx] = r + 1;
col[ridx] = c + 1;
frm[ridx] = t + 1;
// update row index
++ridx;
}
}
}
return;
}