Skip to content
Open
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 docs/closing.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ Filters out dark noise from an image.

- **Parameters:**
- gray_img - Grayscale or binary image data
- kernel - Optional neighborhood, expressed as an array of 1's and 0's. See the [kernel making](get_kernel.md) function. If None,
use cross-shaped structuring element.
- kernel - Optional neighborhood, expressed as an int, tuple, or array of 1's and 0's. See the [kernel making](get_kernel.md) function.
If None, use cross-shaped structuring element.
- roi - Optional rectangular ROI as returned by [`pcv.roi.rectangle`](roi_rectangle.md) within which to apply this function. (default = None, which uses the entire image)
- **Context:**
- Used to reduce image noise, specifically small dark spots (i.e. "pepper").
Expand Down
4 changes: 3 additions & 1 deletion docs/dilate.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ conditions set in kernel are true.

- **Parameters:**
- gray_img - Grayscale (usually binary) image data.
- ksize - An odd integer that is used to build a ksize x ksize matrix using np.ones. Must be greater than 1 to have an effect.
- ksize - Kernel specified as an int, tuple, or numpy.ndarray.
An integer is used to build a ksize x ksize matrix using np.ones and
must be greater than 1 to have an effect.
- i - An integer for number of iterations, i.e. the number of consecutive filtering passes.
- roi - Optional rectangular ROI as returned by [`pcv.roi.rectangle`](roi_rectangle.md) within which to apply this function. (default = None, which uses the entire image)
- **Context:**
Expand Down
3 changes: 2 additions & 1 deletion docs/erode.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ conditions set in kernel are true, otherwise removes pixel.

- **Parameters:**
- gray_img - Grayscale (usually binary) image data
- ksize - Kernel size, an odd integer that is used to build a ksize x ksize matrix using np.ones. Must be greater than 1 to have an effect
- ksize - Kernel specified as an int, tuple, or numpy.ndarray. An integer is used to build a ksize x ksize matrix using np.ones.
An int must be greater than 1 to have an effect.
- i - An integer for number of iterations, i.e. the number of consecutive filtering passes
- roi - Optional rectangular ROI as returned by [`pcv.roi.rectangle`](roi_rectangle.md) within which to apply this function. (default = None, which uses the entire image)

