-
Notifications
You must be signed in to change notification settings - Fork 279
Pixel scatter visualization #810
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
Merged
Merged
Changes from 35 commits
Commits
Show all changes
37 commits
Select commit
Hold shift + click to select a range
a4227a0
add basic read dataset and random subset functions
JorgeGtz c29dd10
add pattern matching to read dataset function
JorgeGtz 5fc831a
update init file
JorgeGtz 087a18d
update init file
JorgeGtz 29ae557
update init file
JorgeGtz 06163eb
move read_dataset and random_subset functions to new subpackage io
JorgeGtz 6107fa8
add pixel_scatter_vis function
JorgeGtz a1fcd96
using channel instead of ch
JorgeGtz 1ab922e
fix N and error string
JorgeGtz 25e1cf3
use random.sample instead of loop
JorgeGtz 588fc45
solve conflict by updating init
JorgeGtz f518064
did not solve conflict
JorgeGtz c8e00c2
add import
JorgeGtz 9fe0b03
lint corrections
JorgeGtz e4c52de
add docstring to functions in io package and pixel scatter vis
JorgeGtz e5e0401
add doc for pixel scatter visualization
JorgeGtz 5c18716
doc for io read dataset
JorgeGtz 684773c
add io methods and pixel scatter vis to table of contents
JorgeGtz 57b652d
remove io package. It is now in a different branch
JorgeGtz f17cdaf
remove io related docs in this branch
JorgeGtz 5938a8f
get channels for both x and y axes in pixel scatter visualization
JorgeGtz 2567073
update pixel scatter vis documentation for using two channels
JorgeGtz 004c338
disable debug mode for inside calls of plantcv functions
JorgeGtz 30a24aa
change name to pixel scatter plot in documentation
JorgeGtz b2c36f8
change name to pixel scatter plot in code
JorgeGtz 50ee48f
add pixel scatter plot to updating file
JorgeGtz 97c8335
fix calls to pixel scatter plot on documentation
JorgeGtz 52abbe6
add header to new py file
HaleySchuhl ad604e6
Create test_pixel_scatter_plot.py
HaleySchuhl 8a5ba1e
Revert "remove io package. It is now in a different branch"
HaleySchuhl 06893af
update io random_subset from 4.x branch
HaleySchuhl 8f5fa53
update read_dataset from 4.x
HaleySchuhl 9b283fc
Update test_pixel_scatter_plot.py
HaleySchuhl 9503d5b
add ch var
HaleySchuhl fdf0e34
Update test_pixel_scatter_plot.py
HaleySchuhl 4b8a43a
Update test name
HaleySchuhl 0d6c946
Update tests/plantcv/visualize/test_pixel_scatter_plot.py
nfahlgren File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Binary file added
BIN
+159 KB
...es/visualize_pixel_scatter_vis/10.9.1.31_pos-153-001-004_2019-10-31-13-05_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+153 KB
...es/visualize_pixel_scatter_vis/10.9.1.31_pos-153-001-004_2019-10-31-13-05_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+160 KB
...es/visualize_pixel_scatter_vis/10.9.1.31_pos-153-001-004_2019-10-31-13-05_3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+153 KB
...es/visualize_pixel_scatter_vis/10.9.1.31_pos-153-001-004_2019-10-31-13-05_4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+86.8 KB
...tation_images/visualize_pixel_scatter_vis/VIS_TV_z500_h2_g0_e100_163042_0_m.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+99.4 KB
...tation_images/visualize_pixel_scatter_vis/VIS_TV_z500_h2_g0_e100_163174_0_m.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+85.4 KB
...tation_images/visualize_pixel_scatter_vis/VIS_TV_z500_h2_g0_e100_163228_0_m.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+108 KB
...tation_images/visualize_pixel_scatter_vis/VIS_TV_z500_h2_g0_e100_167692_0_m.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+76.1 KB
.../documentation_images/visualize_pixel_scatter_vis/brassica_pixel_scatter_Gb.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+61.3 KB
.../documentation_images/visualize_pixel_scatter_vis/brassica_pixel_scatter_ba.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+79.2 KB
docs/img/documentation_images/visualize_pixel_scatter_vis/pixel_scatter_G.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+129 KB
docs/img/documentation_images/visualize_pixel_scatter_vis/pixel_scatter_s.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,78 @@ | ||
| ## Pixel scatter plot | ||
|
|
||
| This function plots a 2D pixel scatter plot visualization for a dataset of images. The horizontal and vertical coordinates are defined by the intensity of the pixels in the specified channels. The color of each dot is given by the original RGB color of the pixel. | ||
|
|
||
| **plantcv.visualize.pixel_scatter_plot**(*paths_to_imgs, x_channel, y_channel*) | ||
|
|
||
| **returns** fig, ax | ||
|
|
||
| - **Parameters:** | ||
| - paths_to_imgs - List of paths to the images. | ||
| - x_channel - Channel to use for the horizontal coordinate of the scatter plot. | ||
| Options: 'R', 'G', 'B', 'l', 'a', 'b', 'h', 's', 'v', 'gray', and 'index'. | ||
| - y_channel - Channel to use for the vertical coordinate of the scatter plot. | ||
| Options: 'R', 'G', 'B', 'l', 'a', 'b', 'h', 's', 'v', 'gray', and 'index'. | ||
|
|
||
|
|
||
| - **Context:** | ||
| - The aim of this visualization is to help selecting the threshold parameters to segment an image or dataset of | ||
| images. This visualization can show the pixels in several images at once, making the selected value more | ||
| likely to be valid for the whole dataset. | ||
|
|
||
|
|
||
| - **Example use:** | ||
| - Below | ||
|
|
||
| **Dataset images:** | ||
|
|
||
|  | ||
|  | ||
|
|
||
|  | ||
|  | ||
|
|
||
|
|
||
|
|
||
| ```python | ||
|
|
||
| from plantcv import plantcv as pcv | ||
|
|
||
| fig1, ax1 = pcv.visualize.pixel_scatter_plot(paths_to_imgs=file_paths, x_channel='index', y_channel='G') | ||
|
|
||
| fig2, ax2 = pcv.visualize.pixel_scatter_plot(paths_to_imgs=file_paths, x_channel='index', y_channel='s') | ||
|
|
||
| ``` | ||
|
|
||
| **Pixel scatter visualizations:** | ||
|
|
||
|  | ||
|
|
||
|  | ||
|
|
||
| **Dataset images:** | ||
|
|
||
|  | ||
|  | ||
|
|
||
|  | ||
|  | ||
|
|
||
| ```python | ||
|
|
||
| from plantcv import plantcv as pcv | ||
|
|
||
| fig1, ax1 = pcv.visualize.pixel_scatter_plot(paths_to_imgs=file_paths, x_channel='b', y_channel='a') | ||
|
|
||
| fig2, ax2 = pcv.visualize.pixel_scatter_plot(paths_to_imgs=file_paths, x_channel='G', y_channel='b') | ||
|
|
||
| ``` | ||
|
|
||
| **Pixel scatter visualizations:** | ||
|
|
||
|  | ||
|
|
||
|  | ||
|
|
||
|
|
||
|
|
||
| **Source Code:** [Here](https://github.com/danforthcenter/plantcv/blob/master/plantcv/plantcv/visualize/pixel_scatter_vis.py) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,123 @@ | ||
| # Visualize a scatter plot of pixels | ||
|
|
||
| import numpy as np | ||
| import cv2 as cv | ||
| from matplotlib import pyplot as plt | ||
| from plantcv import plantcv as pcv | ||
| from plantcv.plantcv import fatal_error | ||
| from plantcv.plantcv import params | ||
|
|
||
|
|
||
| MAX_MARKER_SIZE = 20 | ||
| IMG_WIDTH = 128 | ||
|
|
||
|
|
||
| # functions to get a given channel with parameters compatible | ||
| # with rgb2gray_lab and rgb2gray_hsv to use in the dict | ||
| def _get_R(rgb_img, _): | ||
| """ Get the red channel from a RGB image """ | ||
| return rgb_img[:,:,2] | ||
|
|
||
|
|
||
| def _get_G(rgb_img, _): | ||
| """ Get the green channel from a RGB image """ | ||
| return rgb_img[:,:,1] | ||
|
|
||
|
|
||
| def _get_B(rgb_img, _): | ||
| """ Get the blue channel from a RGB image """ | ||
| return rgb_img[:,:,0] | ||
|
|
||
|
|
||
| def _get_gray(rgb_img, _): | ||
| """ Get the gray scale transformation of a RGB image """ | ||
| return pcv.rgb2gray(rgb_img=rgb_img) | ||
|
|
||
| def _get_index(rgb_img, _): | ||
| """ Get a vector with linear indices of the pixels in an image """ | ||
| h,w,_ = rgb_img.shape | ||
| return np.arange(h*w) | ||
|
|
||
|
|
||
| def _not_valid(*args): | ||
| """ Error for a non valid channel """ | ||
| return fatal_error("channel not valid, use R, G, B, l, a, b, h, s, v, gray, or index") | ||
|
|
||
|
|
||
| def pixel_scatter_plot(paths_to_imgs, x_channel, y_channel): | ||
| """ | ||
| Plot a 2D pixel scatter plot visualization for a dataset of images. | ||
| The horizontal and vertical coordinates are defined by the intensity of the | ||
| pixels in the specified channels. | ||
| The color of each dot is given by the original RGB color of the pixel. | ||
|
|
||
| Inputs: | ||
| paths_to_imgs = List of paths to the images | ||
| x_channel = Channel to use for the horizontal coordinate of the scatter plot. | ||
| Options: 'R', 'G', 'B', 'l', 'a', 'b', 'h', 's', 'v', 'gray', and 'index' | ||
| y_channel = Channel to use for the vertical coordinate of the scatter plot. | ||
| Options: 'R', 'G', 'B', 'l', 'a', 'b', 'h', 's', 'v', 'gray', and 'index' | ||
|
|
||
| Returns: | ||
| fig = matplotlib pyplot Figure object of the visualization | ||
| ax = matplotlib pyplot Axes object of the visualization | ||
|
|
||
| :param paths_to_imgs: str | ||
| :param x_channel: str | ||
| :param y_channel: str | ||
| :return fig: matplotlib.pyplot Figure object | ||
| :return ax: matplotlib.pyplot Axes object | ||
| """ | ||
| # dictionary returns the function that gets the required image channel | ||
| channel_dict = { | ||
| 'R': _get_R, | ||
| 'G': _get_G, | ||
| 'B': _get_B, | ||
| 'l': pcv.rgb2gray_lab, | ||
| 'a': pcv.rgb2gray_lab, | ||
| 'b': pcv.rgb2gray_lab, | ||
| 'gray': _get_gray, | ||
| 'h': pcv.rgb2gray_hsv, | ||
| 's': pcv.rgb2gray_hsv, | ||
| 'v': pcv.rgb2gray_hsv, | ||
| 'index': _get_index, | ||
| } | ||
|
|
||
| # store debug mode | ||
| debug = params.debug | ||
| params.debug = None | ||
|
|
||
| N = len(paths_to_imgs) | ||
| # _ = plt.figure() | ||
| fig, ax = plt.subplots() | ||
| # load and plot the set of images sequentially | ||
| for p in paths_to_imgs: | ||
| img, _, _ = pcv.readimage(filename=p, mode="native") | ||
| h, w, c = img.shape | ||
|
|
||
| # resizing to predetermined width to reduce the number of pixels | ||
| ratio = h/IMG_WIDTH | ||
| img_height = int(IMG_WIDTH*ratio) | ||
| # nearest interpolation avoids mixing pixel values | ||
| sub_img = cv.resize(img, (IMG_WIDTH, img_height), interpolation=cv.INTER_NEAREST) | ||
|
|
||
| # organize the channels as RGB to use as facecolor for the markers | ||
| sub_img_rgb = cv.cvtColor(sub_img, cv.COLOR_BGR2RGB) | ||
| fcolors = sub_img_rgb.reshape(img_height*IMG_WIDTH,c)/255 | ||
|
|
||
| # get channels | ||
| sub_img_x_ch = channel_dict.get(x_channel, _not_valid)(sub_img, x_channel) | ||
| sub_img_y_ch = channel_dict.get(y_channel, _not_valid)(sub_img, y_channel) | ||
|
|
||
| ax.scatter(sub_img_x_ch.reshape(-1), | ||
| sub_img_y_ch.reshape(-1), | ||
| alpha=0.05, s=MAX_MARKER_SIZE/N, | ||
| edgecolors=None, facecolors=fcolors) | ||
|
|
||
| plt.xlabel(x_channel) | ||
| plt.ylabel(y_channel) | ||
|
|
||
| # reset debug | ||
| params.debug = debug | ||
|
|
||
| return fig, ax |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| import pytest | ||
| import cv2 | ||
| import os | ||
| import numpy as np | ||
| from plantcv.plantcv.visualize.pixel_scatter_vis import pixel_scatter_plot | ||
|
|
||
|
|
||
| @pytest.mark.parametrize("ch", ['R', 'G', 'B', 'l', 'a', 'b', 'h', 's', 'v', 'gray']) | ||
| def test_plantcv_visualize_pixel_scatter_plot(ch, tmpdir): | ||
| """Test for PlantCV.""" | ||
| # Create a tmp directory | ||
| cache_dir = tmpdir.mkdir("cache") | ||
| rng = np.random.default_rng() | ||
| img_size = (10,10,3) | ||
| # create a random image and write it to the temp directory | ||
| img = rng.integers(low=0, high=255, size=img_size, dtype=np.uint8, endpoint=True) | ||
| path_to_img = os.path.join(cache_dir, 'tmp_img.png') | ||
| cv2.imwrite(path_to_img, img) | ||
| # test the function with a list of one path to the random image | ||
| _, _ = pixel_scatter_plot(paths_to_imgs=[path_to_img], x_channel=ch, y_channel='index') | ||
| assert 1 | ||
|
|
||
|
|
||
| def test_plantcv_visualize_pixel_scatter_plot_wrong_ch(tmpdir): | ||
HaleySchuhl marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| """Test for PlantCV.""" | ||
| # Create a tmp directory | ||
| cache_dir = tmpdir.mkdir("cache") | ||
| rng = np.random.default_rng() | ||
| img_size = (10,10,3) | ||
| # create a random image and write it to the temp directory | ||
| img = rng.integers(low=0, high=255, size=img_size, dtype=np.uint8, endpoint=True) | ||
| path_to_img = os.path.join(cache_dir, 'tmp_img.png') | ||
| cv2.imwrite(path_to_img, img) | ||
| # test the function with channel parameter that is not an option | ||
| with pytest.raises(RuntimeError): | ||
| _, _ = pixel_scatter_plot(paths_to_imgs=[path_to_img], x_channel='wrong_ch', y_channel='index') | ||
|
|
||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.