Generalizable detector + descriptor combos
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 5/5
- Tiempo estimado
- Más de una semana
- Aptitud para principiantes
- 25/100
- Tipo de issue
- Nueva funcionalidad
- Claridad
- Necesita aclaración
- Estado de actividad
- Tranquilo
- Stack tecnológico
- python
- Área
- computer-vision
Línea de trabajo
El issue propone una nueva abstracción FeaturePipeline en torno a componentes detector y descriptor, utilizando el comportamiento de cv2.Feature2D y algoritmos combinados como SIFT u ORB. No se identifican archivos ni pruebas del repositorio, por lo que primero hay que localizar los puntos de entrada existentes para la extracción de características y determinar cómo se representan actualmente las combinaciones detector-descriptor. La finalización debe incluir una API definida para algoritmos combinados nativos y pares detector-descriptor separados, con cobertura para los patrones de uso indicados.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
This has been on the Wishlist for a while. Here's a Gemini idea:
To achieve true polymorphism where any detector $X$ can be cleanly paired with any descriptor $Y$—while also seamlessly supporting combined algorithms (like SIFT or ORB) that handle both natively—you can implement a unified interface layer.
The primary challenge with OpenCV's underlying structure is that everything inherits from cv2.Feature2D in C++, but in Python, the objects are functionally asymmetric: "Detector-only" objects lack .compute(), "Descriptor-only" objects lack .detect(), and combined frameworks implement everything plus .detectAndCompute().
An elegant way to handle this in Python is to treat the Pipeline itself as the polymorphic interface, using a lightweight structural wrapper or duck-typed composition.
Here is a clean, robust architecture that provides a unified API for any combination.
The Polymorphic Pipeline Architecture
By creating a unified container class, you can abstract away whether the underlying execution runs a combined native method or executes two distinct, mismatched components sequentially.
from typing import Protocol, Tuple, Optional, Any
import cv2
import numpy as np
class FeaturePipeline:
"""
A polymorphic wrapper that pairs any keypoint detector with any
feature descriptor, or wraps a single unified extraction algorithm.
"""
def __init__(self, detector: Any, descriptor: Optional[Any] = None):
self.detector = detector
# If no distinct descriptor is provided, assume the detector handles both
self.descriptor = descriptor if descriptor is not None else detector
def detect(self, image: np.ndarray, mask: Optional[np.ndarray] = None) -> list:
"""Extract only the keypoints from an image."""
if hasattr(self.detector, 'detect'):
return self.detector.detect(image, mask)
elif hasattr(self.detector, 'detectAndCompute'):
kp, _ = self.detector.detectAndCompute(image, mask)
return kp
else:
raise AttributeError(f"The configured detector {type(self.detector).__name__} cannot detect keypoints standalone.")
def compute(self, image: np.ndarray, keypoints: list) -> Tuple[list, np.ndarray]:
"""Compute descriptors for a pre-existing list of keypoints."""
if hasattr(self.descriptor, 'compute'):
return self.descriptor.compute(image, keypoints)
else:
raise AttributeError(f"The configured descriptor {type(self.descriptor).__name__} cannot compute descriptors.")
def extract(self, image: np.ndarray, mask: Optional[np.ndarray] = None) -> Tuple[list, np.ndarray]:
"""
Polymorphically extracts both keypoints and descriptors.
Optimises for combined algorithms if available.
"""
# Case 1: Unified native algorithm (e.g., SIFT, ORB)
if self.detector is self.descriptor and hasattr(self.detector, 'detectAndCompute'):
return self.detector.detectAndCompute(image, mask)
# Case 2: Mix-and-match sequential execution (e.g., FAST + FREAK)
keypoints = self.detect(image, mask)
return self.compute(image, keypoints)
How this Solves Polymorphism
This structure allows your client code to treat every single feature extraction mechanism identically, completely removing conditional checks (if isinstance(...)) from your core tracking loops.
1. Using a Native Combined Pair
# SIFT handles both detection and description internally
sift_pipeline = FeaturePipeline(cv2.SIFT_create())
kp, des = sift_pipeline.extract(img)
2. Using a Mix-and-Match Pair
# FAST handles detection, FREAK handles description
fast_freak_pipeline = FeaturePipeline(
detector=cv2.FastFeatureDetector_create(),
descriptor=cv2.xfeatures2d.FREAK_create()
)
kp, des = fast_freak_pipeline.extract(img)
3. Reusing Coordinates for tracking
# Detect features once, then compute them across sequential frames
initial_kp = fast_freak_pipeline.detect(frame_1)
kp_1, des_1 = fast_freak_pipeline.compute(frame_1, initial_kp)
kp_2, des_2 = fast_freak_pipeline.compute(frame_2, initial_kp)
Type Enforcement (Optional Extension)
If you want explicit structural typing flags to catch setup errors before runtime, you can define lightweight Protocol classes to act as interfaces for the sub-components:
from typing import Protocol, runtime_checkable
@runtime_checkable
class DetectorComponent(Protocol):
def detect(self, image: np.ndarray, mask: Optional[np.ndarray] = None) -> list: ...
@runtime_checkable
class DescriptorComponent(Protocol):
def compute(self, image: np.ndarray, keypoints: list) -> Tuple[list, np.ndarray]: ...
By initializing with this approach, the runtime environment doesn't care where the underlying binary resides (core vs. contrib), as long as the bound object satisfies the duck-typed interface behavior.
- Lenguaje dominante
- Python
- Estrellas
- 223
- Forks
- 30
- Merge medio
- 1 h 4 min
- PR fusionados (30 d)
- 9
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de petercorke/machinevision-toolbox-python
-
enhancement
Dificultad 2/5 1-3 horas Aptitud para principiantes 25/100
petercorke/machinevision-toolbox-python#125 ·
Los mantenedores suelen responder en 1 día
-
tech-debt
Dificultad 5/5 Más de una semana Aptitud para principiantes 25/100
petercorke/machinevision-toolbox-python#122 ·
Los mantenedores suelen responder en 1 día
-
tech-debt
Dificultad 5/5 Más de una semana Aptitud para principiantes 25/100
petercorke/machinevision-toolbox-python#119 ·
Los mantenedores suelen responder en 1 día
-
tech-debt
Dificultad 5/5 Más de una semana Aptitud para principiantes 30/100
petercorke/machinevision-toolbox-python#117 ·
Los mantenedores suelen responder en 1 día
-
Remaining bare `except:` / swallowed exceptions in tests/ and src/ (Codacy + hidden failures)Abiertotech-debt
Dificultad 5/5 Más de una semana Aptitud para principiantes 45/100
petercorke/machinevision-toolbox-python#115 ·
Los mantenedores suelen responder en 1 día
Todos los issues de petercorke/machinevision-toolbox-python
Issues similares
-
enhancement good first issue
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
-
Update Python support to 3.15Abiertopython-version
Dificultad 1/5 Menos de una hora Aptitud para principiantes 88/100
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
Los mantenedores suelen responder en 1 día
-
bug javascript P2-medium python release:v3.1
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
adrirubio/claude-deck#546 ·
Los mantenedores suelen responder en 1 día
-
area: desktop area: website priority: P2 type: feature
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
appandflow/stim#3411 · 1 comentario ·
Los mantenedores suelen responder en 1 día