From: James Tursa on
"Leyart Galli" <leyart_erase_(a)gmail.com> wrote in message <hnlu2q$20$1(a)fred.mathworks.com>...
> I am such stupid, posting the code here I managed to figure out by myself where the problem laid: the output type of the matrix should not have been mxReal but mxDOUBLE_CLASS instead :)
> I hope that this piece of code will help someone in the future.
> Thank you to everyone which has replied me

If you are talking about this line

plhs[0] = mxCreateDoubleMatrix(colLen, rowLen, mxREAL); //mxReal is our data-type, I want a 2d

and replacing the mxREAL with mxDOUBLE_CLASS then you still have a problem. The above line *is* correct for the 3rd argument and you should not replace the mxREAL with mxDOUBLE_CLASS. The latter is for use with mxCreateNumericArray and other functions.

James Tursa
From: James Tursa on
"Leyart Galli" <leyart_erase_(a)gmail.com> wrote in message <hnlt62$dcu$1(a)fred.mathworks.com>...
>
> cr=(double)inputImage[ii,jj,2];

I haven't had much time to look at your code much, but the above line is incorrect. It is valid C code, but it almost certainly does not do what you want. You are using the comma operator in this expression:

ii,jj,2

The comma operator simply evaluates all the sub-expressions in the list and has the value of the last sub-expression in the list, in this case 2. So This statement:

cr=(double)inputImage[ii,jj,2];

is equivalent to this statement (why are you casting the result of inputImage[...] which is already a double as a double again?):

cr = inputImage[2];

This does not get at the 3D indexing you are obviously trying to achieve. You need to fix this up.

James Tursa
From: Steven Lord on

"Leyart Galli" <leyart_erase_(a)gmail.com> wrote in message
news:hnlt62$dcu$1(a)fred.mathworks.com...
> Hello, sorry for the delay.
> The code I am trying to convert is the following:
>
> function [masked] = skincbcr(inputImage)
> processed=zeros(size(inputImage,1),size(inputImage,2));
> for ii=1:size(inputImage,1)
> for jj=1:size(inputImage,2)
> cb=inputImage(ii,jj,2);
> cr=inputImage(ii,jj,3);
> eq1=1.5862*cb+20;
> eq2=0.3448*cb+76.2069;
> eq3=-4.5652*cb+234.5652;
> eq4=-1.15*cb+301.75;
> eq5=-2.2857*cb+432.85;
> if(cr<=eq1&&cr>=eq2&&cr>=eq3&&cr<=eq4&&cr<=eq5)
> processed(ii,jj)=1;
> else
> processed(ii,jj)=0;
> end;
> end;
> end; masked=processed;
>
> I want to convert it because I want to achieve the best performance
> possible and I am not able to achieve them with just matlab code (Over 5
> seconds for a 640*480 image)

If performance is your most important factor (and you're willing to spend a
bit more memory to get performance) try to vectorize.

function masked = skincbcr(inputImage)
[r, c, p] = size(inputImage); % use ~ to ignore the 3rd output if desired
processed = zeros(r, c);
cb = inputImage(:, :, 2);
cr = inputImage(:, :, 3);
eq1=cr <= (1.5862*cb+20);
eq2=cr >= (0.3448*cb+76.2069);
eq3=cr >= (-4.5652*cb+234.5652);
eq4=cr <= (-1.15*cb+301.75);
eq5=cr <= (-2.2857*cb+432.85);
processed(eq1 & eq2 & eq3 & eq4 & eq5) = 1;
masked = processed;

For a 640-by-480 image (which is a 640-by-480-by-3 array) this should be
fairly snappy -- again, as long as you have enough memory to operate on each
page of the matrix. There are ways you could do this with less memory by
performing somewhat more complicated calculations (only compute eq2 for
those pixels in processed where eq1 was true, etc.) but how far you want to
go depends on where your performance/memory tradeoff point is located.

--
Steve Lord
slord(a)mathworks.com
comp.soft-sys.matlab (CSSM) FAQ: http://matlabwiki.mathworks.com/MATLAB_FAQ