Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

Generalizable detector + descriptor combos

Đang mở
#50 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
5/5
Thời gian dự kiến
Hơn một tuần
Mức phù hợp với người mới
25/100
Loại issue
Tính năng
Độ rõ ràng
Cần làm rõ
Mức độ hoạt động
Ít trao đổi
Công nghệ
python
Lĩnh vực
computer-vision

Hướng nghiên cứu

Issue đề xuất một abstraction FeaturePipeline mới xoay quanh các component detector và descriptor, sử dụng behavior của cv2.Feature2D và các algorithm kết hợp như SIFT hoặc ORB. Không xác định được file hay test nào trong repository, vì vậy trước tiên hãy tìm các entry point hiện có cho việc trích xuất feature và xác định các kết hợp detector-descriptor hiện đang được biểu diễn như thế nào. Hoàn thành cần bao gồm một API được định nghĩa cho các algorithm kết hợp native và các cặp detector-descriptor riêng biệt, cùng với coverage cho các pattern sử dụng đã nêu.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

tech-debt

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.

Ngôn ngữ chính
Python
Star
223
Fork
30
Merge trung bình
1 ngày 7 giờ
Pull request đã merge (30 ngày)
18

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của petercorke/machinevision-toolbox-python

Tất cả issue của petercorke/machinevision-toolbox-python

Issue tương tự

Thêm issue về Python

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.