Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
8b27535
sharpening function
joshqsumner Oct 27, 2025
c369764
include sharpen
joshqsumner Oct 27, 2025
2eac040
test sharpen function
joshqsumner Oct 27, 2025
b877581
include sharpening in docs/updating
joshqsumner Oct 27, 2025
81d170c
deepsource
joshqsumner Oct 27, 2025
bfc3069
import params
joshqsumner Oct 27, 2025
112f66d
changing init order
joshqsumner Oct 27, 2025
24f4eb0
direct import
joshqsumner Oct 27, 2025
16287cb
deepsource
joshqsumner Oct 27, 2025
28ce95d
moving helper to helpers
joshqsumner Oct 27, 2025
68c663e
deepsource
joshqsumner Oct 27, 2025
7e3673c
shuffling order
joshqsumner Oct 27, 2025
eb51b03
deepsource again
joshqsumner Oct 27, 2025
26b8429
module name
joshqsumner Oct 27, 2025
077fd5b
changing module name back
joshqsumner Oct 27, 2025
ec799c1
moving helper back to main sharpen module
joshqsumner Oct 27, 2025
37ac07a
importing np and cv2
joshqsumner Oct 27, 2025
5f291e1
less specific namespace
joshqsumner Oct 27, 2025
0fbcbb4
params back to bottom
joshqsumner Oct 27, 2025
9af3baf
shuffling init
joshqsumner Oct 27, 2025
f1dbc4a
Merge branch 'main' into v5.0
joshqsumner Oct 27, 2025
0c52263
Merge branch 'v5.0' into image-sharpening
joshqsumner Oct 27, 2025
a7aa6a8
params verbosity default
joshqsumner Oct 27, 2025
7dca6a5
docs update
joshqsumner Oct 27, 2025
4fc053a
importing directly again
joshqsumner Oct 28, 2025
9c63d97
relative import
joshqsumner Oct 28, 2025
d2acd28
moving params import into function
joshqsumner Oct 28, 2025
1051b93
just going to try to change the whole thing I guess
joshqsumner Oct 28, 2025
f934a6f
making debug aware of params.verbose
joshqsumner Oct 28, 2025
c730d1e
only send deprecation warnings at most verbose level
joshqsumner Oct 28, 2025
8b8788a
deepsource
joshqsumner Oct 28, 2025
d3c792a
renaming points class for deepsource
joshqsumner Oct 28, 2025
d4e832f
deepsource
joshqsumner Oct 28, 2025
b592c6c
cyclic error
joshqsumner Oct 28, 2025
07ceed8
typo
joshqsumner Oct 28, 2025
9e179f3
testing more specific import in readimage
joshqsumner Oct 28, 2025
32085a8
test import change
joshqsumner Oct 28, 2025
3101c10
desperation? spelling?
joshqsumner Oct 28, 2025
07a1288
Merge branch 'image-sharpening' into params-verbosity
joshqsumner Oct 28, 2025
81aed14
cyclic imports from touching plantcv.plantcv
joshqsumner Oct 28, 2025
611aa38
covering line
joshqsumner Oct 28, 2025
7b55c84
Merge branch 'v5.0' into params-verbosity
joshqsumner Nov 14, 2025
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
6 changes: 3 additions & 3 deletions docs/Points.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Using [Jupyter Notebooks](jupyter.md) it is possible to interactively click to collect coordinates from an image, which can be used in various downstream applications. Left click on the image to collect a point. Right click removes the
closest collected point.

**plantcv.Points**(*img, figsize=(12, 6)*)
**plantcv.Point**(*img, figsize=(12, 6)*)

**returns** interactive image class

