Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sync of changes from master into developer #55

Merged
merged 18 commits into from
Aug 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions +agg/seg.m
Original file line number Diff line number Diff line change
Expand Up @@ -181,11 +181,11 @@
moreaggs = 0; % default, returned if 'Yes' is chosen
if strcmp(choice,'Yes, but refine')
choice2 = questdlg('How do you want to refine aggregate detection?',...
'agg detection','More particles or add to existing particles', ...
'agg detection','Interactive tool to adjust thresholding', ...
'Remove particles','More particles or add to existing particles');

% If more particles, set moreaggs = 1, which will skip ahead to Line 131
if strcmp(choice2, 'More particles or add to existing particles')
if strcmp(choice2, 'Interactive tool to adjust thresholding')
moreaggs = 1;

% If particles to remove, use the bwselect utility.
Expand Down
Binary file modified +agg/ui_slider2.mlapp
Binary file not shown.
19 changes: 12 additions & 7 deletions +tools/load_imgs.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
% the input string, FD. For example, the sample images can be loaded using
% IMGS = load_imgs('images').
%
% IMGS = load_imgs(FD,N) loads the images specified by array N. By
% IMGS = load_imgs(FD, N) loads the images specified by array N. By
% default, N spans 1 to the number of images in the given folder. For
% example, the 2nd and 3rd images can be loaded using N = [2,3]. This
% allows for partial loading of larger data sets for batch processing.
Expand Down Expand Up @@ -95,13 +95,18 @@

%-- Get file information -------------------------------------------------%
while flag == 0
dir_start = 'images'; % initial directory to look for images
dir_start = 'images'; % initial directory to look for images

% Browse or get file information.
if isempty(fd) % if no folder, user browses for images (tif,jpg)
if isempty(fd) % if no folder, user browses for images (tif,jpg)
[fname, folder] = uigetfile({'*.tif;*.jpg;*.png', 'TEM image (*.tif;*.jpg)'}, ...
'Select Images', dir_start, 'MultiSelect', 'on');
else % if folder is given, get all tif files in the folder

elseif isfile(fd) % then a single filename is given
[folder, fname, ext] = fileparts(fd);
fname = [fname, ext];

else % if folder is given, get all tif files in the folder
t0 = [ ... % pattern to match filenames
dir(fullfile(fd,'*.tif')), ... % get TIF
dir(fullfile(fd,'*.jpg'))]; % get JPG
Expand All @@ -110,15 +115,15 @@
end

% Format file information for output
if iscell(fname) % handle a cell array of files
if iscell(fname) % handle a cell array of files
flag = 1;
for ii=length(fname):-1:1
Imgs(ii).fname = fname{ii};
Imgs(ii).folder = [folder, filesep];
end
elseif Imgs.fname==0 % handle when no image was selected
elseif Imgs.fname==0 % handle when no image was selected
error('No image selected.');
else % handle when only one image is selected
else % handle when only one image is selected
Imgs.fname = fname;
Imgs.folder = [folder, filesep];
flag = 1;
Expand Down
11 changes: 11 additions & 0 deletions +tools/write_json.m
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@

% WRITE_JSON Used to write structures for JSON files.
% NOTE: Saving large aggregate structures can be slow.
%
% AUTHOR: Timothy Sipkens

function [t2,t0] = write_json(var, fname)

fid = fopen(fname,'wt'); % open file, overwriting previous text

% Binary field of Aggs structure is sparse logical.
% Convert of logical, as sparse structure cannot be stored.
if isfield(var, 'binary')
for ii=1:length(var)
var(ii).binary = full(var(ii).binary);
end
end

%-- Encode json ----------------------------------------------------------%
t0 = jsonencode(var); % generate json text using built-in function
Expand Down
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
jobs:
build:
machine:
image: 'ubuntu-2004:202201-02'
image: default
steps:
- checkout
- matlab/install
Expand Down
24 changes: 13 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,13 @@ This code also includes a set of utility functions in the **+tools** package and

# A. Dependencies

This software was tested using MATLAB 2020a (though most functions have been validated against older versions) and depends on the following MATLAB toolboxes:
This software was tested using MATLAB 2022a (though most functions have been validated against older versions). The current code depends on the following MATLAB toolboxes:

1. the curve fitting toolbox,
2. the financial toolbox,
3. the image toolbox,
4. the optimization toolbox, and
6. the video and image blockset (in the computer vision toolbox, which is used for OCR).
5. the video and image blockset (in the computer vision toolbox, which is used for OCR).

