source: branches/4.2/components/bio-formats/utils/bfopen.m @ 7270

Revision 7270, 9.5 KB checked in by melissa, 9 years ago (diff)

Merged r7253 into 4.2.

Line 
1function [result] = bfopen(id)
2% A script for opening microscopy images in MATLAB using Bio-Formats.
3%
4% The function returns a list of image series; i.e., a cell array of cell
5% arrays of (matrix, label) pairs, with each matrix representing a single
6% image plane, and each inner list of matrices representing an image
7% series. See below for examples of usage.
8%
9% Portions of this code were adapted from:
10% http://www.mathworks.com/support/solutions/en/data/1-2WPAYR/
11%
12% This method is ~1.5x-2.5x slower than Bio-Formats's command line
13% showinf tool (MATLAB 7.0.4.365 R14 SP2 vs. java 1.6.0_20),
14% due to overhead from copying arrays.
15%
16% Thanks to all who offered suggestions and improvements:
17%     * Ville Rantanen
18%     * Brett Shoelson
19%     * Martin Offterdinger
20%     * Tony Collins
21%     * Cris Luengo
22%     * Arnon Lieber
23%     * Jimmy Fong
24%
25% NB: Internet Explorer sometimes erroneously renames the Bio-Formats library
26%     to loci_tools.zip. If this happens, rename it back to loci_tools.jar.
27%
28% Here are some examples of accessing data using the bfopen function:
29%
30%     % read the data using Bio-Formats
31%     data = bfopen('C:/data/experiment.lif');
32%
33%     % unwrap some specific image planes from the result
34%     numSeries = size(data, 1);
35%     series1 = data{1, 1};
36%     series2 = data{2, 1};
37%     series3 = data{3, 1};
38%     metadataList = data{1, 2};
39%     % ...etc.
40%     series1_numPlanes = size(series1, 1);
41%     series1_plane1 = series1{1, 1};
42%     series1_label1 = series1{1, 2};
43%     series1_plane2 = series1{2, 1};
44%     series1_label2 = series1{2, 2};
45%     series1_plane3 = series1{3, 1};
46%     series1_label3 = series1{3, 2};
47%     % ...etc.
48%
49%     % plot the 1st series's 1st image plane in a new figure
50%     series1_colorMaps = data{1, 3};
51%     figure('Name', series1_label1);
52%     if isempty(series1_colorMaps{1})
53%         colormap(gray);
54%     else
55%         colormap(series1_colorMaps{1});
56%     end
57%     imagesc(series1_plane1);
58%
59%     % Or if you have the image processing toolbox, you could use:
60%     % imshow(series1_plane1, []);
61%
62%     % Or animate as a movie (assumes 8-bit unsigned data)
63%     v = linspace(0, 1, 256)';
64%     cmap = [v v v];
65%     for p = 1:series1_numPlanes
66%         M(p) = im2frame(uint8(series1{p, 1}), cmap);
67%     end
68%     movie(M);
69%
70%     % Query some metadata fields (keys are format-dependent)
71%     subject = metadataList.get('Subject');
72%     title = metadataList.get('Title');
73
74% -- Configuration - customize this section to your liking --
75
76% Toggle the autoloadBioFormats flag to control automatic loading
77% of the Bio-Formats library using the javaaddpath command.
78%
79% For static loading, you can add the library to MATLAB's class path:
80%     1. Type "edit classpath.txt" at the MATLAB prompt.
81%     2. Go to the end of the file, and add the path to your JAR file
82%        (e.g., C:/Program Files/MATLAB/work/loci_tools.jar).
83%     3. Save the file and restart MATLAB.
84%
85% There are advantages to using the static approach over javaaddpath:
86%     1. If you use bfopen within a loop, it saves on overhead
87%        to avoid calling the javaaddpath command repeatedly.
88%     2. Calling 'javaaddpath' may erase certain global parameters.
89autoloadBioFormats = 1;
90
91% Toggle the stitchFiles flag to control grouping of similarly
92% named files into a single dataset based on file numbering.
93stitchFiles = 0;
94
95% To work with compressed Evotec Flex, fill in your LuraWave license code.
96%lurawaveLicense = 'xxxxxx-xxxxxxx';
97
98% -- Main function - no need to edit anything past this point --
99
100% load the Bio-Formats library into the MATLAB environment
101if autoloadBioFormats
102    path = fullfile(fileparts(mfilename('fullpath')), 'loci_tools.jar');
103    javaaddpath(path);
104end
105
106% set LuraWave license code, if available
107if exist('lurawaveLicense')
108    path = fullfile(fileparts(mfilename('fullpath')), 'lwf_jsdk2.6.jar');
109    javaaddpath(path);
110    java.lang.System.setProperty('lurawave.license', lurawaveLicense);
111end
112
113% check MATLAB version, since typecast function requires MATLAB 7.1+
114canTypecast = versionCheck(version, 7, 1);
115
116% check Bio-Formats version, since makeDataArray2D function requires trunk
117bioFormatsVersion = char(loci.formats.FormatTools.VERSION);
118isBioFormatsTrunk = versionCheck(bioFormatsVersion, 5, 0);
119
120r = loci.formats.ChannelFiller();
121r = loci.formats.ChannelSeparator(r);
122if stitchFiles
123    r = loci.formats.FileStitcher(r);
124end
125
126tic
127r.setId(id);
128numSeries = r.getSeriesCount();
129result = cell(numSeries, 2);
130for s = 1:numSeries
131    fprintf('Reading series #%d', s);
132    r.setSeries(s - 1);
133    width = r.getSizeX();
134    height = r.getSizeY();
135    pixelType = r.getPixelType();
136    bpp = loci.formats.FormatTools.getBytesPerPixel(pixelType);
137    fp = loci.formats.FormatTools.isFloatingPoint(pixelType);
138    sgn = loci.formats.FormatTools.isSigned(pixelType);
139    bppMax = power(2, bpp * 8);
140    little = r.isLittleEndian();
141    numImages = r.getImageCount();
142    imageList = cell(numImages, 2);
143    colorMaps = cell(numImages);
144    for i = 1:numImages
145        if mod(i, 72) == 1
146            fprintf('\n    ');
147        end
148        fprintf('.');
149        plane = r.openBytes(i - 1);
150
151        % retrieve color map data
152        if bpp == 1
153            colorMaps{s, i} = r.get8BitLookupTable()';
154        else
155            colorMaps{s, i} = r.get16BitLookupTable()';
156        end
157        if ~isempty(colorMaps{s, i})
158            newMap = colorMaps{s, i};
159            m = newMap(row, col) < 0;
160            newMap(m) = newMap(m) + bppMax;
161            colorMaps{s, i} = newMap / (bppMax - 1);
162        end
163
164        % convert byte array to MATLAB image
165        if isBioFormatsTrunk && (sgn || ~canTypecast)
166            % can get the data directly to a matrix
167            arr = loci.common.DataTools.makeDataArray2D(plane, ...
168                bpp, fp, little, height);
169        else
170            % get the data as a vector, either because makeDataArray2D
171            % is not available, or we need a vector for typecast
172            arr = loci.common.DataTools.makeDataArray(plane, ...
173                bpp, fp, little);
174        end
175
176        % Java does not have explicitly unsigned data types;
177        % hence, we must inform MATLAB when the data is unsigned
178        if ~sgn
179            if canTypecast
180                % TYPECAST requires at least MATLAB 7.1
181                % NB: arr will always be a vector here
182                switch class(arr)
183                    case 'int8'
184                        arr = typecast(arr, 'uint8');
185                    case 'int16'
186                        arr = typecast(arr, 'uint16');
187                    case 'int32'
188                        arr = typecast(arr, 'uint32');
189                    case 'int64'
190                        arr = typecast(arr, 'uint64');
191                end
192            else
193                % adjust apparent negative values to actual positive ones
194                % NB: arr might be either a vector or a matrix here
195                mask = arr < 0;
196                adjusted = arr(mask) + bppMax / 2;
197                switch class(arr)
198                    case 'int8'
199                        arr = uint8(arr);
200                        adjusted = uint8(adjusted);
201                    case 'int16'
202                        arr = uint16(arr);
203                        adjusted = uint16(adjusted);
204                    case 'int32'
205                        arr = uint32(arr);
206                        adjusted = uint32(adjusted);
207                    case 'int64'
208                        arr = uint64(arr);
209                        adjusted = uint64(adjusted);
210                end
211                adjusted = adjusted + bppMax / 2;
212                arr(mask) = adjusted;
213            end
214        end
215
216        if isvector(arr)
217            % convert results from vector to matrix
218            shape = [width height];
219            arr = reshape(arr, shape)';
220        end
221
222        % build an informative title for our figure
223        label = id;
224        if numSeries > 1
225            qs = int2str(s);
226            label = [label, '; series ', qs, '/', int2str(numSeries)];
227        end
228        if numImages > 1
229            qi = int2str(i);
230            label = [label, '; plane ', qi, '/', int2str(numImages)];
231            if r.isOrderCertain()
232                lz = 'Z';
233                lc = 'C';
234                lt = 'T';
235            else
236                lz = 'Z?';
237                lc = 'C?';
238                lt = 'T?';
239            end
240            zct = r.getZCTCoords(i - 1);
241            sizeZ = r.getSizeZ();
242            if sizeZ > 1
243                qz = int2str(zct(1) + 1);
244                label = [label, '; ', lz, '=', qz, '/', int2str(sizeZ)];
245            end
246            sizeC = r.getSizeC();
247            if sizeC > 1
248                qc = int2str(zct(2) + 1);
249                label = [label, '; ', lc, '=', qc, '/', int2str(sizeC)];
250            end
251            sizeT = r.getSizeT();
252            if sizeT > 1
253                qt = int2str(zct(3) + 1);
254                label = [label, '; ', lt, '=', qt, '/', int2str(sizeT)];
255            end
256        end
257
258        % save image plane and label into the list
259        imageList{i, 1} = arr;
260        imageList{i, 2} = label;
261    end
262
263    % extract metadata table for this series
264    metadataList = r.getMetadata();
265
266    % save images and metadata into our master series list
267    result{s, 1} = imageList;
268    result{s, 2} = metadataList;
269    result{s, 3} = colorMaps;
270    fprintf('\n');
271end
272r.close();
273toc
274
275% -- Helper functions --
276
277function [result] = versionCheck(v, maj, min)
278
279tokens = regexp(v, '[^\d]*(\d+)[^\d]+(\d+).*', 'tokens');
280majToken = tokens{1}(1);
281minToken = tokens{1}(2);
282major = str2num(majToken{1});
283minor = str2num(minToken{1});
284result = major > maj || (major == maj && minor >= min);
Note: See TracBrowser for help on using the repository browser.