Source code for ewoksndreg.features.mapping.scikitimage_backend
from typing import Callable
from typing import Dict
from typing import Optional
from typing import Sequence
import numpy
from skimage.measure import ransac
from ...transformation import TransformationType
from ...transformation.numpy_backend import NumpyHomography
from ...transformation.scikitimage_backend import AffineTransform
from ...transformation.scikitimage_backend import EuclideanTransform
from ...transformation.scikitimage_backend import ProjectiveTransform
from ...transformation.scikitimage_backend import ShiftTransform
from ...transformation.scikitimage_backend import SimilarityTransform
from ..detection.base import Features
from .base import FeatureMapping
__all__ = ["SciKitImageRansacFeatureMapping"]
[docs]
class SciKitImageRansacFeatureMapping(
FeatureMapping, registry_id=FeatureMapping.RegistryId("Ransac", "SciKitImage")
):
def __init__(
self, transfo_type: TransformationType, solve_options: Optional[Dict] = None
) -> None:
if solve_options is None:
solve_options = dict()
solve_options.setdefault("min_samples", 8)
solve_options.setdefault("residual_threshold", 2)
solve_options.setdefault("max_trials", 100)
super().__init__(transfo_type)
self._solver = get_ransac_solver(self._transfo_type, **solve_options)
[docs]
def calculate(
self, from_features: Features, to_features: Features
) -> NumpyHomography:
passive_matrix = self._solver(
to_features.coordinates, from_features.coordinates
)
return NumpyHomography(passive_matrix, self._transfo_type)
[docs]
def identity(self) -> NumpyHomography:
return NumpyHomography(numpy.identity(3), TransformationType.identity)
[docs]
def get_ransac_solver(
transfo_type: TransformationType, **solve_options
) -> Callable[[Sequence[numpy.ndarray], Sequence[numpy.ndarray]], numpy.ndarray]:
transfo_type = TransformationType(transfo_type)
if transfo_type == transfo_type.translation:
model_classobject = ShiftTransform
elif transfo_type == transfo_type.rigid:
model_classobject = EuclideanTransform
elif transfo_type == transfo_type.similarity:
model_classobject = SimilarityTransform
elif transfo_type == transfo_type.affine:
model_classobject = AffineTransform
elif transfo_type == transfo_type.projective:
model_classobject = ProjectiveTransform
else:
raise ValueError(f"No ransac solver found for {transfo_type}")
def ransac_wapper(
from_coord: Sequence[numpy.ndarray], to_coord: Sequence[numpy.ndarray]
) -> numpy.ndarray:
src = numpy.asarray(from_coord).T
dst = numpy.asarray(to_coord).T
tr, inliers = ransac((src, dst), model_classobject, **solve_options)
return tr.params
return ransac_wapper