If not already installed, these packages can be added to MATLAB via the instructions available on [MATLAB's website](https://www.mathworks.com/help/matlab/matlab_env/get-add-ons.html).

Expand All @@ -62,7 +62,9 @@ git submodule init

The submodule is not necessary for any of the scripts or methods included with this code.

Additional dependencies are required for use of the **[carboseg](https://github.com/tsipkens/atems/tree/master/carboseg)** or convolutional neureal network component of this program, including a copy of Python. See the appropriate [section below](#+-carboseg-and-cnn-segmentation) for more information.
Additional dependencies are required for use of the **[carboseg](https://github.com/tsipkens/atems/tree/master/carboseg)** or convolutional neural network component of this program, including a copy of Python. See the appropriate [section below](#+-carboseg-and-cnn-segmentation) for more information.

This code has been tested on Windows 10+. Linux users may have some issues with loading images when supplying a string to `tools.load_imgs(...)` (for example, because of differences in file separator). macOS users may encounter similar issues, including in writing aggregate structures to JSON files and in certain plotting functions.

# B. Getting started

Expand Down Expand Up @@ -115,7 +117,7 @@ on the MATLAB command line for more information on that function.
The next step is to evaluate binary masks that separate the image into pixels that are part of the background and pixels that are part of aggregates. This is done using the functions in the **+agg** package. For example, a *k*-means classifier can be used by calling:

```Matlab
imgs_binary = agg.seg_kmeans(imgs, pixsizes, opts);
imgs_binary = agg.seg_kmeans(imgs, pixsizes);
% segment aggregates
```

Expand Down Expand Up @@ -175,7 +177,7 @@ Code associated with this example is given in the script **main_b.m**. The outpu

# C. Components

This section provides details of the overall structure of this codebase and the methods available for characterization of soot aggregates in TEM images.
This section provides details of the overall structure of this codebase and the methods available for the characterization of soot aggregates in TEM images.

## 1. MAIN SCRIPTS (main_\*): Testing the codebase

Expand Down Expand Up @@ -232,17 +234,17 @@ This `seg_carboseg(...)` function employs Python to implement a convolutional ne
Details on the setup and use of this component are given in the [README](carboseg/README.md) in the **carboseg** subfolder. Two options exist for interacting with the Python code: (1) initializing an instance of Python directly in MATLAB or (2) a multi-step procedure of exporting and reimporting images.


### + **seg_otsu_rb\*** / Otsu thresholding
### + **seg_otsu\*** / Otsu thresholding

These automated methods apply Otsu thresholding followed by a rolling ball transformation. Two versions of this function are included.

**A.** The `agg.seg_otsu_rb_orig(...)` function remains more true to the original code of [Dastanpour et al. (2016)][dastanpour2016]. For the sample images, this often results in fragmented segmentations, e.g.,
**A.** The `agg.seg_otsu_orig(...)` function remains more true to the original code of [Dastanpour et al. (2016)][dastanpour2016]. For the sample images, this often results in fragmented segmentations, e.g.,

![rb_orig](docs/otsu_rb_orig.png)

As the technique may be insufficient on its own, this implementation can be complimented with `agg.seg_slider(...)`, described [below](#-seg_slider_orig--gui-based-slider-method), to fill in the gaps between the aggregates and add missing aggregates.

**B.** Stemming from the deficiencies of the above function, the `agg.seg_otsu_rb(...)` function updates the above implementation by (*i*) not immediately removing boundary aggregates, (*ii*) adding a background subtraction step using the `agg.bg_subtract(...)` function, and (*iii*) adding a bilateral denoising step. This results in the following segmentations.
**B.** Stemming from the deficiencies of the above function, the `agg.seg_otsu(...)` function updates the above implementation by (*i*) not immediately removing boundary aggregates, (*ii*) adding a background subtraction step using the `agg.bg_subtract(...)` function, and (*iii*) adding a bilateral denoising step. This results in the following segmentations.

![otsu_rb](docs/otsu_rb.png)

Expand Down Expand Up @@ -292,11 +294,11 @@ Among the changes to the original EDM-SBS code, this implementation also applies

### + **kook\*** / Hough transform

Two `pp.kook*(...)` functions are included with this program, which fit circles to features in the image using the Hough transform and the pre-processing steps described by [Kook et al. (2015)][kook].
Two `pp.hough_kook**(...)` functions are included with this program, which fit circles to features in the image using the Hough transform and the pre-processing steps described by [Kook et al. (2015)][kook].

The first function, `pp.kook(...)`, contains a copy of the code provided by [Kook et al. (2015)][kook], with minor modifications to match the input/output of some of the other packages — namely to take a single image, `img`, and a pixel size, `pixsize` — and to output a `Pp` structure, which contains information for each circle. Note that the original function acts on images without trying to assign primary particles to an aggregate, something resolved in the second function below. This causes some compatibility issues in terms of comparing the output from this function to the other methods contained in this program.
The first function, `pp.hough_kook*(...)`, contains a copy of the code provided by [Kook et al. (2015)][kook], with minor modifications to match the input/output of some of the other packages — namely to take a single image, `img`, and a pixel size, `pixsize` — and to output a `Pp` structure, which contains information for each circle. Note that the original function acts on images without trying to assign primary particles to an aggregate, something resolved in the second function below. This causes some compatibility issues in terms of comparing the output from this function to the other methods contained in this program.

The `pp.kook2(...)` function contains a modified version of the method proposed by [Kook et al. (2015)][kook] that excludes circles in the background and assigns primary particles to aggregates. This is done rather simply: by checking if the center of the circles from the preceding procedure lie within the binary for a given aggregate. A sample output is as follows.
The `pp.hough_kook2(...)` function contains a modified version of the method proposed by [Kook et al. (2015)][kook] that excludes circles in the background and assigns primary particles to aggregates. This is done rather simply: by checking if the center of the circles from the preceding procedure lie within the binary for a given aggregate. A sample output is as follows.

![kook2](docs/kook2.png)

Expand Down
4 changes: 2 additions & 2 deletions docs/paper/paper.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ This code has been used in a number of studies in the literature. This code was

# Acknowledgements

We wish to acknowledge related code released in association with some of the cited work. These including Matlab code provided in @kook2016 and [SciLab code](https://www.coria.fr/en/edm-sbs-automated-analysis-of-tem-images/) released in association with @bescond2014. The code from @altenhoff2020 was provided by the authors and adapted to the present format.
We wish to acknowledge related code released in association with some of the cited work. These include Matlab code provided in @kook2016 and [SciLab code](https://www.coria.fr/en/edm-sbs-automated-analysis-of-tem-images/) released in association with @bescond2014. The code from @altenhoff2020 was provided by the authors and adapted to the present format.

We also wish to acknowledge funding by the Canadian Council of the Arts (Killam Fellowship), the Natural Sciences and Engineering Research Council of Canada (NSERC), and Transport Canada.


# References
# References
Loading