Convert cell array to double, with comma separated elements

Hello guys,
I have got a cell array like the follow:
'1.265000e+02, 2.505000e+02, 22, 27, '
'1.275000e+02, 2.505000e+02, 20, 29, '
'1.275000e+02, 2.525000e+02, 20, 25, '
...
I need to convert it in double (or uint8). The outup should be:
[126.5, 250.5, 22, 27]
What I need is that all the values must be in a single cell and that a comma separeted any value. The last comma from any cell should be removed.
L'output in double/ uint8
Can you please help me? Many thanks in advance!!

2 Comments

"I need to convert it in double (or uint8)"
I doubt you want uint8 (8-bit integer). 126.5 is not an integer so will be rounded. With matlab's strange integer conversion rule, this would be rounded to 127. In addition, the maximum value that can be stored as uint8 is 255, very close to your 250.5.
thank you. what about double?

Sign in to comment.

Answers (2)

>> v=cell2mat(cellfun(@(s) sscanf(s,'%f,').',c,'UniformOutput',false))
v =
126.5000 250.5000 22.0000 27.0000
127.5000 250.5000 20.0000 29.0000
127.5000 252.5000 20.0000 25.0000
>>
However, it would probably be better to read the data in numerically instead...how did you obtain the above cell content?

12 Comments

thank you dpb, but the output is 4 cells for each row.
I need one cell for each row like this:
[126.5, 250.5, 22, 27]
[126.5, 250.5, 22, 27]
[127.5, 250.5, 22, 29]
[127.5, 252.5, 22, 25]
separated by comma
The output is a matrix. By definition, each cell of a matrix can only contain one number.
You could convert to a cell array of vectors, which would use more memory to store the same thing and be more complicated to use with:
num2cell(v, 2)
but what would be the point?
If you want one cell per string, simply get rid of the cell2mat.
This is probably the most efficient solution:
>> C = {'1.265000e+02, 2.505000e+02, 22, 27, ';'1.275000e+02, 2.505000e+02, 20, 29, ';'1.275000e+02, 2.525000e+02, 20, 25, '};
>> M = sscanf([C{:}],'%f,',[4,Inf]).'
M =
126.500 250.500 22.000 27.000
127.500 250.500 20.000 29.000
127.500 252.500 20.000 25.000
Yeah, I used cellfun to do the reshape() or instead of coding in the shape into sscanf...
The form of the input the number isn't known directly w/o counting delimiters so isn't as general solution.
I still say the more interesting question is how got the data in this format to begin with and why not solve the issue there instead?
I completely agree with dpb, most likely that cell array comes from a badly designed import and it would be much better to fix that import rather than try to fix the mess after the fact.
"I need one cell for each row like this:"
What on the earth for???? Show us a WHY for that...almost certainly not going to be the better way forward (nor mousetrap, either).
Initially, my code was:
BoundingBox = [];
image = bwlabel(Mask);
props = regionprops(image, 'BoundingBox');
bbox = props.BoundingBox;
BoundB = [BoundingBox; bbox];
So the output was double, with 4 cells for each row:
BoundB =
126.500 250.500 22.000 27.000
127.500 250.500 20.000 29.000
127.500 252.500 20.000 25.000
However, Since I need a comma separated values, in a single cell, like this:
Desired_output:
[26,250,22,27]
[126,250,22,27]
[127,250,22,29]
[127,252,22,25]
I had to convert in cell array, using this script:
BoundingBox = {};
image = bwlabel(Mask);
props = regionprops(image, 'BoundingBox');
bbox = props.BoundingBox;
BoundingBox = [BoundingBox; (sprintf('[%2.0f,%2.0f,%d,%d]', bbox))];
So the output is:
'[127,251,22,27]'
'[128,251,20,29]'
'[128,253,20,25]'
'[129,251,23,29]'
but I cannot convert it to a double anymore and I got an error message:
Error using tabular/rowfun>dfltErrHandler (line 509)
Applying the function '@(varargin)selectTrainingSamples(this,classNames,varargin{:})' to the 1st row of A
generated the following error:
The value of 'bboxA' is invalid. Expected input to be one of these types:
uint8, int8, uint16, int16, uint32, int32, single, double
that's why I need to convert those value in one of that format.
Any help?
BoundingBox = [];
image = bwlabel(Mask);
props = regionprops(image, 'BoundingBox');
bbox = props.BoundingBox;
BoundB = [BoundingBox; bbox];
is more simply written as just
image = bwlabel(Mask);
props = regionprops(image, 'BoundingBox');
BoundB = props.BoundingBox;
the other intermediary variables and catenation serve no useful purpose; MATLAB will allocate on assignment.
"So the output was double, with 4 cells for each row:...However, Since I need a comma separated values, in a single cell, like this:"
Why? You've not shown anything that gives any reason whatsoever to not just use the array. What are you trying to do with BoundB that you can't, specifically?
Ok, let's see now.
The input for objectDetectorTrainingData is:
"If you use a table, the table must have two or more columns. The first column of the table must contain image file names with paths. The images must be grayscale or truecolor (RGB) and they can be in any format supported by imread. Each of the remaining columns must be a cell vector that contains M-by-4 matrices that represent a single object class, such as vehicle, flower, or stop sign. The columns contain 4-element double arrays of M bounding boxes in the format [x,y,width,height]. The format specifies the upper-left corner location and size of the bounding box in the corresponding image"
The pitcure I had tried to attach is in the input argument of this page:
thank you
[I deleted the image and related redherring sidebar...dpb]
I don't have the TB so can't play directly, but looks like there's a veritable plethora of helper functions that go along with building the necessary objects. Don't see any use of them in any of the code you've supplied so far..
I suggest trying to follow one of those examples -- some of the command window looks like you loaded some of the samples as see image names -- and post exactly the code you try...
I'm sure from a quick scan of the doc you can pass an array at the appropriate place although may need to be by row indexing and that you don't need to convert it to cell array w/ embedded commas. I'm sure that's misreading what the documentation means.
English likely not being your primary language, that's quite possibly related to why; that the object/toolbox seems very convoluted likely is also a contributor as well...
@Frances, there's a huge difference between what matlab displays (in the variable browser and at the command prompt) and what matlab stores. For example, look at the following table in the variable browser and command prompt
>> t = table([1;2;3], {[1 2 3]; [4, 5, 6, 7]; []})
t =
3×2 table
Var1 Var2
____ ____________
1 {1×3 double}
2 {1×4 double}
3 {0×0 double}
Despite, the variable browser showing brackets and commas, these are not part of the data. They're just display elements to show you that each row of Var2 is a vector of numbers.
In your case, as the help file you linked states, the remaining columns must be a cell vector of Mx4 (actually 1x4) matrices. To create that from your bounding boxes:
%...
props = regionprops(image, 'BoundingBox');
BoundingBoxes = num2cell(vertcat(props.BoundingBox), 2); %vertically concatenate the bounding boxes into a Mx4 matrix, then split into a Mx1 cell array or 1x4 matrix
ok..thanks for the patient!

Sign in to comment.

I hope you are looking this
A = ['1.265000e+02, 2.505000e+02, 22, 27, '
'1.275000e+02, 2.505000e+02, 20, 29, '
'1.275000e+02, 2.525000e+02, 20, 25, '];
str2num(A(1,:))

6 Comments

no, it doesn't work.
Error using str2num (line 35)
Input must be a character vector or string scalar.
Because A above is assumed to be a char() array, NOT a cellstr array (note the square brackets instead of {}).
str2num(char(c)) will work but has potential side effects in that str2num calls eval internally.
I still say you're probably looking at wrong way to solve the problem in that almost certainly should have read the data in as numeric to start with or done the conversion there. But, how you got these data in this format isn't provided so we can't answer the underlying question that wasn't asked.
Note that the construction of A in Mohamed's answer would have failed if one the lines had more characters than the other (e.g. replace the 29 by 29.5 on the 2nd line).
It's unlikely the input is a char array.
you are getting erro like
"Error using str2num (line 35)
Input must be a character vector or string scalar."
means your cell array is not like what I wrote
A = ['1.265000e+02, 2.505000e+02, 22, 27, '
'1.275000e+02, 2.505000e+02, 20, 29, '
'1.275000e+02, 2.525000e+02, 20, 25, '];
if you make it in this format, then it will work sure, otherwise send code to me, I will check it.
More better to make your code fit the OPs data... :)
"your cell array is not like what I wrote"
You did not write a cell array! Your A is a 2D char vector. That's very different. The cell array would be:
A = {'1.265000e+02, 2.505000e+02, 22, 27, ';
'1.275000e+02, 2.505000e+02, 20, 29, ';
'1.275000e+02, 2.525000e+02, 20, 25, '};
Note the use of {} not [].
"if you make it in this format, then it will work sure,"
Except it is impossible to construct a 2D char vectors with rows of different length:
>> A = ['1.265000e+02, 2.505000e+02, 22, 27.5, '; %<--- longer row here
'1.275000e+02, 2.505000e+02, 20, 29, ';
'1.275000e+02, 2.525000e+02, 20, 25, '];
Error using vertcat
Dimensions of arrays being concatenated are not
consistent.
whereas it's not an issue with cell arrays:
>> A = {'1.265000e+02, 2.505000e+02, 22, 27.5, '; %<--- longer row here
'1.275000e+02, 2.505000e+02, 20, 29, ';
'1.275000e+02, 2.525000e+02, 20, 25, '}; %does not generate an error

Sign in to comment.

Asked:

on 18 Mar 2020

Edited:

on 19 Mar 2020

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!