diff --git a/docs/changelog.md b/docs/changelog.md index e50a031..ef594b7 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -18,6 +18,10 @@ All notable changes to this project will be documented below. * v0.1dev: viewer = **annotate.napari_label_classes**(*img, classes, size=10, importdata=False, show=True*) +#### annotate.napari_naive_bayes_colors + +* v0.1dev: viewer = **annotate.napari_naive_bayes_colors**(*img, maskdict, filename*) + #### annotate.napari_open * v0.1dev: viewer = **annotate.napari_open**(*img, mode = 'native', show=True*) diff --git a/docs/img/documentation_images/napari_naive_bayes_colors/nbdata.png b/docs/img/documentation_images/napari_naive_bayes_colors/nbdata.png new file mode 100644 index 0000000..1b3518f Binary files /dev/null and b/docs/img/documentation_images/napari_naive_bayes_colors/nbdata.png differ diff --git a/docs/napari_naive_bayes_colors.md b/docs/napari_naive_bayes_colors.md new file mode 100644 index 0000000..c5a5571 --- /dev/null +++ b/docs/napari_naive_bayes_colors.md @@ -0,0 +1,53 @@ +## Extract Color Data from Dictionary of Masks for Naive Bayes + +This function is to extract color information from a dictionary of masks in order +to get data for naive bayes functions. Collect pixel training data in Napari, rather than ImageJ for example. + +**plantcv.annotate.napari_naive_bayes_colors**(*img, maskdict, filename*) + +**returns** data frame + +- **Parameters:** + - img - RGB image to extract color information from + - maskdict - dictionary of masks, output of [`napari_points_mask`](docs/napari_points_mask.md) for example + - filename - filename to save data, formatted to work with [Naive Bayes segmentation](https://plantcv.readthedocs.io/en/latest/tutorials/machine_learning_tutorial/) + +- **Context:** + - This function is used to extract color information from an RGB image and a mask and convert data + to be compatible with Naive Bayes training functions. + +- **Example use:** + - used in Napari Naive Bayes + + +```python +import plantcv.plantcv as pcv +import plantcv.annotate as pcvan +from plantcv import learn +import napari + +# Create an instance of the Points class +img, path, name = pcv.readimage("./wheat.png") + +# Should open interactive napari viewer +viewer = pcvan.napari_label_classes(img=img, classes=['background','healthy', 'rust', 'chlorosis'], size=4) + +maskdict = pcvan.napari_points_mask(img, viewer) + +nbdata = pcvan.napari_naive_bayes_colors(img=img, maskdict=maskdict, filename="./nbdata.txt") + +learn.naive_bayes_multiclass(samples_file="./nbdata.txt", outfile="naive_bayes_test_pdfs.txt") + +masks = pcv.naive_bayes_classifier(rgb_img=img, + pdf_file="./naive_bayes_test_pdfs.txt") + +``` + +![Screenshot](img/documentation_images/napari_points_mask/viewer_labeled.png) + +***Output Data*** + +![Screenshot](img/documentation_images/napari_naive_bayes_colors/nbdata.png) + + +**Source Code:** [Here](https://github.com/danforthcenter/plantcv-annotate/blob/main/plantcv/annotate/napari_naive_bayes_colors.py) diff --git a/mkdocs.yml b/mkdocs.yml index 2be77e3..f571acc 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -20,6 +20,7 @@ nav: - Napari Classes: napari_classes.md - Napari Join: napari_join_labels.md - Napari Label: napari_label_classes.md + - Napari Naive Bayes: napari_naive_bayes_colors.md - Napari Open: napari_open.md - Napari Points Mask: napari_points_mask.md - Napari Read Coor: napari_read_coor.md diff --git a/plantcv/annotate/__init__.py b/plantcv/annotate/__init__.py index 204af28..86ca3df 100644 --- a/plantcv/annotate/__init__.py +++ b/plantcv/annotate/__init__.py @@ -8,6 +8,7 @@ from plantcv.annotate.napari_save_coor import napari_save_coor from plantcv.annotate.napari_read_coor import napari_read_coor from plantcv.annotate.napari_points_mask import napari_points_mask +from plantcv.annotate.napari_naive_bayes_colors import napari_naive_bayes_colors # Auto versioning __version__ = version("plantcv-annotate") @@ -21,5 +22,6 @@ "napari_join_labels", "napari_save_coor", "napari_read_coor", - "napari_points_mask" + "napari_points_mask", + "napari_naive_bayes_colors" ] diff --git a/plantcv/annotate/napari_naive_bayes_colors.py b/plantcv/annotate/napari_naive_bayes_colors.py new file mode 100755 index 0000000..0dd1e50 --- /dev/null +++ b/plantcv/annotate/napari_naive_bayes_colors.py @@ -0,0 +1,40 @@ +# Get Data from Dictionary of Masks and Format for Naive Bayes + +import pandas as pd +import numpy as np + + +def napari_naive_bayes_colors(img, maskdict, filename): + """ + get names of napari keys + + Inputs: + img = rgb image + maskdict = dictionary of masks, output of napari_points_mask for example + filename = name/path of file to save data + + Returns: + dataarray = pandas data array + + :param img: RGB image + :param maskdict = dictionary of masks + :param filename = str + :return dataarray: pandas dataframe + """ + keys = list(maskdict.keys()) + datadict = {} + for key in keys: + mask = maskdict[key] + nonzero = np.transpose(np.nonzero(mask)) + keydata = [] + for x, y in nonzero: + rgbdata = list(reversed(img[x][y])) + rgblist = ", ".join(repr(int(e)) for e in rgbdata) + keydata.append(rgblist) + dict1 = {key: keydata} + datadict.update(dict1) + dataarray = pd.DataFrame.from_dict(datadict, orient='index') + datatranspose = dataarray.transpose() + datatranspose.to_csv(filename, sep="\t", index=False) + + return datatranspose diff --git a/tests/conftest.py b/tests/conftest.py index 180c56a..5ce1fa6 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -28,6 +28,11 @@ def __init__(self): # Coordinates File filename_coor = "germinated.txt" self.coor_data = os.path.join(self.datadir, filename_coor) + # Naive Bayes Data + filename_nbrgb = "08_02_16-QTHJ-RIL-019_zoomed.png" + self.nb_rgb = os.path.join(self.datadir, filename_nbrgb) + filename_nbmask = "my_maskdict.npy" + self.nb_mask = os.path.join(self.datadir, filename_nbmask) diff --git a/tests/test_napari_naive_bayes.py b/tests/test_napari_naive_bayes.py new file mode 100644 index 0000000..ae77cf1 --- /dev/null +++ b/tests/test_napari_naive_bayes.py @@ -0,0 +1,16 @@ +import os +import numpy as np +from plantcv.plantcv import readimage +from plantcv.annotate import napari_naive_bayes_colors + + +def test_napari_naive_bayes_colors(test_data, tmpdir): + """Test for PlantCV.Annotate""" + # Read in test data + cache_dir = tmpdir.mkdir("cache") + img, _, _ = readimage(test_data.nb_rgb) + maskdict = np.load(test_data.nb_mask, allow_pickle='TRUE').item() + filename = os.path.join(cache_dir, 'tempfile.txt') + data = napari_naive_bayes_colors(img, maskdict, filename) + + assert data.shape == (16, 1) diff --git a/tests/testdata/08_02_16-QTHJ-RIL-019_zoomed.png b/tests/testdata/08_02_16-QTHJ-RIL-019_zoomed.png new file mode 100755 index 0000000..f4bcea3 Binary files /dev/null and b/tests/testdata/08_02_16-QTHJ-RIL-019_zoomed.png differ diff --git a/tests/testdata/my_maskdict.npy b/tests/testdata/my_maskdict.npy new file mode 100644 index 0000000..279ccd3 Binary files /dev/null and b/tests/testdata/my_maskdict.npy differ