diff --git a/jcvi/apps/base.py b/jcvi/apps/base.py index b69946d7..a519f764 100644 --- a/jcvi/apps/base.py +++ b/jcvi/apps/base.py @@ -7,6 +7,7 @@ import logging import os import os.path as op +import platform import shutil import signal import sys @@ -1206,13 +1207,32 @@ def Popen(cmd, stdin=None, stdout=PIPE, debug=False, shell="/bin/bash"): return proc -def is_macOS(): +def get_system_processor() -> Tuple[str, str]: """ - Check if current OS is macOS, this impacts mostly plotting code. + Get the system and processor information. """ - import platform + return platform.system(), platform.processor() - return platform.system() == "Darwin" + +def is_macOS_arm() -> bool: + """ + Check if the system is macOS on ARM. + """ + system, processor = get_system_processor() + return system == "Darwin" and "arm" in processor + + +def setup_magick_home(): + """ + Set MAGICK_HOME for ImageMagick. + """ + if "MAGICK_HOME" not in os.environ: + if is_macOS_arm(): + magick_home = "/opt/homebrew/opt/imagemagick" + if op.isdir(magick_home): + os.environ["MAGICK_HOME"] = magick_home + else: + logger.error("MAGICK_HOME not set") def popen(cmd, debug=True, shell="/bin/bash"): diff --git a/jcvi/graphics/grabseeds.py b/jcvi/graphics/grabseeds.py index eb020f35..489f5063 100644 --- a/jcvi/graphics/grabseeds.py +++ b/jcvi/graphics/grabseeds.py @@ -10,11 +10,16 @@ import sys from collections import Counter +from datetime import date from math import cos, pi, sin from typing import Any, List, Optional, Tuple import numpy as np +from ..apps.base import setup_magick_home + +setup_magick_home() + from PIL.Image import open as iopen from pyefd import elliptic_fourier_descriptors from pytesseract import image_to_string @@ -22,7 +27,7 @@ from scipy.optimize import fmin_bfgs as fmin from skimage.color import gray2rgb, rgb2gray from skimage.feature import canny, peak_local_max -from skimage.filters import roberts, sobel +from skimage.filters import roberts, sobel, threshold_otsu from skimage.measure import find_contours, regionprops, label from skimage.morphology import disk, closing from skimage.segmentation import clear_border, watershed @@ -87,7 +92,7 @@ def __init__( self.circularity = 4 * pi * props.area / props.perimeter**2 self.rgb = rgb self.colorname = closest_color(rgb) - self.datetime = exif.get("exif:DateTimeOriginal", "none") + self.datetime = exif.get("exif:DateTimeOriginal", date.today()) self.rgbtag = triplet_to_rgb(rgb) self.pixeltag = f"length={self.length} width={self.width} area={self.area}" self.hashtag = " ".join((self.rgbtag, self.colorname)) @@ -308,7 +313,7 @@ def add_seeds_options(p, args): ) g3 = p.add_argument_group("De-noise") - valid_filters = ("canny", "roberts", "sobel") + valid_filters = ("canny", "roberts", "sobel", "otsu") g3.add_argument( "--filter", default="canny", @@ -649,6 +654,9 @@ def seeds(args): edges = roberts(img_gray) elif ff == "sobel": edges = sobel(img_gray) + elif ff == "otsu": + thresh = threshold_otsu(img_gray) + edges = img_gray > thresh edges = clear_border(edges, buffer_size=opts.border) selem = disk(kernel) closed = closing(edges, selem) if kernel else edges