Expand All @@ -25,8 +25,8 @@ closest collected point.
```python
from plantcv import plantcv as pcv

# Create an instance of the Points class
marker = pcv.Points(img=img, figsize=(12,6))
# Create an instance of the Point class
marker = pcv.Point(img=img, figsize=(12,6))

# Click on the plotted image to collect coordinates

Expand Down
Binary file added docs/img/documentation_images/sharpen/sharp1.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 docs/img/documentation_images/sharpen/sharp5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/params.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ the morphology sub-package. Default = 2.

**saved_color_scale**: Using the `color_palette` function will save the color scale here for reuse in downstream functions. Set to `None` to remove. Default = `None`.

**verbose**: Set the status of verboseness. When in "verbose" mode, the deprecation warning will always be printed once triggered. Default: `True`. Users can turn off deprecation warnings by setting `verbose=False`.
**verbose**: Set the status of verboseness as an integer between 0 and 2. When in the most verbose mode (2), the deprecation warning will always be printed once triggered. Default: `1`. Users can turn off messages by setting `verbose=0` or opt for more messages/debug images with `verbose=2`.

**unit**: Set the units of the size outputs. Users can scale size measurements by updating the `unit`, `px_height` and `px_width` Default: `pixels`

Expand Down
44 changes: 44 additions & 0 deletions docs/sharpen.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
## Sharpen

Sharpens an image through the unmask-sharpening method. Applies a gaussian blur which is subtracted from an exaggerated version of the starting image.

**plantcv.sharpen**(*img, ksize, amount=1, threshold=0, sigma_x=0, sigma_y=None, roi=None*)

**returns** sharpened image

- **Parameters:**
- img - RGB or grayscale image data
- ksize - Tuple of kernel dimensions, e.g. (5, 5). 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
- 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)
- **Context:**
- Used to reduce blur in an image

**Original image**

![Screenshot](img/documentation_images/threshold_2channels/VIS_TV_z500_h2_g0_e100_163042_0_m.png)

**Sharpening Image**

```python

# Apply sharpening within an ROI to show differences
roi = pcv.roi.rectangle(img, 200, 0, 335, 200)
sharp1 = pcv.sharpen(img, (5, 5), amount=1, roi=roi)