Expand Down
2 changes: 1 addition & 1 deletion docs/gaussian_blur.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ The function is a wrapper for the OpenCV function [gaussian blur](http://docs.op

- **Parameters:**
- img - RGB or grayscale image data
- ksize - Tuple of kernel dimensions, e.g. (5, 5). Must be odd integers.
- ksize - Kernel specified as a binary numpy.ndarray for arbitrary shapes, shape tuple for a rectangular kernel, or integer for a square kernel. Here any input will be coerced to a tuple.
- sigma_x - standard deviation in X direction; if 0 (default), calculated from kernel size
- sigma_y - standard deviation in Y direction; if sigma_Y is None (default), sigma_Y is taken to equal sigma_X
- roi - Optional rectangular ROI as returned by [`pcv.roi.rectangle`](roi_rectangle.md) within which to apply this function. (default = None, which uses the entire image)
Expand Down
2 changes: 1 addition & 1 deletion docs/gaussian_threshold.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ In the Gaussian adaptive threshold, the local average is a weighted average of t

- **Parameters:**
- gray_img - Grayscale image data.
- ksize - Size of the block of pixels used to compute the local average.
- ksize - Kernel specified as a binary numpy.ndarray for arbitrary shapes, shape tuple for a rectangular kernel, or integer for a square kernel. Here any input will be simplified to an integer specifying a square kernel.
- offset - Value substracted from the local average to compute the local threshold.
A negative offset sets the local threshold above the local average.
- object_type - "light" or "dark" (default: "light").
Expand Down
2 changes: 1 addition & 1 deletion docs/laplace_filter.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ This is a filtering method used to identify and highlight fine edges based on th

- **Parameters:**
- gray_img - Grayscale image data
- ksize - apertures size used to calculate 2nd derivative filter, specifies the size of the kernel (must be an odd integer: 1,3,5...)
- ksize - Kernel specified as a binary numpy.ndarray for arbitrary shapes, shape tuple for a rectangular kernel, or integer for a square kernel. Kernel inputs will be coerced to int and specify the size of the kernel (must be an odd integer: 1,3,5...) using the first element of a tuple or size of first dimension.
- scale - scaling factor applied (multiplied) to computed Laplacian values (scale = 1 is unscaled)
- roi - Optional rectangular ROI as returned by [`pcv.roi.rectangle`](roi_rectangle.md) within which to apply this function. (default = None, which uses the entire image)

Expand Down
2 changes: 1 addition & 1 deletion docs/median_blur.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ The function is a wrapper for the SciPy function [median filter](https://docs.sc

- **Parameters:**
- gray_img - Grayscale image data
- ksize - kernel size => integer or tuple, `ksize` x `ksize` box if integer, (n, m) size box if tuple
- ksize - kernel specification. Makes a ksize x ksize box if integer, an (n, m) size box if tuple, or an `np.shape(ksize)` size box if array.
- roi - Optional rectangular ROI as returned by [`pcv.roi.rectangle`](roi_rectangle.md) within which to apply this function. (default = None, which uses the entire image)
- **Context:**
- Used to reduce image noise
Expand Down
2 changes: 1 addition & 1 deletion docs/segment_image_series.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ This function uses watershed segmentation to label individual objects in a serie
- masks_paths = List of paths to the masks in the time series. Each mask should correspond to the image in imgs_paths for the same index
- rois = List of roi contours
- save_labels = Optional, saves the labels of each image independently (default: True)
- ksize = Size of the block in the time dimension to propagate the labels (default: 3)
- ksize = int, tuple, or numpy.ndarray. Specifies the size of the block in the time dimension to propagate the labels. If a tuple the first element is used, if array then the first dimension is used (default: 3)

- **Context:**
- Used to obtain individual masks for objects, like full plants or leaves, that grow in a
Expand Down
2 changes: 1 addition & 1 deletion docs/sharpen.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Sharpens an image through the unsharp masking method. Applies a gaussian blur wh

- **Parameters:**
- img - RGB or grayscale image data
- ksize - Tuple of kernel dimensions, e.g. (5, 5). Must be odd integers.
- ksize - Int, Tuple, or numpy.ndarray. Used to make a tuple of kernel dimensions, e.g. (5, 5), which must be odd integers.
- amount - Integer describing amount of sharpening, higher numbers will sharpen more.
- threshold - Integer cutoff on low contrast, contrasts lower than this will be removed.
- sigma_x - standard deviation in X direction; if 0 (default), calculated from kernel size
Expand Down
2 changes: 1 addition & 1 deletion docs/sobel_filter.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Similar results to the [Scharr filter](scharr_filter.md) function.
- gray_img - Grayscale image data
- dx - derivative of x to analyze
- dy - derivative of y to analyze
- ksize - apertures size used to calculate 2nd derivative filter, specifies the size of the kernel (must be an odd integer)
- ksize - Kernel specified as a binary numpy.ndarray for arbitrary shapes, shape tuple for a rectangular kernel, or integer for a square kernel. Here any input will be simplified to an integer specifying a square kernel. Here an integer is used, which will be taken from the first element of a tuple or the first dimension of an array's shape for compatibility with cv2.
- roi - Optional rectangular ROI as returned by [`pcv.roi.rectangle`](roi_rectangle.md) within which to apply this function. (default = None, which uses the entire image)
- **Context:**
- Used to define edges within and around objects
Expand Down
2 changes: 1 addition & 1 deletion docs/stdev_filter.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Creates a grayscale image of pixelwise standard deviation from a grayscale image

- **Parameters:**
- img - Grayscale or RGB image data
- ksize - Kernel size for texture measure calculation
- ksize - Kernel specified as a binary numpy.ndarray for arbitrary shapes, shape tuple for a rectangular kernel, or integer for a square kernel. Here any input will be simplified to an integer specifying a square kernel.
- borders - How the array borders are handled, either ‘reflect’, ‘constant’, ‘nearest’ (default), ‘mirror’, or ‘wrap’
- roi - Optional rectangular ROI as returned by [`pcv.roi.rectangle`](roi_rectangle.md) within which to apply this function. (default = None, which uses the entire image)
- **Note:**
Expand Down
2 changes: 1 addition & 1 deletion docs/texture_threshold.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ texture calculation for thresholding.

- **Parameters:**
- gray_img - Grayscale image data
- ksize - Kernel size for texture measure calculation
- ksize - Kernel specified as a binary numpy.ndarray for arbitrary shapes, shape tuple for a rectangular kernel, or integer for a square kernel. Here any input will be simplified to an integer specifying a square kernel.
- threshold - Threshold value (0-255)
- offset - Distance offsets (default offset=3)
- texture_method - Feature of a grey level co-occurrence matrix, either
Expand Down
41 changes: 24 additions & 17 deletions plantcv/plantcv/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from skimage import morphology
from plantcv.plantcv import fatal_error, warn
from plantcv.plantcv._globals import params
from plantcv.plantcv.get_kernel import _format_kernel
import pandas as pd


Expand All @@ -16,8 +17,10 @@ def _closing(gray_img, kernel=None, roi=None):
----------
gray_img = numpy.ndarray
input image (grayscale or binary)
kernel = numpy.ndarray
optional neighborhood, expressed as an array of 1s and 0s. If None, use cross-shaped structuring element.
kernel = int, numpy.ndarray, or tuple
Kernel specified as a binary numpy.ndarray for arbitrary shapes,
shape tuple for a rectangular kernel, or integer for a square kernel.
If None, uses cross-shaped structuring element.
roi : Objects class
Optional rectangular ROI to erode within

Expand All @@ -34,19 +37,20 @@ def _closing(gray_img, kernel=None, roi=None):
# Make sure the image is binary/grayscale
if len(np.shape(gray_img)) != 2:
fatal_error("Input image must be grayscale or binary")
k = _format_kernel(kernel, to=np.ndarray)

if len(np.unique(gray_img)) <= 2:
bool_img = gray_img.astype(bool)
sub_img = _rect_filter(bool_img, roi=roi, function=morphology.binary_closing,
**{"footprint": kernel})
**{"footprint": k})
filtered_img = sub_img.astype(np.uint8) * 255
replaced_img = _rect_replace(bool_img.astype(np.uint8) * 255, filtered_img, roi)
# Otherwise use method appropriate for grayscale images
else:
filtered_img = _rect_filter(gray_img,
roi=roi,
function=morphology.closing,
**{"footprint": kernel})
**{"footprint": k})
replaced_img = _rect_replace(gray_img, filtered_img, roi)

