Skip to content
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

Add "otsu" method to GRABSEEDS #668

Merged
merged 5 commits into from
May 14, 2024
Merged
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
28 changes: 24 additions & 4 deletions jcvi/apps/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import logging
import os
import os.path as op
import platform
import shutil
import signal
import sys
Expand Down Expand Up @@ -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"):
Expand Down
14 changes: 11 additions & 3 deletions jcvi/graphics/grabseeds.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,24 @@
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
from scipy.ndimage import binary_fill_holes, distance_transform_edt
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
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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
Expand Down