Source code for sksurgeryimage.calibration.chessboard_point_detector

# coding=utf-8

"""
Chessboard implementation of PointDetector.
"""

import logging
import copy
import cv2
import numpy as np
from sksurgeryimage.calibration.point_detector import PointDetector

LOGGER = logging.getLogger(__name__)


[docs]class ChessboardPointDetector(PointDetector): """ Class to detect chessboard points in a 2D grey scale video image. """ def __init__(self, number_of_corners, square_size_in_mm, scale=(1, 1)): """ Constructs a ChessboardPointDetector. :param number_of_corners: tuple of (number in x, number in y) :param square_size_in_mm: physical size of chessboard squares in mm :param scale: if you want to resize the image, specify scale factors """ super(ChessboardPointDetector, self).__init__(scale=scale) self.number_of_corners = number_of_corners self.number_in_x, self.number_in_y = self.number_of_corners self.expected_number_of_points = self.number_in_x * self.number_in_y self.square_size_in_mm = square_size_in_mm self.object_points = np.zeros((self.expected_number_of_points, 3)) self.ids = np.zeros((self.expected_number_of_points, 1), dtype=np.int16) for i in range(0, self.expected_number_of_points): self.object_points[i][0] = (i % self.number_in_x) \ * self.square_size_in_mm self.object_points[i][1] = (i // self.number_in_x) \ * self.square_size_in_mm self.object_points[i][2] = 0 self.ids[i][0] = i def _internal_get_points(self, image, is_distorted=True): """ Extracts points using OpenCV's chessboard implementation. :param image: numpy 2D grey scale image. :return: ids, object_points, image_points as Nx[1,3,2] ndarrays """ img_points = np.zeros((0, 2)) detection_criteria = cv2.CALIB_CB_ADAPTIVE_THRESH\ + cv2.CALIB_CB_FILTER_QUADS ret, corners = cv2.findChessboardCorners(image, self.number_of_corners, detection_criteria) optimisation_criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001) if ret: img_points = cv2.cornerSubPix(image, corners, (11, 11), (-1, -1), optimisation_criteria ) # If successful, we return all ids, 3D points and 2D points. return copy.deepcopy(self.ids), \ copy.deepcopy(self.object_points), \ img_points.squeeze() # If we didn't find all points, return consistent set of 'nothing' return np.zeros((0, 1)), np.zeros((0, 3)), img_points
[docs] def get_model_points(self): """ Returns a [Nx3] numpy ndarray representing the model points in 3D. """ return copy.deepcopy(self.object_points)