return replaced_img
Expand Down Expand Up @@ -96,8 +100,11 @@ def _erode(gray_img, ksize, i, roi=None):
----------
gray_img : numpy.ndarray
Grayscale (usually binary) image data
ksize : int
Kernel size (int). A ksize x ksize kernel will be built. Must be greater than 1 to have an effect.
ksize : int, numpy.ndarray, or tuple
Kernel specified as a binary numpy.ndarray for arbitrary shapes,
shape tuple for a rectangular kernel, or integer for a square kernel.
If ksize is an int then a k x k kernel will be built and ksize must
be greater than 1 to have an effect.
i : int
interations, i.e. number of consecutive filtering passes
roi : Objects class
Expand All @@ -113,13 +120,11 @@ def _erode(gray_img, ksize, i, roi=None):
ValueError
If ksize is less than or equal to 1.
"""
if ksize <= 1:
if isinstance(ksize, int) and ksize <= 1:
raise ValueError('ksize needs to be greater than 1 for the function to have an effect')

kernel1 = int(ksize)
kernel2 = np.ones((kernel1, kernel1), np.uint8)
k = _format_kernel(ksize, to=np.ndarray)
sub_er_img = _rect_filter(img=gray_img, roi=roi, function=cv2.erode,
**{"kernel": kernel2, "iterations": i})
**{"kernel": k, "iterations": i})
er_img = _rect_replace(gray_img, sub_er_img, roi)

return er_img
Expand All @@ -132,8 +137,11 @@ def _dilate(gray_img, ksize, i, roi=None):
----------
gray_img : numpy.ndarray
Grayscale image data to be dilated
ksize : int
Kernel size (int). A k x k kernel will be built. Must be greater than 1 to have an effect.
ksize : : int, numpy.ndarray, or tuple
Kernel specified as a binary numpy.ndarray for arbitrary shapes,
shape tuple for a rectangular kernel, or integer for a square kernel.
If ksize is an int then a k x k kernel will be built and ksize must
be greater than 1 to have an effect.
i : int
Number of iterations (i.e. how many times to apply the dilation).
roi : Objects class
Expand All @@ -149,13 +157,12 @@ def _dilate(gray_img, ksize, i, roi=None):
ValueError
If ksize is less than or equal to 1.
"""
if ksize <= 1:
if isinstance(ksize, int) and ksize <= 1:
raise ValueError('ksize needs to be greater than 1 for the function to have an effect')

kernel1 = int(ksize)
kernel2 = np.ones((kernel1, kernel1), np.uint8)
k = _format_kernel(ksize, to=np.ndarray)
sub_dil_img = _rect_filter(img=gray_img, roi=roi, function=cv2.dilate,
**{"kernel": kernel2, "iterations": i})
**{"kernel": k, "iterations": i})
dil_img = _rect_replace(gray_img, sub_dil_img, roi)

