# Fast Image Thresholding-will a mex file improve speed?

2 views (last 30 days)
Joel on 15 Aug 2011
I have some image/video processing code where on each frame I have to threshold it about 3 different times. Right now I simply use...
while(1)
im = getsnapshot; %returns a uint8 640X480 array
im1 = im>50&im<100; %example thresholds
im2 = im >100&im<150;
im3 = im>150&im<200;
%lots more image processing
end
______
I have made the remainder of the code so efficient that at this point, most of the time is spent on the thresholding lines. Any tips to make this faster? (FYI im2bw is much slower).
Is this a situation where a Mex File could improve performance? I know a lot has changes in the last few versions of matlab to make it much faster so I am wondering if its worth mex-ing?
Thanks, Joel

Jan on 15 Aug 2011
Yes, this will be faster as C-Mex.
im1 = im > 50 & im < 100
Here at first a 640x480 LOGICAL matrix is calculated in "im > 50". Then a 2nd matrix is created for "im < 100". But is a pixels is <= 50, the test for > 100 is a waste if time. Most of all if the different intervals are not overlapping a lot of time can be saved by avoiding unnecessary tests.
Before I post a C-code, it would be helpful to know, if the intervals are continous, in opposite to your example. E.g. 50 < im < 100, 100 <= im < 150, 150 <= im < 200? Or is im==100 exluded on purpose?
[TEST-IMPLEMENTATION UNTIL QUESTIONS ARE CLEARED]: I assume, that the intervals are dense here.
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
uint8_T *im, limit1, limit2, limit3, limit4, p;
mxLogical *im1, *im2, *im3;
mwSize m, n, len;
mwIndex i;
// Check inputs:
if (nrhs != 5 || nlhs != 3) {
"Need 5 inputs and 3 outputs.");
}
if (!mxIsUint8(prhs[0])) {
"1st input must be an UINT8 matrix.");
}
// Get size of input and pointer to data:
m = mxGetM(plhs[0]);
n = mxGetN(plhs[0]);
im = (uint8_T *) mxGetData(prhs[0]);
len = m * n;
limit1 = (uint8_T) mxGetScalar(prhs[1]);
limit2 = (uint8_T) mxGetScalar(prhs[2]);
limit3 = (uint8_T) mxGetScalar(prhs[3]);
limit4 = (uint8_T) mxGetScalar(prhs[4]);
// Create outputs:
plhs[0] = mxCreateNumericMatrix(m, n, mxLOGICAL_CLASS, mxREAL);
im1 = (mxLogical *) mxGetData(plhs[0]);
plhs[1] = mxCreateNumericMatrix(m, n, mxLOGICAL_CLASS, mxREAL);
im2 = (mxLogical *) mxGetData(plhs[1]);
plhs[2] = mxCreateNumericMatrix(m, n, mxLOGICAL_CLASS, mxREAL);
im3 = (mxLogical *) mxGetData(plhs[2]);
// The calculations:
for (i = 0; i < len; i++) {
p = im[i];
if (p > limit1) {
if (p < limit2) {
im1[i] = 1;
} else if (p < limit3) {
im2[i] = 1;
} else if (p < limit4) {
im3[i] = 1;
}
}
}
return;
}
Joel on 22 Aug 2011
Any more thoughts on how the color version shoudl be structured to optimize performance?

Chirag Gupta on 15 Aug 2011
You can also use manual trigger mode on your videoinput object to reduce the overhead associated with getsnapshot.
Check the "Acquiring a Single Image in a Loop" demo in the documentation
Joel on 22 Aug 2011
Any more thoughts?