# Higher amount of sharpening will look more dramatic
sharp5 = pcv.sharpen(img, (5, 5), amount = 5, roi=roi)
```

**Sharpen (ksize = (5,5), amount=1, roi=roi)**

![sharp1](img/documentation_images/sharpen/sharp1.png)

**Sharpen (ksize = (5,5), amount=5, roi=roi)**

![sharp5](img/documentation_images/sharpen/sharp5.png)

**Source Code:** [Here](https://github.com/danforthcenter/plantcv/blob/main/plantcv/plantcv/sharpen.py)
4 changes: 4 additions & 0 deletions docs/updating.md
Original file line number Diff line number Diff line change
Expand Up @@ -1065,6 +1065,10 @@ pages for more details on the input and output variable types.
* post v3.0dev2: sr_img = **plantcv.scharr_filter**(*gray_img, dx, dy, scale*)
* post v4.9: sr_img = **plantcv.scharr_filter**(*gray_img, dx, dy, scale, roi=None*)

#### plantcv.sharpen
* pre v5.0: NA
* post v5.0: **plantcv.sharpen**(*img, ksize, amount=1, threshold=0, sigma_x=0, sigma_y=None, roi=None*)

#### plantcv.shift_img

* pre v3.0dev2: device, adjusted_img = **plantcv.shift_img**(*img, device, number, side="right", debug=None*)
Expand Down
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ nav:
- 'Filter a mask by ROI (quickly)': roi_quick_filter.md
- 'Convert ROI to Mask': roi2mask.md
- 'Segment Image Series': segment_image_series.md
- 'Sharpen Image': sharpen.md
- 'Shift Image': shift.md
- 'Spatial Clustering': spatial_clustering.md
- 'Spectral Index': spectral_index.md
Expand Down
11 changes: 7 additions & 4 deletions plantcv/plantcv/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,12 @@
from plantcv.plantcv.classes import Outputs
from plantcv.plantcv.classes import Spectral_data
from plantcv.plantcv.classes import PSII_data
from plantcv.plantcv.classes import Points
from plantcv.plantcv.classes import Point
from plantcv.plantcv.classes import Objects

# Initialize an instance of the Params and Outputs class with default values
# params and outputs are available when plantcv is imported
params = Params()
outputs = Outputs()
from plantcv.plantcv._globals import params, outputs

from plantcv.plantcv.deprecation_warning import deprecation_warning
from plantcv.plantcv.warn import warn
Expand Down Expand Up @@ -63,6 +62,7 @@
from plantcv.plantcv.canny_edge_detect import canny_edge_detect
from plantcv.plantcv.opening import opening
from plantcv.plantcv.closing import closing
from plantcv.plantcv.sharpen import sharpen
from plantcv.plantcv import roi
from plantcv.plantcv import threshold
from plantcv.plantcv import visualize
Expand Down Expand Up @@ -91,8 +91,10 @@
"Outputs",
"Spectral_data",
'PSII_data',
'Points',
'Point',
"Objects",
"params",
"outputs",
"deprecation_warning",
"warn",
"print_image",
Expand Down Expand Up @@ -139,6 +141,7 @@
"canny_edge_detect",
"opening",
"closing",
"sharpen",
"roi",
"threshold",
"visualize",
Expand Down
42 changes: 23 additions & 19 deletions plantcv/plantcv/_debug.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,32 @@
# Debugging module
from plantcv.plantcv import params
from plantcv.plantcv._globals import params
from plantcv.plantcv import print_image
from plantcv.plantcv import plot_image


def _debug(visual, filename=None, **kwargs):
"""
Save or display a visual for debugging.
def _debug(visual, filename=None, verbosity_level=0, **kwargs):
"""Save or display a visual for debugging.

Inputs:
visual - An image or plot to display for debugging
filename - An optional filename to save the visual to (default: None)
kwargs - key-value arguments to xarray.plot method
Parameters
----------
visual = numpy.ndarray, An image or plot to display for debugging
filename = str, An optional filename to save the visual to (default: None)
verbosity level = int, threshold for params.verbose to make debug image.
Defaults to 0, which essentially ignores params.verbose
kwargs = dict, key-value arguments to xarray.plot method

:param visual: numpy.ndarray
:param filename: str
:param kwargs: dict
Returns
-------
No returns
"""
# Auto-increment the device counter
params.device += 1
# if verbose from params is at least to the verbosity level, make debug images
if params.verbose >= verbosity_level:
# Auto-increment the device counter
params.device += 1

if params.debug == "print":
# If debug is print, save the image to a file
print_image(img=visual, filename=filename, **kwargs)
elif params.debug == "plot":
# If debug is plot, print to the plotting device
plot_image(img=visual, **kwargs)
if params.debug == "print":
# If debug is print, save the image to a file
print_image(img=visual, filename=filename, **kwargs)
elif params.debug == "plot":
# If debug is plot, print to the plotting device
plot_image(img=visual, **kwargs)
7 changes: 7 additions & 0 deletions plantcv/plantcv/_globals.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# define singletons

from plantcv.plantcv.classes import Params
from plantcv.plantcv.classes import Outputs

params = Params()
outputs = Outputs()
2 changes: 1 addition & 1 deletion plantcv/plantcv/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import numpy as np
from skimage import morphology
from plantcv.plantcv import fatal_error, warn
from plantcv.plantcv import params
from plantcv.plantcv._globals import params
import pandas as pd


Expand Down
3 changes: 1 addition & 2 deletions plantcv/plantcv/analyze/bound_horizontal.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
import numpy as np
from plantcv.plantcv._debug import _debug
from plantcv.plantcv._helpers import _iterate_analysis, _grayscale_to_rgb, _scale_size
from plantcv.plantcv import params
from plantcv.plantcv import outputs
from plantcv.plantcv._globals import params, outputs


def _get_boundary_values(bound_mask, total_area, axis=0):
Expand Down
2 changes: 1 addition & 1 deletion plantcv/plantcv/analyze/bound_vertical.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from plantcv.plantcv._debug import _debug
from plantcv.plantcv._helpers import _iterate_analysis, _grayscale_to_rgb, _scale_size
from plantcv.plantcv.analyze.bound_horizontal import _get_boundary_values, _boundary_img_annotation
from plantcv.plantcv import params
from plantcv.plantcv._globals import params
from plantcv.plantcv import outputs


Expand Down
2 changes: 1 addition & 1 deletion plantcv/plantcv/analyze/color.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import numpy as np
from scipy import stats
from plantcv.plantcv import fatal_error
from plantcv.plantcv import params
from plantcv.plantcv._globals import params
from plantcv.plantcv._debug import _debug
from plantcv.plantcv import outputs
from plantcv.plantcv.visualize import histogram
Expand Down
2 changes: 1 addition & 1 deletion plantcv/plantcv/analyze/size.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from scipy.spatial.distance import euclidean
from plantcv.plantcv._helpers import _iterate_analysis, _cv2_findcontours, _object_composition, _grayscale_to_rgb, _scale_size
from plantcv.plantcv import outputs, within_frame
from plantcv.plantcv import params
from plantcv.plantcv._globals import params
from plantcv.plantcv._debug import _debug


Expand Down
2 changes: 1 addition & 1 deletion plantcv/plantcv/apply_mask.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import os
import cv2
import numpy as np
from plantcv.plantcv import params
from plantcv.plantcv._globals import params
from plantcv.plantcv._debug import _debug
from plantcv.plantcv import fatal_error
from plantcv.plantcv.transform import rescale
Expand Down
2 changes: 1 addition & 1 deletion plantcv/plantcv/background_subtraction.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import numpy as np
from plantcv.plantcv._debug import _debug
from plantcv.plantcv import fatal_error, warn
from plantcv.plantcv import params
from plantcv.plantcv._globals import params


def background_subtraction(background_image, foreground_image):
Expand Down
2 changes: 1 addition & 1 deletion plantcv/plantcv/canny_edge_detect.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from plantcv.plantcv._debug import _debug
from plantcv.plantcv._helpers import _dilate
from plantcv.plantcv import params
from plantcv.plantcv._globals import params
from plantcv.plantcv import fatal_error
from skimage import feature
import numpy as np
Expand Down
67 changes: 25 additions & 42 deletions plantcv/plantcv/classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
import json
import numpy as np
import datetime
from plantcv.plantcv import __version__ as ver
from plantcv.plantcv import fatal_error
from importlib.metadata import version
from plantcv.plantcv.fatal_error import fatal_error
from plantcv.plantcv.annotate.points import _find_closest_pt
import matplotlib.pyplot as plt
from math import floor
Expand All @@ -19,46 +19,29 @@ class Params:
def __init__(self, device=0, debug=None, debug_outdir=".", line_thickness=5,
line_color=(255, 0, 255), dpi=100, text_size=0.55,
text_thickness=2, marker_size=60, color_scale="gist_rainbow", color_sequence="sequential",
sample_label="default", saved_color_scale=None, verbose=True, unit="pixels", px_height=1, px_width=1):
sample_label="default", saved_color_scale=None, verbose=1, unit="pixels", px_height=1, px_width=1):
"""Initialize parameters.

Keyword arguments/parameters:
device = Device number. Used to count steps in the pipeline. (default: 0)
debug = None, print, or plot. Print = save to file, Plot = print to screen. (default: None)
debug_outdir = Debug images output directory. (default: .)
line_thickness = Width of line drawings. (default: 5)
line_color = Color of line annotations (default = (255, 0, 255))
dpi = Figure plotting resolution, dots per inch. (default: 100)
text_size = Size of plotting text. (default: 0.55)
text_thickness = Thickness of plotting text. (default: 2)
marker_size = Size of plotting markers (default: 60)
color_scale = Name of plotting color scale (matplotlib colormap). (default: gist_rainbow)
color_sequence = Build color scales in "sequential" or "random" order. (default: sequential)
sample_label = Sample name prefix. Used in analyze functions. (default: "default")
saved_color_scale = Saved color scale that will be applied next time color_palette is called. (default: None)
verbose = Whether or not in verbose mode. (default: True)
unit = Units of size trait outputs. (default: "pixels")
px_height = Size scaling information about pixel height (default: 1)
px_width = Size scaling information about pixel width (default: 1)


:param device: int
:param debug: str
:param debug_outdir: str
:param line_thickness: numeric
:param dpi: int
:param text_size: float
:param text_thickness: int
:param marker_size: int
:param color_scale: str
:param color_sequence: str
:param sample_label: str
:param saved_color_scale: list
:param verbose: bool
:param unit: str
:param px_height: float
:param px_width: float

Parameters
----------
device = int, Device number. Used to count steps in the pipeline. (default: 0)
debug = str or None. Print = save to file, Plot = print to screen. (default: None)
debug_outdir = str, Debug images output directory. (default: .)
line_thickness = numeric, Width of line drawings. (default: 5)
line_color = tuple, Color of line annotations (default = (255, 0, 255))
dpi = numeric, Figure plotting resolution, dots per inch. (default: 100)
text_size = float, Size of plotting text. (default: 0.55)
text_thickness = int, Thickness of plotting text. (default: 2)
marker_size = int, Size of plotting markers (default: 60)
color_scale = str, Name of plotting color scale (matplotlib colormap). (default: gist_rainbow)
color_sequence = str, Build color scales in "sequential" or "random" order. (default: sequential)
sample_label = str, Sample name prefix. Used in analyze functions. (default: "default")
saved_color_scale = list or None, Saved color scale that will be applied next time color_palette is called.
(default: None)
verbose = Int, 0:2 representing verbosity level. 0 is least verbose, 2 is most verbose (default 1)
unit = str, Units of size trait outputs. (default: "pixels")
px_height = float, Size scaling information about pixel height (default: 1)
px_width = float, Size scaling information about pixel width (default: 1)
"""
self.device = device
self.debug = debug
Expand Down Expand Up @@ -180,7 +163,7 @@ def save_results(self, filename, outformat="json"):
# Add current date & time to metadata in UTC format
run_datetime = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%fZ")
self.add_metadata(term="run_date", datatype=str, value=run_datetime)
self.add_metadata(term="plantcv_version", datatype=str, value=ver)
self.add_metadata(term="plantcv_version", datatype=str, value=version("plantcv"))

if outformat.upper() == "JSON":
if os.path.isfile(filename):
Expand Down Expand Up @@ -377,7 +360,7 @@ def add_data(self, protocol):
self.__dict__[protocol.name] = protocol


class Points:
class Point:
"""Point annotation/collection class to use in Jupyter notebooks. It allows the user to
interactively click to collect coordinates from an image. Left click collects the point and
right click removes the closest collected point
Expand Down
2 changes: 1 addition & 1 deletion plantcv/plantcv/closing.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import os
from plantcv.plantcv import params
from plantcv.plantcv._globals import params
from plantcv.plantcv._debug import _debug
from plantcv.plantcv._helpers import _closing

Expand Down
2 changes: 1 addition & 1 deletion plantcv/plantcv/color_palette.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from matplotlib import pyplot as plt
import numpy as np
from plantcv.plantcv import params
from plantcv.plantcv._globals import params


def color_palette(num, saved=False):
Expand Down
2 changes: 1 addition & 1 deletion plantcv/plantcv/create_labels.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import numpy as np
from skimage.measure import label
from skimage.color import label2rgb
from plantcv.plantcv import params
from plantcv.plantcv._globals import params
from plantcv.plantcv._debug import _debug
from plantcv.plantcv._helpers import _roi_filter, _cv2_findcontours

Expand Down
Loading