return dil_img
Expand Down
20 changes: 12 additions & 8 deletions plantcv/plantcv/closing.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,19 @@
def closing(gray_img, kernel=None, roi=None):
"""Closes holes, removing small dark spots (i.e. pepper).

Inputs:
gray_img = input image (grayscale or binary)
kernel = optional neighborhood, expressed as an array of 1s and 0s. If None, use cross-shaped structuring element.
roi = optional rectangular ROI to apply closing within a region
Parameters:
gray_img = np.ndarray,
input image (grayscale or binary)
kernel = int, numpy.ndarray, or tuple
Kernel specified as a binary numpy.ndarray for arbitrary shapes,
shape tuple for a rectangular kernel, or integer for a square kernel.
roi = plantcv.plantcv.Objects,
optional rectangular ROI to apply closing within a region

:param gray_img: np.ndarray
:param kernel = np.ndarray
:param roi: plantcv.plantcv.Objects
:return filtered_img: np.ndarray
Returns:
--------
filtered_img = numpy.ndarray
Closed image
"""
filtered_img = _closing(gray_img, kernel, roi=roi)

Expand Down
32 changes: 18 additions & 14 deletions plantcv/plantcv/dilate.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,36 @@
from plantcv.plantcv._debug import _debug
from plantcv.plantcv._helpers import _dilate
from plantcv.plantcv._globals import params
from plantcv.plantcv.get_kernel import _format_kernel


def dilate(gray_img, ksize, i, roi=None):
"""
Performs morphological 'dilation' filtering. Adds pixel to center of kernel if conditions set in kernel are true.

Inputs:
gray_img = Grayscale (usually binary) image data
ksize = Kernel size (int). A k x k kernel will be built. Must be greater than 1 to have an effect.
i = iterations, i.e. number of consecutive filtering passes
roi = rectangular ROI to dilate within
Parameters:
-----------
gray_img = numpy.ndarray,
Grayscale (usually binary) image data
ksize = int, numpy.ndarray, or tuple
Kernel specified as a binary numpy.ndarray for arbitrary shapes,
shape tuple for a rectangular kernel, or integer for a square kernel.
i = int,
iterations, i.e. number of consecutive filtering passes
roi = plantcv.plantcv.Objects,
rectangular ROI to dilate within

Returns:
dil_img = dilated image

:param gray_img: numpy.ndarray
:param ksize: int
:param i: int
:param roi: plantcv.plantcv.Objects
:return dil_img: numpy.ndarray
--------
dil_img = numpy.ndarray,
dilated image
"""
dil_img = _dilate(gray_img, ksize, i, roi=roi)
k = _format_kernel(ksize, int)
dil_img = _dilate(gray_img, k, i, roi=roi)

_debug(visual=dil_img,
filename=os.path.join(params.debug_outdir,
str(params.device) + '_dil_image' + str(ksize) + '_itr' + str(i) + '.png'),
str(params.device) + '_dil_image' + str(k) + '_itr' + str(i) + '.png'),
cmap='gray')

return dil_img
12 changes: 8 additions & 4 deletions plantcv/plantcv/erode.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from plantcv.plantcv._debug import _debug
from plantcv.plantcv._helpers import _erode
from plantcv.plantcv._globals import params
from plantcv.plantcv.get_kernel import _format_kernel


def erode(gray_img, ksize, i, roi=None):
Expand All @@ -16,8 +17,10 @@ def erode(gray_img, ksize, i, roi=None):
----------
gray_img : numpy.ndarray
Grayscale (usually binary) image data
ksize : int
Kernel size (int). A ksize x ksize kernel will be built. Must be greater than 1 to have an effect.
ksize : int, numpy.ndarray, or tuple
Kernel specified as a binary numpy.ndarray for arbitrary shapes,
shape tuple for a rectangular kernel, or integer for a square kernel.
Here any input will be coerced to int.
i : int
interations, i.e. number of consecutive filtering passes
roi : plantcv.plantcv.Objects
Expand All @@ -33,11 +36,12 @@ def erode(gray_img, ksize, i, roi=None):
ValueError
If ksize is less than or equal to 1.
"""
er_img = _erode(gray_img, ksize, i, roi=roi)
k = _format_kernel(ksize, int)
er_img = _erode(gray_img, k, i, roi=roi)

_debug(er_img,
filename=os.path.join(params.debug_outdir,
str(params.device) + '_er_image' + str(ksize) + '_itr_' + str(i) + '.png'),
str(params.device) + '_er_image' + str(k) + '_itr_' + str(i) + '.png'),
cmap='gray')

return er_img
Loading