Indexing contents of structures without extracting them to new variables

3 views (last 30 days)
I need some help in finding a way to address the contents of a matrix that is stored in a cell within a structure DIRECTLY without having to convert the cell to another ‘variable’. This is an OUT OF MEMORY problem which I can avoid by not having to make additional copies of the contents of the structure components.
I am using the functions jpeg_read and jpeg_write from Phil Sallee’s Matlab JPEG Toolbox. Specifically, I invoke
jpegobj = jpeg_read(filename); filename is a JPEG image file
The Sallee jpeg_obj structure consists of :
image_width: 7680
image_height: 1600
image_components: 3
image_color_space: 2
jpeg_components: 3
jpeg_color_space: 3
comments: {}
coef_arrays: {[1600x7680 double] [1600x7680 double] [1600x7680 double]}
quant_tables: {[8x8 double] [8x8 double]}
ac_huff_tables: [1x4 struct]
dc_huff_tables: [1x2 struct]
optimize_coding: 0
comp_info: [1x3 struct]
progressive_mode: 1
For these large JPEG files, I consistently get OUT OF MEMORY errors even after trying to make the m-file more efficient (by, e.g., clearing variables as the script progresses).
The bulk of the storage size for jpegobj (approx 300 MB) is taken up by the three coef_arrays (the luminance, chroma blue, and chroma red matrices). My program needs to “manipulate” these matrices so I am extracting them from the jpegobj structure into usable Matlab matrices with statements such as:
luma=cell2mat(jpegobj.coef_arrays(1)); (Equation 1)
i.e., luma is a normal Matlab matrix which is modified by my code and then rewritten back to the jpegobj structure via:
jpegobj.coef_arrays(1)= mat2cell(luma,nrluma,ncluma);
These ‘steps’ are repeated for the two chroma matrices. Each of the luma and chroma matrices are approx 100 MB and this leads to my MEMORY problems – 300 MB allocated to jpegobj and an additional 300 MB allocated to luma, chromablue, and chromared.
Logically, it would be much preferable to deal directly with
cell2mat(jpegobj.coef_arrays(1))
and so avoid allocating the duplicate 300 MB of RAM. However, I don’t know how (assuming it is even possible) to access the elements of luma without using Equation 1 above. In other words, how do I get to the single element
luma(i,j)
by indexing directly into
cell2mat(jpegobj.coef_arrays(1))
???
It seems to me that, if I could do this, I could avoid using luma, chromablue, and chromared and halve my memory allocation for such large JPEG images.
I would appreciate if someone could show me how to manipulate (i.e., index into) the matrix cell2mat(jpegobj.coef_arrays(1)) directly or if there is some technique to use a pointer or ‘alias’ name for this cell matrix which would not result in allocating additional memory to the left side of equation (1).
I have a limited working ability in C++ which probably explains why I seem to have much difficulty in manipulating structures/cells within Matlab!
  2 Comments
Jose Giovanni
Jose Giovanni on 11 Apr 2013
Edited: Jan on 11 Apr 2013
Could you send me the Phil Sallee's matlab Jpeg toolbox please. I wasn't be able to download it from his home page. My email is: [deleted] Thanks
Jan
Jan on 11 Apr 2013
Edited: Jan on 11 Apr 2013
@Jose: Please do not highjack foreign threads and append a new question as a comment. In addition this forum is thought for public interchanges, such that a request to email you some code is not wanted. And finally you did not provide any useful information about your problem: I you are not able to download code from a homepage and do not show us the link to it, how could we help?
It would be more efficient to contact the author instead of asking us to do the work for you. If you really think, that this is a proper question for the forum, ask a new question. Thanks.

Sign in to comment.

Accepted Answer

Walter Roberson
Walter Roberson on 22 Feb 2012
jpegobj.coef_arrays{1}(i,j)
Notice the {1} instead of (1)
  2 Comments
Jan
Jan on 22 Feb 2012
+1. Perhaps it is not clear. The command "A = jpegobj.coef_arrays{1}" does *not* copy the array stored in the struct, but it creates a "shared array": Two variables using two headers (about 120 bytes overhead), but pointing to the same memory block.
If you modify an element of A later on, a copy is performed automatically. But as long as you only read elements from A not further memory is used.
Kenneth Sala
Kenneth Sala on 22 Feb 2012
Many thanks for this. I must have tried a dozen "combinations" of brackets but never this one. Again, thanks - 'tis already implemented in my code and does the trick.

Sign in to comment.

More Answers (1)

Sean de Wolski
Sean de Wolski on 22 Feb 2012
Cascaded indexing can be used:
S.coefArrays = {magic(1000),rand(1000),eye(1000)};
%Getting the last element of the eye()
S.coefArrays{3}(end)
%Getting the whole random matrix
r = S.coefArrays{2}; %use curly {} instead of cell2mat
%etc.
  5 Comments

Sign in to comment.

Categories

Find more on Structures in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!