mirror of
https://github.com/EyeTrackVR/EyeTrackVR.git
synced 2025-09-26 23:09:28 +08:00
fix: ahsf feat. summer
This commit is contained in:
parent
910e6fdfe1
commit
58eaed9ad4
@ -28,76 +28,94 @@ LICENSE: Summer Software Distribution License 1.0
|
||||
------------------------------------------------------------------------------------------------------
|
||||
"""
|
||||
from __future__ import annotations
|
||||
from typing import Tuple, Optional
|
||||
import cv2
|
||||
import numpy as np
|
||||
from typing import Tuple, Optional
|
||||
import numba
|
||||
|
||||
# ------------------------- utility helpers ------------------------- #
|
||||
def _rect_scale(rect: Tuple[int, int, int, int],
|
||||
ratio: float,
|
||||
keep_center: bool = True,
|
||||
square_outer: bool = False) -> Tuple[int, int, int, int]:
|
||||
"""Scale rectangle by *ratio* (optionally keep centre fixed)."""
|
||||
x, y, w, h = rect
|
||||
if square_outer:
|
||||
w = h = int(max(w, h) * ratio)
|
||||
|
||||
@numba.njit(cache=True, fastmath=True)
|
||||
def _get_integral_sum(ii: np.ndarray, x: int, y: int, w: int, h: int) -> float:
|
||||
return ii[y + h, x + w] - ii[y, x + w] - ii[y + h, x] + ii[y, x]
|
||||
|
||||
|
||||
@numba.njit(cache=True, fastmath=True)
|
||||
def _evaluate_single_position(ii: np.ndarray, x: int, y: int, width: int, height: int,
|
||||
ratio_outer: float, kf: float, use_square: bool,
|
||||
bx: int, by: int, bw: int, bh: int) -> Tuple[float, int, int, int, int, float, float]:
|
||||
if use_square:
|
||||
ow = oh = int(max(width, height) * ratio_outer)
|
||||
else:
|
||||
w = int(w * ratio)
|
||||
h = int(h * ratio)
|
||||
if keep_center:
|
||||
cx, cy = x + rect[2] // 2, y + rect[3] // 2
|
||||
x = int(cx - w / 2)
|
||||
y = int(cy - h / 2)
|
||||
return (x, y, w, h)
|
||||
ow = int(width * ratio_outer)
|
||||
oh = int(height * ratio_outer)
|
||||
|
||||
def _clip_rect(rect: Tuple[int, int, int, int],
|
||||
boundary: Tuple[int, int, int, int]) -> Tuple[int, int, int, int]:
|
||||
"""Clip *rect* to *boundary* = (x, y, w, h)."""
|
||||
bx, by, bw, bh = boundary
|
||||
x, y, w, h = rect
|
||||
x = max(bx, x)
|
||||
y = max(by, y)
|
||||
w = min(x + w, bx + bw) - x
|
||||
h = min(y + h, by + bh) - y
|
||||
return (x, y, max(0, w), max(0, h))
|
||||
cx = x + width // 2
|
||||
cy = y + height // 2
|
||||
ox = int(cx - ow / 2)
|
||||
oy = int(cy - oh / 2)
|
||||
|
||||
def _get_block_integral(ii: np.ndarray,
|
||||
rect: Tuple[int, int, int, int]) -> int:
|
||||
"""Integral‑image sum over *rect*."""
|
||||
x, y, w, h = rect
|
||||
return (ii[y+h, x+w] - ii[y, x+w] - ii[y+h, x] + ii[y, x])
|
||||
ox = max(bx, ox)
|
||||
oy = max(by, oy)
|
||||
ow = min(ox + ow, bx + bw) - ox
|
||||
oh = min(oy + oh, by + bh) - oy
|
||||
|
||||
if ow <= 0 or oh <= 0:
|
||||
return -255.0, ox, oy, max(0, ow), max(0, oh), 0.0, 0.0
|
||||
|
||||
inner_area = width * height
|
||||
outer_area = ow * oh - inner_area
|
||||
|
||||
if outer_area <= 0:
|
||||
return -255.0, ox, oy, max(0, ow), max(0, oh), 0.0, 0.0
|
||||
|
||||
inner_sum = _get_integral_sum(ii, x, y, width, height)
|
||||
outer_sum = _get_integral_sum(ii, ox, oy, ow, oh)
|
||||
|
||||
mu_in = inner_sum / inner_area
|
||||
mu_out = (outer_sum - inner_sum) / outer_area
|
||||
|
||||
f_val = mu_out - kf * mu_in
|
||||
|
||||
return f_val, ox, oy, max(0, ow), max(0, oh), mu_in, mu_out
|
||||
|
||||
|
||||
@numba.njit(cache=True)
|
||||
def _coarse_search(ii: np.ndarray,
|
||||
roi_x: int, roi_y: int, roi_w: int, roi_h: int,
|
||||
width_min: int, width_max: int, wh_step: int, xy_step: int,
|
||||
ratio_outer: float, kf: float, use_square: bool,
|
||||
bx: int, by: int, bw: int, bh: int):
|
||||
best_f = -255
|
||||
best_pupil = (0, 0, 0, 0)
|
||||
best_outer = (0, 0, 0, 0)
|
||||
best_mu_in = best_mu_out = 0.0
|
||||
|
||||
for width in range(width_min, width_max + 1, wh_step):
|
||||
height = width
|
||||
|
||||
xmax = roi_x + roi_w - width
|
||||
ymax = roi_y + roi_h - height
|
||||
|
||||
if xmax < roi_x or ymax < roi_y:
|
||||
continue
|
||||
|
||||
for x in range(roi_x, xmax + 1, xy_step):
|
||||
for y in range(roi_y, ymax + 1, xy_step):
|
||||
f_val, ox, oy, ow, oh, mu_in, mu_out = _evaluate_single_position(
|
||||
ii, x, y, width, height, ratio_outer, kf, use_square, bx, by, bw, bh)
|
||||
|
||||
if f_val > best_f:
|
||||
best_f = f_val
|
||||
best_pupil = (x, y, width, height)
|
||||
best_outer = (ox, oy, ow, oh)
|
||||
best_mu_in = mu_in
|
||||
best_mu_out = mu_out
|
||||
|
||||
return best_f, best_pupil, best_outer, best_mu_in, best_mu_out
|
||||
|
||||
def _canny_pure(img: np.ndarray,
|
||||
low: int = 64,
|
||||
high_ratio: float = 2.0) -> np.ndarray:
|
||||
"""Lightweight Canny wrapper (imitates canny_pure())."""
|
||||
img_blur = cv2.GaussianBlur(img, (3, 3), 0)
|
||||
return cv2.Canny(img_blur, low, int(low*high_ratio))
|
||||
|
||||
# --------------------------- main class ---------------------------- #
|
||||
class PupilDetectorHaar:
|
||||
"""
|
||||
Haar‑based coarse‑to‑fine pupil detector.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
ratio_outer : float
|
||||
Scaling factor for Haar outer rectangle.
|
||||
kf : float
|
||||
Weighting term in response function f = µ_outer − kf*µ_inner.
|
||||
use_square_haar : bool
|
||||
If True, outer Haar window is square; else horizontal rectangle.
|
||||
use_init_rect : bool
|
||||
If True, provide an approximate pupil box in *init_rect*.
|
||||
init_rect : Tuple[int,int,int,int] | None
|
||||
Initial pupil location on the full‑resolution frame.
|
||||
target_resolution : Tuple[int,int]
|
||||
Image is down‑sampled so the longer side ~320 px by default.
|
||||
width_min / width_max / wh_step / xy_step
|
||||
Search‑grid parameters for Haar scanning.
|
||||
"""
|
||||
|
||||
# -------- initialisation -------- #
|
||||
def __init__(self,
|
||||
ratio_outer: float = 1.4,
|
||||
kf: float = 1.5,
|
||||
@ -109,6 +127,7 @@ class PupilDetectorHaar:
|
||||
width_max: int = 120,
|
||||
wh_step: int = 2,
|
||||
xy_step: int = 2):
|
||||
|
||||
self.ratio_outer = ratio_outer
|
||||
self.kf = kf
|
||||
self.use_square_haar = use_square_haar
|
||||
@ -116,20 +135,17 @@ class PupilDetectorHaar:
|
||||
self.init_rect = (0, 0, 0, 0) if init_rect is None else init_rect
|
||||
self.target_resolution = target_resolution
|
||||
|
||||
# search‑grid params (may be auto‑tuned after first frame)
|
||||
self.width_min = width_min
|
||||
self.width_max = width_max
|
||||
self.wh_step = wh_step
|
||||
self.xy_step = xy_step
|
||||
|
||||
# dynamic state
|
||||
self.frame_num = 0
|
||||
self.mu_inner = 50
|
||||
self.mu_outer = 200
|
||||
self.mu_inner0 = 50 # first frame stats
|
||||
self.mu_inner0 = 50
|
||||
self.mu_outer0 = 200
|
||||
|
||||
# outputs (public)
|
||||
self.pupil_rect_coarse = (0, 0, 0, 0)
|
||||
self.outer_rect_coarse = (0, 0, 0, 0)
|
||||
self.max_response_coarse = -255
|
||||
@ -138,67 +154,38 @@ class PupilDetectorHaar:
|
||||
self.pupil_rect_fine = (0, 0, 0, 0)
|
||||
self.center_fine = (0.0, 0.0)
|
||||
|
||||
# private temp
|
||||
self._ratio_down = 1.0
|
||||
self._img_boundary = (0, 0, 0, 0)
|
||||
self._init_rect_down = (0, 0, 0, 0)
|
||||
|
||||
# ---------------------------------------------------------------- #
|
||||
# PUBLIC API #
|
||||
# ---------------------------------------------------------------- #
|
||||
def detect(self, img_gray: np.ndarray) -> Tuple[Tuple[int,int,int,int], Tuple[float,float]]:
|
||||
"""
|
||||
Run detector on a single *uint8* gray image.
|
||||
|
||||
Returns
|
||||
-------
|
||||
pupil_rect_fine : (x,y,w,h)
|
||||
center_fine : (cx,cy) -- both on full‑resolution image.
|
||||
"""
|
||||
def detect(self, img_gray: np.ndarray) -> Tuple[Tuple[int, int, int, int], Tuple[float, float]]:
|
||||
if img_gray.dtype != np.uint8:
|
||||
raise TypeError("img_gray must be uint8 [0,255]")
|
||||
|
||||
self.frame_num += 1
|
||||
img_down = self._preprocess(img_gray)
|
||||
self._coarse_detection(img_down)
|
||||
self._fine_detection(img_down)
|
||||
self._fine_detection_fast(img_down)
|
||||
self._postprocess()
|
||||
|
||||
return self.pupil_rect_fine, self.center_fine
|
||||
|
||||
# --------------- optional helper for visual debugging ------------ #
|
||||
def draw_debug(self, bgr: np.ndarray) -> None:
|
||||
"""Draw rectangular outputs on *bgr* in‑place."""
|
||||
cv2.rectangle(bgr, self.pupil_rect_fine, (0, 255, 0), 1)
|
||||
cv2.rectangle(bgr, self.outer_rect_coarse, (255, 0, 0), 1)
|
||||
cx, cy = map(int, self.center_fine)
|
||||
cv2.drawMarker(bgr, (cx, cy), (0, 0, 255),
|
||||
markerType=cv2.MARKER_CROSS, markerSize=10, thickness=1)
|
||||
|
||||
# ---------------------------------------------------------------- #
|
||||
# INTERNAL STAGES #
|
||||
# ---------------------------------------------------------------- #
|
||||
def _preprocess(self, img_gray: np.ndarray) -> np.ndarray:
|
||||
# down‑sample to target size (longer side ≈ target_resolution[0])
|
||||
h, w = img_gray.shape
|
||||
self._ratio_down = max(w / self.target_resolution[0],
|
||||
h / self.target_resolution[1], 1.0)
|
||||
new_w = int(round(w / self._ratio_down))
|
||||
new_h = int(round(h / self._ratio_down))
|
||||
img_down = cv2.resize(img_gray, (new_w, new_h),
|
||||
interpolation=cv2.INTER_AREA)
|
||||
|
||||
img_down = cv2.resize(img_gray, (new_w, new_h), interpolation=cv2.INTER_AREA)
|
||||
self._img_boundary = (0, 0, new_w, new_h)
|
||||
|
||||
# optional high‑intensity suppression on first frame
|
||||
if self.use_init_rect and self.frame_num == 1:
|
||||
# Estimate µ_inner0 / µ_outer0 inside init box
|
||||
x, y, rw, rh = self.init_rect
|
||||
region = img_gray[y:y+rh, x:x+rw]
|
||||
region = img_gray[y:y + rh, x:x + rw]
|
||||
self.mu_inner0 = np.percentile(region, 25)
|
||||
self.mu_outer0 = np.percentile(region, 75)
|
||||
|
||||
# adjust kf like original code
|
||||
if self.mu_outer0 - self.mu_inner0 > 30:
|
||||
tau = self.mu_outer0
|
||||
else:
|
||||
@ -207,122 +194,94 @@ class PupilDetectorHaar:
|
||||
|
||||
return img_down
|
||||
|
||||
# ------------------------------------------------------------ #
|
||||
# COARSE DETECTION #
|
||||
# ------------------------------------------------------------ #
|
||||
def _initial_search_range(self, img_down: np.ndarray) -> Tuple[int,int,int,int]:
|
||||
"""Compute ROI and width range for current frame (down‑sampled)."""
|
||||
def _initial_search_range(self, img_down: np.ndarray) -> Tuple[int, int, int, int]:
|
||||
h, w = img_down.shape
|
||||
margin = h // 10 // 2
|
||||
full = (margin, margin, w - 2*margin, h - 2*margin)
|
||||
full = (margin, margin, w - 2 * margin, h - 2 * margin)
|
||||
|
||||
if not self.use_init_rect:
|
||||
self.roi = full
|
||||
return
|
||||
|
||||
# scale init_rect to down resolution
|
||||
self._init_rect_down = tuple(int(x / self._ratio_down) for x in self.init_rect)
|
||||
ix, iy, iw, ih = self._init_rect_down
|
||||
|
||||
# grow ROI adaptively near borders (imitates C++ code)
|
||||
rx, ry, rw, rh = full
|
||||
enlarge = 35
|
||||
if ix < enlarge: rx, rw = 0, w
|
||||
if iy < enlarge: ry, rh = 0, h
|
||||
if ix+iw > w - enlarge: rx, rw = 0, w
|
||||
if iy+ih > h - enlarge: ry, rh = 0, h
|
||||
if ix + iw > w - enlarge: rx, rw = 0, w
|
||||
if iy + ih > h - enlarge: ry, rh = 0, h
|
||||
self.roi = (rx, ry, rw, rh)
|
||||
|
||||
# width search band tuned by first frame
|
||||
self.width_min = max(int(iw*1.0), 24)
|
||||
self.width_max = min(int(iw*1.5), 120)
|
||||
self.width_min = max(int(iw * 1.0), 24)
|
||||
self.width_max = min(int(iw * 1.5), 120)
|
||||
|
||||
def _coarse_detection(self, img_down: np.ndarray) -> None:
|
||||
self._initial_search_range(img_down)
|
||||
roi_x, roi_y, roi_w, roi_h = self.roi
|
||||
|
||||
# build integral image (cv2 adds +1 row/col)
|
||||
# Build integral image
|
||||
ii = cv2.integral(img_down, sdepth=cv2.CV_32S)
|
||||
|
||||
best_f = -255
|
||||
best_pupil = (0, 0, 0, 0)
|
||||
best_outer = (0, 0, 0, 0)
|
||||
best_mu_in, best_mu_out = 0, 0
|
||||
|
||||
for width in range(self.width_min, self.width_max+1, self.wh_step):
|
||||
# height tied to width; rectangular pupils handled fine
|
||||
for height in range(width, width+1, self.wh_step):
|
||||
xmax = roi_x + roi_w - width
|
||||
ymax = roi_y + roi_h - height
|
||||
for x in range(roi_x, xmax+1, self.xy_step):
|
||||
for y in range(roi_y, ymax+1, self.xy_step):
|
||||
pupil = (x, y, width, height)
|
||||
outer = _rect_scale(pupil, self.ratio_outer,
|
||||
keep_center=True,
|
||||
square_outer=self.use_square_haar)
|
||||
outer = _clip_rect(outer, self._img_boundary)
|
||||
|
||||
mu_in, mu_out = 0.0, 0.0
|
||||
mu_out = (_get_block_integral(ii, outer) -
|
||||
_get_block_integral(ii, pupil)) / \
|
||||
(outer[2]*outer[3] - width*height)
|
||||
mu_in = _get_block_integral(ii, pupil) / (width*height)
|
||||
f_val = mu_out - self.kf * mu_in
|
||||
if f_val > best_f:
|
||||
best_f = f_val
|
||||
best_pupil = pupil
|
||||
best_outer = outer
|
||||
best_mu_in, best_mu_out = mu_in, mu_out
|
||||
# Optimized search
|
||||
bx, by, bw, bh = self._img_boundary
|
||||
best_f, best_pupil, best_outer, best_mu_in, best_mu_out = _coarse_search(
|
||||
ii, roi_x, roi_y, roi_w, roi_h,
|
||||
self.width_min, self.width_max, self.wh_step, self.xy_step,
|
||||
self.ratio_outer, self.kf, self.use_square_haar,
|
||||
bx, by, bw, bh
|
||||
)
|
||||
|
||||
self.pupil_rect_coarse = best_pupil
|
||||
self.outer_rect_coarse = best_outer
|
||||
self.max_response_coarse = best_f
|
||||
self.mu_inner, self.mu_outer = best_mu_in, best_mu_out
|
||||
self.mu_inner = best_mu_in
|
||||
self.mu_outer = best_mu_out
|
||||
|
||||
px, py, pw, ph = best_pupil
|
||||
self.center_coarse = (px + pw / 2, py + ph / 2)
|
||||
|
||||
# ------------------------------------------------------------ #
|
||||
# FINE DETECTION #
|
||||
# ------------------------------------------------------------ #
|
||||
def _fine_detection(self, img_down: np.ndarray) -> None:
|
||||
def _fine_detection_fast(self, img_down: np.ndarray) -> None:
|
||||
px, py, pw, ph = self.pupil_rect_coarse
|
||||
expand = 1.42
|
||||
exp_rect = _clip_rect(_rect_scale(self.pupil_rect_coarse, expand, True),
|
||||
self._img_boundary)
|
||||
ex, ey, ew, eh = exp_rect
|
||||
patch = img_down[ey:ey+eh, ex:ex+ew]
|
||||
|
||||
# threshold at µ_inner (same heuristic)
|
||||
_, bw = cv2.threshold(patch, int(self.mu_inner), 255,
|
||||
cv2.THRESH_BINARY_INV)
|
||||
cx, cy = px + pw // 2, py + ph // 2
|
||||
ew, eh = int(pw * expand), int(ph * expand)
|
||||
ex, ey = cx - ew // 2, cy - eh // 2
|
||||
|
||||
# dilate to merge gaps
|
||||
bw = cv2.dilate(bw, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5)))
|
||||
# Clip to boundary
|
||||
bx, by, bw, bh = self._img_boundary
|
||||
ex = max(bx, ex)
|
||||
ey = max(by, ey)
|
||||
ew = min(ex + ew, bx + bw) - ex
|
||||
eh = min(ey + eh, by + bh) - ey
|
||||
|
||||
# connected components
|
||||
n, labels, stats, centroids = cv2.connectedComponentsWithStats(bw)
|
||||
if n <= 1:
|
||||
# fall‑back: keep coarse rect
|
||||
self.pupil_rect_fine = tuple(int(v) for v in
|
||||
np.array(self.pupil_rect_coarse) *
|
||||
self._ratio_down)
|
||||
self.center_fine = tuple(v * self._ratio_down
|
||||
for v in self.center_coarse)
|
||||
if ew <= 0 or eh <= 0:
|
||||
self.pupil_rect_fine = self.pupil_rect_coarse
|
||||
self.center_fine = self.center_coarse
|
||||
return
|
||||
|
||||
patch = img_down[ey:ey + eh, ex:ex + ew]
|
||||
|
||||
_, bw = cv2.threshold(patch, int(self.mu_inner), 255, cv2.THRESH_BINARY_INV)
|
||||
bw = cv2.dilate(bw, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5)))
|
||||
|
||||
n, labels, stats, centroids = cv2.connectedComponentsWithStats(bw)
|
||||
if n <= 1:
|
||||
self.pupil_rect_fine = self.pupil_rect_coarse
|
||||
self.center_fine = self.center_coarse
|
||||
return
|
||||
|
||||
# discard tiny blobs (<4% of patch)
|
||||
areas = stats[1:, cv2.CC_STAT_AREA]
|
||||
mask = areas > 0.04 * bw.size
|
||||
if not np.any(mask):
|
||||
mask = areas.argmax()[None] # keep largest if all tiny
|
||||
mask = areas.argmax()[None]
|
||||
|
||||
# choose component through image centre, else darkest centroid
|
||||
cx_local = patch.shape[1] // 2
|
||||
cy_local = patch.shape[0] // 2
|
||||
comp_idx = labels[cy_local, cx_local]
|
||||
if comp_idx == 0 or not mask[comp_idx-1]:
|
||||
# pick darkest of two largest blobs (C++ heuristic)
|
||||
if comp_idx == 0 or not mask[comp_idx - 1]:
|
||||
dark = 255
|
||||
for idx in np.flatnonzero(mask) + 1:
|
||||
cx_i, cy_i = centroids[idx]
|
||||
@ -331,24 +290,21 @@ class PupilDetectorHaar:
|
||||
dark = val
|
||||
comp_idx = idx
|
||||
|
||||
# final bounding box in down‑scaled coords
|
||||
x, y, w, h = stats[comp_idx, cv2.CC_STAT_LEFT : cv2.CC_STAT_HEIGHT+1]
|
||||
x, y, w, h = stats[comp_idx, cv2.CC_STAT_LEFT: cv2.CC_STAT_HEIGHT + 1]
|
||||
x += ex
|
||||
y += ey
|
||||
self.pupil_rect_fine = (x, y, w, h)
|
||||
self.center_fine = (x + w / 2, y + h / 2)
|
||||
|
||||
# ------------------------------------------------------------ #
|
||||
# UPSAMPLE BACK #
|
||||
# ------------------------------------------------------------ #
|
||||
def _postprocess(self) -> None:
|
||||
# scale coarse and fine rects + centres back to full resolution
|
||||
scale = self._ratio_down
|
||||
|
||||
def _up(rect):
|
||||
return tuple(int(round(v*scale)) for v in rect)
|
||||
return tuple(int(round(v * scale)) for v in rect)
|
||||
|
||||
self.pupil_rect_coarse = _up(self.pupil_rect_coarse)
|
||||
self.outer_rect_coarse = _up(self.outer_rect_coarse)
|
||||
self.pupil_rect_fine = _up(self.pupil_rect_fine)
|
||||
|
||||
self.center_coarse = tuple(v*scale for v in self.center_coarse)
|
||||
self.center_fine = tuple(v*scale for v in self.center_fine)
|
||||
self.center_coarse = tuple(v * scale for v in self.center_coarse)
|
||||
self.center_fine = tuple(v * scale for v in self.center_fine)
|
@ -62,7 +62,7 @@ WINDOW_NAME = "EyeTrackApp"
|
||||
|
||||
|
||||
page_url = "https://github.com/EyeTrackVR/EyeTrackVR/releases/latest"
|
||||
appversion = "EyeTrackApp 0.2.3"
|
||||
appversion = "EyeTrackApp 0.2.4"
|
||||
|
||||
|
||||
class KeyManager:
|
||||
|
193
poetry.lock
generated
193
poetry.lock
generated
@ -422,6 +422,37 @@ dev = ["changelist (==0.5)"]
|
||||
lint = ["pre-commit (==3.7.0)"]
|
||||
test = ["pytest (>=7.4)", "pytest-cov (>=4.1)"]
|
||||
|
||||
[[package]]
|
||||
name = "llvmlite"
|
||||
version = "0.44.0"
|
||||
description = "lightweight wrapper around basic LLVM functionality"
|
||||
optional = false
|
||||
python-versions = ">=3.10"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "llvmlite-0.44.0-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:9fbadbfba8422123bab5535b293da1cf72f9f478a65645ecd73e781f962ca614"},
|
||||
{file = "llvmlite-0.44.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cccf8eb28f24840f2689fb1a45f9c0f7e582dd24e088dcf96e424834af11f791"},
|
||||
{file = "llvmlite-0.44.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7202b678cdf904823c764ee0fe2dfe38a76981f4c1e51715b4cb5abb6cf1d9e8"},
|
||||
{file = "llvmlite-0.44.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:40526fb5e313d7b96bda4cbb2c85cd5374e04d80732dd36a282d72a560bb6408"},
|
||||
{file = "llvmlite-0.44.0-cp310-cp310-win_amd64.whl", hash = "sha256:41e3839150db4330e1b2716c0be3b5c4672525b4c9005e17c7597f835f351ce2"},
|
||||
{file = "llvmlite-0.44.0-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:eed7d5f29136bda63b6d7804c279e2b72e08c952b7c5df61f45db408e0ee52f3"},
|
||||
{file = "llvmlite-0.44.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ace564d9fa44bb91eb6e6d8e7754977783c68e90a471ea7ce913bff30bd62427"},
|
||||
{file = "llvmlite-0.44.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c5d22c3bfc842668168a786af4205ec8e3ad29fb1bc03fd11fd48460d0df64c1"},
|
||||
{file = "llvmlite-0.44.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f01a394e9c9b7b1d4e63c327b096d10f6f0ed149ef53d38a09b3749dcf8c9610"},
|
||||
{file = "llvmlite-0.44.0-cp311-cp311-win_amd64.whl", hash = "sha256:d8489634d43c20cd0ad71330dde1d5bc7b9966937a263ff1ec1cebb90dc50955"},
|
||||
{file = "llvmlite-0.44.0-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:1d671a56acf725bf1b531d5ef76b86660a5ab8ef19bb6a46064a705c6ca80aad"},
|
||||
{file = "llvmlite-0.44.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5f79a728e0435493611c9f405168682bb75ffd1fbe6fc360733b850c80a026db"},
|
||||
{file = "llvmlite-0.44.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0143a5ef336da14deaa8ec26c5449ad5b6a2b564df82fcef4be040b9cacfea9"},
|
||||
{file = "llvmlite-0.44.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d752f89e31b66db6f8da06df8b39f9b91e78c5feea1bf9e8c1fba1d1c24c065d"},
|
||||
{file = "llvmlite-0.44.0-cp312-cp312-win_amd64.whl", hash = "sha256:eae7e2d4ca8f88f89d315b48c6b741dcb925d6a1042da694aa16ab3dd4cbd3a1"},
|
||||
{file = "llvmlite-0.44.0-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:319bddd44e5f71ae2689859b7203080716448a3cd1128fb144fe5c055219d516"},
|
||||
{file = "llvmlite-0.44.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9c58867118bad04a0bb22a2e0068c693719658105e40009ffe95c7000fcde88e"},
|
||||
{file = "llvmlite-0.44.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46224058b13c96af1365290bdfebe9a6264ae62fb79b2b55693deed11657a8bf"},
|
||||
{file = "llvmlite-0.44.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aa0097052c32bf721a4efc03bd109d335dfa57d9bffb3d4c24cc680711b8b4fc"},
|
||||
{file = "llvmlite-0.44.0-cp313-cp313-win_amd64.whl", hash = "sha256:2fb7c4f2fb86cbae6dca3db9ab203eeea0e22d73b99bc2341cdf9de93612e930"},
|
||||
{file = "llvmlite-0.44.0.tar.gz", hash = "sha256:07667d66a5d150abed9157ab6c0b9393c9356f229784a4385c02f99e94fc94d4"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "macholib"
|
||||
version = "1.16.3"
|
||||
@ -583,42 +614,77 @@ extra = ["lxml (>=4.6)", "pydot (>=3.0.1)", "pygraphviz (>=1.14)", "sympy (>=1.1
|
||||
test = ["pytest (>=7.2)", "pytest-cov (>=4.0)", "pytest-xdist (>=3.0)"]
|
||||
test-extras = ["pytest-mpl", "pytest-randomly"]
|
||||
|
||||
[[package]]
|
||||
name = "numba"
|
||||
version = "0.61.2"
|
||||
description = "compiling Python code using LLVM"
|
||||
optional = false
|
||||
python-versions = ">=3.10"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "numba-0.61.2-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:cf9f9fc00d6eca0c23fc840817ce9f439b9f03c8f03d6246c0e7f0cb15b7162a"},
|
||||
{file = "numba-0.61.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ea0247617edcb5dd61f6106a56255baab031acc4257bddaeddb3a1003b4ca3fd"},
|
||||
{file = "numba-0.61.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ae8c7a522c26215d5f62ebec436e3d341f7f590079245a2f1008dfd498cc1642"},
|
||||
{file = "numba-0.61.2-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:bd1e74609855aa43661edffca37346e4e8462f6903889917e9f41db40907daa2"},
|
||||
{file = "numba-0.61.2-cp310-cp310-win_amd64.whl", hash = "sha256:ae45830b129c6137294093b269ef0a22998ccc27bf7cf096ab8dcf7bca8946f9"},
|
||||
{file = "numba-0.61.2-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:efd3db391df53aaa5cfbee189b6c910a5b471488749fd6606c3f33fc984c2ae2"},
|
||||
{file = "numba-0.61.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:49c980e4171948ffebf6b9a2520ea81feed113c1f4890747ba7f59e74be84b1b"},
|
||||
{file = "numba-0.61.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3945615cd73c2c7eba2a85ccc9c1730c21cd3958bfcf5a44302abae0fb07bb60"},
|
||||
{file = "numba-0.61.2-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:bbfdf4eca202cebade0b7d43896978e146f39398909a42941c9303f82f403a18"},
|
||||
{file = "numba-0.61.2-cp311-cp311-win_amd64.whl", hash = "sha256:76bcec9f46259cedf888041b9886e257ae101c6268261b19fda8cfbc52bec9d1"},
|
||||
{file = "numba-0.61.2-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:34fba9406078bac7ab052efbf0d13939426c753ad72946baaa5bf9ae0ebb8dd2"},
|
||||
{file = "numba-0.61.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4ddce10009bc097b080fc96876d14c051cc0c7679e99de3e0af59014dab7dfe8"},
|
||||
{file = "numba-0.61.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5b1bb509d01f23d70325d3a5a0e237cbc9544dd50e50588bc581ba860c213546"},
|
||||
{file = "numba-0.61.2-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:48a53a3de8f8793526cbe330f2a39fe9a6638efcbf11bd63f3d2f9757ae345cd"},
|
||||
{file = "numba-0.61.2-cp312-cp312-win_amd64.whl", hash = "sha256:97cf4f12c728cf77c9c1d7c23707e4d8fb4632b46275f8f3397de33e5877af18"},
|
||||
{file = "numba-0.61.2-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:3a10a8fc9afac40b1eac55717cece1b8b1ac0b946f5065c89e00bde646b5b154"},
|
||||
{file = "numba-0.61.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7d3bcada3c9afba3bed413fba45845f2fb9cd0d2b27dd58a1be90257e293d140"},
|
||||
{file = "numba-0.61.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:bdbca73ad81fa196bd53dc12e3aaf1564ae036e0c125f237c7644fe64a4928ab"},
|
||||
{file = "numba-0.61.2-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:5f154aaea625fb32cfbe3b80c5456d514d416fcdf79733dd69c0df3a11348e9e"},
|
||||
{file = "numba-0.61.2-cp313-cp313-win_amd64.whl", hash = "sha256:59321215e2e0ac5fa928a8020ab00b8e57cda8a97384963ac0dfa4d4e6aa54e7"},
|
||||
{file = "numba-0.61.2.tar.gz", hash = "sha256:8750ee147940a6637b80ecf7f95062185ad8726c8c28a2295b8ec1160a196f7d"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
llvmlite = "==0.44.*"
|
||||
numpy = ">=1.24,<2.3"
|
||||
|
||||
[[package]]
|
||||
name = "numpy"
|
||||
version = "1.23.5"
|
||||
description = "NumPy is the fundamental package for array computing with Python."
|
||||
version = "1.24.4"
|
||||
description = "Fundamental package for array computing in Python"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "numpy-1.23.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9c88793f78fca17da0145455f0d7826bcb9f37da4764af27ac945488116efe63"},
|
||||
{file = "numpy-1.23.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e9f4c4e51567b616be64e05d517c79a8a22f3606499941d97bb76f2ca59f982d"},
|
||||
{file = "numpy-1.23.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7903ba8ab592b82014713c491f6c5d3a1cde5b4a3bf116404e08f5b52f6daf43"},
|
||||
{file = "numpy-1.23.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e05b1c973a9f858c74367553e236f287e749465f773328c8ef31abe18f691e1"},
|
||||
{file = "numpy-1.23.5-cp310-cp310-win32.whl", hash = "sha256:522e26bbf6377e4d76403826ed689c295b0b238f46c28a7251ab94716da0b280"},
|
||||
{file = "numpy-1.23.5-cp310-cp310-win_amd64.whl", hash = "sha256:dbee87b469018961d1ad79b1a5d50c0ae850000b639bcb1b694e9981083243b6"},
|
||||
{file = "numpy-1.23.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ce571367b6dfe60af04e04a1834ca2dc5f46004ac1cc756fb95319f64c095a96"},
|
||||
{file = "numpy-1.23.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:56e454c7833e94ec9769fa0f86e6ff8e42ee38ce0ce1fa4cbb747ea7e06d56aa"},
|
||||
{file = "numpy-1.23.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5039f55555e1eab31124a5768898c9e22c25a65c1e0037f4d7c495a45778c9f2"},
|
||||
{file = "numpy-1.23.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58f545efd1108e647604a1b5aa809591ccd2540f468a880bedb97247e72db387"},
|
||||
{file = "numpy-1.23.5-cp311-cp311-win32.whl", hash = "sha256:b2a9ab7c279c91974f756c84c365a669a887efa287365a8e2c418f8b3ba73fb0"},
|
||||
{file = "numpy-1.23.5-cp311-cp311-win_amd64.whl", hash = "sha256:0cbe9848fad08baf71de1a39e12d1b6310f1d5b2d0ea4de051058e6e1076852d"},
|
||||
{file = "numpy-1.23.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f063b69b090c9d918f9df0a12116029e274daf0181df392839661c4c7ec9018a"},
|
||||
{file = "numpy-1.23.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0aaee12d8883552fadfc41e96b4c82ee7d794949e2a7c3b3a7201e968c7ecab9"},
|
||||
{file = "numpy-1.23.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92c8c1e89a1f5028a4c6d9e3ccbe311b6ba53694811269b992c0b224269e2398"},
|
||||
{file = "numpy-1.23.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d208a0f8729f3fb790ed18a003f3a57895b989b40ea4dce4717e9cf4af62c6bb"},
|
||||
{file = "numpy-1.23.5-cp38-cp38-win32.whl", hash = "sha256:06005a2ef6014e9956c09ba07654f9837d9e26696a0470e42beedadb78c11b07"},
|
||||
{file = "numpy-1.23.5-cp38-cp38-win_amd64.whl", hash = "sha256:ca51fcfcc5f9354c45f400059e88bc09215fb71a48d3768fb80e357f3b457e1e"},
|
||||
{file = "numpy-1.23.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8969bfd28e85c81f3f94eb4a66bc2cf1dbdc5c18efc320af34bffc54d6b1e38f"},
|
||||
{file = "numpy-1.23.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a7ac231a08bb37f852849bbb387a20a57574a97cfc7b6cabb488a4fc8be176de"},
|
||||
{file = "numpy-1.23.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf837dc63ba5c06dc8797c398db1e223a466c7ece27a1f7b5232ba3466aafe3d"},
|
||||
{file = "numpy-1.23.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33161613d2269025873025b33e879825ec7b1d831317e68f4f2f0f84ed14c719"},
|
||||
{file = "numpy-1.23.5-cp39-cp39-win32.whl", hash = "sha256:af1da88f6bc3d2338ebbf0e22fe487821ea4d8e89053e25fa59d1d79786e7481"},
|
||||
{file = "numpy-1.23.5-cp39-cp39-win_amd64.whl", hash = "sha256:09b7847f7e83ca37c6e627682f145856de331049013853f344f37b0c9690e3df"},
|
||||
{file = "numpy-1.23.5-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:abdde9f795cf292fb9651ed48185503a2ff29be87770c3b8e2a14b0cd7aa16f8"},
|
||||
{file = "numpy-1.23.5-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9a909a8bae284d46bbfdefbdd4a262ba19d3bc9921b1e76126b1d21c3c34135"},
|
||||
{file = "numpy-1.23.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:01dd17cbb340bf0fc23981e52e1d18a9d4050792e8fb8363cecbf066a84b827d"},
|
||||
{file = "numpy-1.23.5.tar.gz", hash = "sha256:1b1766d6f397c18153d40015ddfc79ddb715cabadc04d2d228d4e5a8bc4ded1a"},
|
||||
{file = "numpy-1.24.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c0bfb52d2169d58c1cdb8cc1f16989101639b34c7d3ce60ed70b19c63eba0b64"},
|
||||
{file = "numpy-1.24.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ed094d4f0c177b1b8e7aa9cba7d6ceed51c0e569a5318ac0ca9a090680a6a1b1"},
|
||||
{file = "numpy-1.24.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79fc682a374c4a8ed08b331bef9c5f582585d1048fa6d80bc6c35bc384eee9b4"},
|
||||
{file = "numpy-1.24.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ffe43c74893dbf38c2b0a1f5428760a1a9c98285553c89e12d70a96a7f3a4d6"},
|
||||
{file = "numpy-1.24.4-cp310-cp310-win32.whl", hash = "sha256:4c21decb6ea94057331e111a5bed9a79d335658c27ce2adb580fb4d54f2ad9bc"},
|
||||
{file = "numpy-1.24.4-cp310-cp310-win_amd64.whl", hash = "sha256:b4bea75e47d9586d31e892a7401f76e909712a0fd510f58f5337bea9572c571e"},
|
||||
{file = "numpy-1.24.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f136bab9c2cfd8da131132c2cf6cc27331dd6fae65f95f69dcd4ae3c3639c810"},
|
||||
{file = "numpy-1.24.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e2926dac25b313635e4d6cf4dc4e51c8c0ebfed60b801c799ffc4c32bf3d1254"},
|
||||
{file = "numpy-1.24.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:222e40d0e2548690405b0b3c7b21d1169117391c2e82c378467ef9ab4c8f0da7"},
|
||||
{file = "numpy-1.24.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7215847ce88a85ce39baf9e89070cb860c98fdddacbaa6c0da3ffb31b3350bd5"},
|
||||
{file = "numpy-1.24.4-cp311-cp311-win32.whl", hash = "sha256:4979217d7de511a8d57f4b4b5b2b965f707768440c17cb70fbf254c4b225238d"},
|
||||
{file = "numpy-1.24.4-cp311-cp311-win_amd64.whl", hash = "sha256:b7b1fc9864d7d39e28f41d089bfd6353cb5f27ecd9905348c24187a768c79694"},
|
||||
{file = "numpy-1.24.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1452241c290f3e2a312c137a9999cdbf63f78864d63c79039bda65ee86943f61"},
|
||||
{file = "numpy-1.24.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:04640dab83f7c6c85abf9cd729c5b65f1ebd0ccf9de90b270cd61935eef0197f"},
|
||||
{file = "numpy-1.24.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5425b114831d1e77e4b5d812b69d11d962e104095a5b9c3b641a218abcc050e"},
|
||||
{file = "numpy-1.24.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd80e219fd4c71fc3699fc1dadac5dcf4fd882bfc6f7ec53d30fa197b8ee22dc"},
|
||||
{file = "numpy-1.24.4-cp38-cp38-win32.whl", hash = "sha256:4602244f345453db537be5314d3983dbf5834a9701b7723ec28923e2889e0bb2"},
|
||||
{file = "numpy-1.24.4-cp38-cp38-win_amd64.whl", hash = "sha256:692f2e0f55794943c5bfff12b3f56f99af76f902fc47487bdfe97856de51a706"},
|
||||
{file = "numpy-1.24.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2541312fbf09977f3b3ad449c4e5f4bb55d0dbf79226d7724211acc905049400"},
|
||||
{file = "numpy-1.24.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9667575fb6d13c95f1b36aca12c5ee3356bf001b714fc354eb5465ce1609e62f"},
|
||||
{file = "numpy-1.24.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3a86ed21e4f87050382c7bc96571755193c4c1392490744ac73d660e8f564a9"},
|
||||
{file = "numpy-1.24.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d11efb4dbecbdf22508d55e48d9c8384db795e1b7b51ea735289ff96613ff74d"},
|
||||
{file = "numpy-1.24.4-cp39-cp39-win32.whl", hash = "sha256:6620c0acd41dbcb368610bb2f4d83145674040025e5536954782467100aa8835"},
|
||||
{file = "numpy-1.24.4-cp39-cp39-win_amd64.whl", hash = "sha256:befe2bf740fd8373cf56149a5c23a0f601e82869598d41f8e188a0e9869926f8"},
|
||||
{file = "numpy-1.24.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:31f13e25b4e304632a4619d0e0777662c2ffea99fcae2029556b17d8ff958aef"},
|
||||
{file = "numpy-1.24.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95f7ac6540e95bc440ad77f56e520da5bf877f87dca58bd095288dce8940532a"},
|
||||
{file = "numpy-1.24.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:e98f220aa76ca2a977fe435f5b04d7b3470c0a2e6312907b37ba6068f26787f2"},
|
||||
{file = "numpy-1.24.4.tar.gz", hash = "sha256:80f5e3a4e498641401868df4208b74581206afbee7cf7b8329daae82676d9463"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1293,52 +1359,53 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
|
||||
|
||||
[[package]]
|
||||
name = "scikit-image"
|
||||
version = "0.24.0"
|
||||
version = "0.25.2"
|
||||
description = "Image processing in Python"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
python-versions = ">=3.10"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "scikit_image-0.24.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cb3bc0264b6ab30b43c4179ee6156bc18b4861e78bb329dd8d16537b7bbf827a"},
|
||||
{file = "scikit_image-0.24.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:9c7a52e20cdd760738da38564ba1fed7942b623c0317489af1a598a8dedf088b"},
|
||||
{file = "scikit_image-0.24.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:93f46e6ce42e5409f4d09ce1b0c7f80dd7e4373bcec635b6348b63e3c886eac8"},
|
||||
{file = "scikit_image-0.24.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39ee0af13435c57351a3397eb379e72164ff85161923eec0c38849fecf1b4764"},
|
||||
{file = "scikit_image-0.24.0-cp310-cp310-win_amd64.whl", hash = "sha256:7ac7913b028b8aa780ffae85922894a69e33d1c0bf270ea1774f382fe8bf95e7"},
|
||||
{file = "scikit_image-0.24.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:272909e02a59cea3ed4aa03739bb88df2625daa809f633f40b5053cf09241831"},
|
||||
{file = "scikit_image-0.24.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:190ebde80b4470fe8838764b9b15f232a964f1a20391663e31008d76f0c696f7"},
|
||||
{file = "scikit_image-0.24.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59c98cc695005faf2b79904e4663796c977af22586ddf1b12d6af2fa22842dc2"},
|
||||
{file = "scikit_image-0.24.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa27b3a0dbad807b966b8db2d78da734cb812ca4787f7fbb143764800ce2fa9c"},
|
||||
{file = "scikit_image-0.24.0-cp311-cp311-win_amd64.whl", hash = "sha256:dacf591ac0c272a111181afad4b788a27fe70d213cfddd631d151cbc34f8ca2c"},
|
||||
{file = "scikit_image-0.24.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6fccceb54c9574590abcddc8caf6cefa57c13b5b8b4260ab3ff88ad8f3c252b3"},
|
||||
{file = "scikit_image-0.24.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:ccc01e4760d655aab7601c1ba7aa4ddd8b46f494ac46ec9c268df6f33ccddf4c"},
|
||||
{file = "scikit_image-0.24.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18836a18d3a7b6aca5376a2d805f0045826bc6c9fc85331659c33b4813e0b563"},
|
||||
{file = "scikit_image-0.24.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8579bda9c3f78cb3b3ed8b9425213c53a25fa7e994b7ac01f2440b395babf660"},
|
||||
{file = "scikit_image-0.24.0-cp312-cp312-win_amd64.whl", hash = "sha256:82ab903afa60b2da1da2e6f0c8c65e7c8868c60a869464c41971da929b3e82bc"},
|
||||
{file = "scikit_image-0.24.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ef04360eda372ee5cd60aebe9be91258639c86ae2ea24093fb9182118008d009"},
|
||||
{file = "scikit_image-0.24.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:e9aadb442360a7e76f0c5c9d105f79a83d6df0e01e431bd1d5757e2c5871a1f3"},
|
||||
{file = "scikit_image-0.24.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e37de6f4c1abcf794e13c258dc9b7d385d5be868441de11c180363824192ff7"},
|
||||
{file = "scikit_image-0.24.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4688c18bd7ec33c08d7bf0fd19549be246d90d5f2c1d795a89986629af0a1e83"},
|
||||
{file = "scikit_image-0.24.0-cp39-cp39-win_amd64.whl", hash = "sha256:56dab751d20b25d5d3985e95c9b4e975f55573554bd76b0aedf5875217c93e69"},
|
||||
{file = "scikit_image-0.24.0.tar.gz", hash = "sha256:5d16efe95da8edbeb363e0c4157b99becbd650a60b77f6e3af5768b66cf007ab"},
|
||||
{file = "scikit_image-0.25.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d3278f586793176599df6a4cf48cb6beadae35c31e58dc01a98023af3dc31c78"},
|
||||
{file = "scikit_image-0.25.2-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:5c311069899ce757d7dbf1d03e32acb38bb06153236ae77fcd820fd62044c063"},
|
||||
{file = "scikit_image-0.25.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be455aa7039a6afa54e84f9e38293733a2622b8c2fb3362b822d459cc5605e99"},
|
||||
{file = "scikit_image-0.25.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a4c464b90e978d137330be433df4e76d92ad3c5f46a22f159520ce0fdbea8a09"},
|
||||
{file = "scikit_image-0.25.2-cp310-cp310-win_amd64.whl", hash = "sha256:60516257c5a2d2f74387c502aa2f15a0ef3498fbeaa749f730ab18f0a40fd054"},
|
||||
{file = "scikit_image-0.25.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f4bac9196fb80d37567316581c6060763b0f4893d3aca34a9ede3825bc035b17"},
|
||||
{file = "scikit_image-0.25.2-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:d989d64ff92e0c6c0f2018c7495a5b20e2451839299a018e0e5108b2680f71e0"},
|
||||
{file = "scikit_image-0.25.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2cfc96b27afe9a05bc92f8c6235321d3a66499995675b27415e0d0c76625173"},
|
||||
{file = "scikit_image-0.25.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24cc986e1f4187a12aa319f777b36008764e856e5013666a4a83f8df083c2641"},
|
||||
{file = "scikit_image-0.25.2-cp311-cp311-win_amd64.whl", hash = "sha256:b4f6b61fc2db6340696afe3db6b26e0356911529f5f6aee8c322aa5157490c9b"},
|
||||
{file = "scikit_image-0.25.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:8db8dd03663112783221bf01ccfc9512d1cc50ac9b5b0fe8f4023967564719fb"},
|
||||
{file = "scikit_image-0.25.2-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:483bd8cc10c3d8a7a37fae36dfa5b21e239bd4ee121d91cad1f81bba10cfb0ed"},
|
||||
{file = "scikit_image-0.25.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d1e80107bcf2bf1291acfc0bf0425dceb8890abe9f38d8e94e23497cbf7ee0d"},
|
||||
{file = "scikit_image-0.25.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a17e17eb8562660cc0d31bb55643a4da996a81944b82c54805c91b3fe66f4824"},
|
||||
{file = "scikit_image-0.25.2-cp312-cp312-win_amd64.whl", hash = "sha256:bdd2b8c1de0849964dbc54037f36b4e9420157e67e45a8709a80d727f52c7da2"},
|
||||
{file = "scikit_image-0.25.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7efa888130f6c548ec0439b1a7ed7295bc10105458a421e9bf739b457730b6da"},
|
||||
{file = "scikit_image-0.25.2-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:dd8011efe69c3641920614d550f5505f83658fe33581e49bed86feab43a180fc"},
|
||||
{file = "scikit_image-0.25.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28182a9d3e2ce3c2e251383bdda68f8d88d9fff1a3ebe1eb61206595c9773341"},
|
||||
{file = "scikit_image-0.25.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8abd3c805ce6944b941cfed0406d88faeb19bab3ed3d4b50187af55cf24d147"},
|
||||
{file = "scikit_image-0.25.2-cp313-cp313-win_amd64.whl", hash = "sha256:64785a8acefee460ec49a354706db0b09d1f325674107d7fa3eadb663fb56d6f"},
|
||||
{file = "scikit_image-0.25.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:330d061bd107d12f8d68f1d611ae27b3b813b8cdb0300a71d07b1379178dd4cd"},
|
||||
{file = "scikit_image-0.25.2.tar.gz", hash = "sha256:e5a37e6cd4d0c018a7a55b9d601357e3382826d3888c10d0213fc63bff977dde"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
imageio = ">=2.33"
|
||||
imageio = ">=2.33,<2.35.0 || >2.35.0"
|
||||
lazy-loader = ">=0.4"
|
||||
networkx = ">=2.8"
|
||||
numpy = ">=1.23"
|
||||
networkx = ">=3.0"
|
||||
numpy = ">=1.24"
|
||||
packaging = ">=21"
|
||||
pillow = ">=9.1"
|
||||
scipy = ">=1.9"
|
||||
pillow = ">=10.1"
|
||||
scipy = ">=1.11.4"
|
||||
tifffile = ">=2022.8.12"
|
||||
|
||||
[package.extras]
|
||||
build = ["Cython (>=3.0.4)", "build", "meson-python (>=0.15)", "ninja", "numpy (>=2.0.0rc1)", "packaging (>=21)", "pythran", "setuptools (>=67)", "spin (==0.8)", "wheel"]
|
||||
build = ["Cython (>=3.0.8)", "build (>=1.2.1)", "meson-python (>=0.16)", "ninja (>=1.11.1.1)", "numpy (>=2.0)", "pythran (>=0.16)", "spin (==0.13)"]
|
||||
data = ["pooch (>=1.6.0)"]
|
||||
developer = ["ipython", "pre-commit", "tomli ; python_version < \"3.11\""]
|
||||
docs = ["PyWavelets (>=1.1.1)", "dask[array] (>=2022.9.2)", "ipykernel", "ipywidgets", "kaleido", "matplotlib (>=3.6)", "myst-parser", "numpydoc (>=1.7)", "pandas (>=1.5)", "plotly (>=5.10)", "pooch (>=1.6)", "pydata-sphinx-theme (>=0.15.2)", "pytest-doctestplus", "pytest-runner", "scikit-learn (>=1.1)", "seaborn (>=0.11)", "sphinx (>=7.3)", "sphinx-copybutton", "sphinx-gallery (>=0.14)", "sphinx_design (>=0.5)", "tifffile (>=2022.8.12)"]
|
||||
optional = ["PyWavelets (>=1.1.1)", "SimpleITK", "astropy (>=5.0)", "cloudpickle (>=0.2.1)", "dask[array] (>=2021.1.0)", "matplotlib (>=3.6)", "pooch (>=1.6.0)", "pyamg", "scikit-learn (>=1.1)"]
|
||||
test = ["asv", "numpydoc (>=1.7)", "pooch (>=1.6.0)", "pytest (>=7.0)", "pytest-cov (>=2.11.0)", "pytest-doctestplus", "pytest-faulthandler", "pytest-localserver"]
|
||||
docs = ["PyWavelets (>=1.6)", "dask[array] (>=2023.2.0)", "intersphinx-registry (>=0.2411.14)", "ipykernel", "ipywidgets", "kaleido (==0.2.1)", "matplotlib (>=3.7)", "myst-parser", "numpydoc (>=1.7)", "pandas (>=2.0)", "plotly (>=5.20)", "pooch (>=1.6)", "pydata-sphinx-theme (>=0.16)", "pytest-doctestplus", "scikit-learn (>=1.2)", "seaborn (>=0.11)", "sphinx (>=8.0)", "sphinx-copybutton", "sphinx-gallery[parallel] (>=0.18)", "sphinx_design (>=0.5)", "tifffile (>=2022.8.12)"]
|
||||
optional = ["PyWavelets (>=1.6)", "SimpleITK", "astropy (>=5.0)", "cloudpickle (>=1.1.1)", "dask[array] (>=2023.2.0)", "matplotlib (>=3.7)", "pooch (>=1.6.0)", "pyamg (>=5.2)", "scikit-learn (>=1.2)"]
|
||||
test = ["asv", "numpydoc (>=1.7)", "pooch (>=1.6.0)", "pytest (>=8)", "pytest-cov (>=2.11.0)", "pytest-doctestplus", "pytest-faulthandler", "pytest-localserver"]
|
||||
|
||||
[[package]]
|
||||
name = "scipy"
|
||||
@ -1599,4 +1666,4 @@ files = [
|
||||
[metadata]
|
||||
lock-version = "2.1"
|
||||
python-versions = "~3.11.0"
|
||||
content-hash = "7ffb992ec99af574f2c8cba03a0ba54fda04d7d691b8920a8f30adf465050ff2"
|
||||
content-hash = "2c1cc120973c6c14fee04467811aa33c9ec374cf4c5415e7ca41ac8faa07005f"
|
||||
|
@ -11,7 +11,7 @@ python = "~3.11.0"
|
||||
python-osc = "^1.8.0"
|
||||
requests = "^2.28.1"
|
||||
opencv-python = "~4.6.0.66"
|
||||
numpy = "~1.23.5"
|
||||
numpy = "~1.24.0"
|
||||
pye3d = "^0.3.2"
|
||||
pysimplegui-4-foss = "^4.6.4.1"
|
||||
pydantic = "^2.4.2"
|
||||
@ -25,6 +25,7 @@ colorama = "^0.4.6"
|
||||
taskipy = "^1.10.4"
|
||||
pytest = "^8.0.0"
|
||||
pytest-cov = "^4.1.0"
|
||||
numba = "^0.61.2"
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
black = "^22.10.0"
|
||||
|
Loading…
Reference in New Issue
Block a user