Omnibus's picture
Update image_stitching/stitcher.py
eba226d
import logging
import cv2
import numpy
from .combine import combine_images
from .combine import compute_matches
__doc__ = '''ImageStitcher class for combining all images together'''
class ImageStitcher:
__doc__ = '''ImageStitcher class for combining all images together'''
def __init__(self, min_num: int = 10, lowe: float = 0.7, knn_clusters: int = 2):
'''constructor that initialises the SIFT class and Flann matcher'''
self.min_num = min_num
self.lowe = lowe
self.knn_clusters = knn_clusters
self.flann = cv2.FlannBasedMatcher({'algorithm': 0, 'trees': 5}, {'checks': 50})
self.sift = cv2.SIFT_create()
self.result_image = None
self.result_image_gray = None
def add_image(self, image: numpy.ndarray):
'''
this adds a new image to the stitched image by
running feature extraction and matching them
'''
assert image.ndim == 3, 'must be an image!'
assert image.shape[-1] == 3, 'must be BGR!'
assert image.dtype == numpy.uint8, 'must be a uint8'
image_gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
if self.result_image is None:
self.result_image = image
self.result_image_gray = image_gray
return
# todo(will.brennan) - stop computing features on the results image each time!
result_features = self.sift.detectAndCompute(self.result_image_gray, None)
image_features = self.sift.detectAndCompute(image_gray, None)
matches_src, matches_dst, n_matches = compute_matches(result_features,
image_features,
matcher=self.flann,
knn=self.knn_clusters,
lowe=self.lowe)
if n_matches < self.min_num:
logging.warning('too few correspondences to add image to stitched image')
return
logging.debug('computing homography between accumulated and new images')
homography, _ = cv2.findHomography(matches_src, matches_dst, cv2.RANSAC, 5.0)
logging.debug('stitching images together')
#print (f"self.result_image Pre:: {self.result_image}")
self.result_image = combine_images(image, self.result_image, homography)
#print (f"self.result_image Combine:: {self.result_image}")
self.result_image_gray = cv2.cvtColor(self.result_image, cv2.COLOR_RGB2GRAY)
def image(self):
'''class for fetching the stitched image'''
return self.result_image