Source code for openalea.phenomenal.calibration.chessboard

# -*- python -*-
#
#       Copyright INRIA - CIRAD - INRA
#
#       Distributed under the Cecill-C License.
#       See accompanying file LICENSE.txt or copy at
#           http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.html
#
# ==============================================================================
from __future__ import division, print_function, absolute_import

import cv2
import numpy
import json
import collections
# ==============================================================================

__all__ = ["Target", "Chessboard"]

# ==============================================================================


[docs]class Target(object):
[docs] def __init__(self): self.image_points = collections.defaultdict(dict)
def add_image_points(self, camera_view, angle, image): pass def get_3d_local_points(self): pass def get_image_points(self): pass
[docs]class Chessboard(object):
[docs] def __init__(self, square_size=50, shape=(7, 7)): self.square_size = square_size self.shape = shape self.image_points = collections.defaultdict(dict)
def __str__(self): s = ("Chessboard Attributes :\n" "Square size (mm): {}\n" "Shape : {}\n".format(self.square_size, self.shape)) return s def get_corners_local_3d(self): square_size = self.square_size width, height = self.shape corners_local_3d = list() for y in range(height): for x in range(width): v = numpy.array([x * square_size, y * square_size, 0.0]) corners_local_3d.append(v) return corners_local_3d def get_corners_2d(self, id_camera): corners_2d = dict() for angle in self.image_points[id_camera]: corners_2d[angle] = self.image_points[id_camera][angle][:, 0, :] return corners_2d def detect_corners(self, id_camera, angle, image): """ Detect chessboard corner in a image and save it in object with the id_camera and angle like keys. :param id_camera: id/label/name_key of the camera who take the picture :param angle: Angle of chessboard on the turnable platform :param image: numpy GRAYSCALE Image containing the chessboard target :return: True if chessboard corner are found otherwise False. """ if len(image.shape) == 3: image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) try: found, corners = cv2.findChessboardCorners( image, tuple(self.shape), flags=cv2.CALIB_CB_ADAPTIVE_THRESH + cv2.CALIB_CB_NORMALIZE_IMAGE) if found: cv2.cornerSubPix( image, corners, (11, 11), (-1, -1), criteria=(cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)) self.image_points[id_camera][angle] = corners except cv2.error: return False return found def dump(self, filename): # Convert to json format image_points = collections.defaultdict(dict) for id_camera in self.image_points: for angle in self.image_points[id_camera]: image_points[id_camera][angle] = \ self.image_points[id_camera][angle].tolist() save_class = dict() save_class['square_size'] = self.square_size save_class['shape'] = self.shape save_class['image_points'] = image_points with open(filename, 'w') as output_file: json.dump(save_class, output_file, sort_keys=True, indent=4, separators=(',', ': ')) @staticmethod def load(filename): with open(filename, 'r') as input_file: save_class = json.load(input_file) square_size = float(save_class['square_size']) shape = [int(val) for val in save_class['shape']] chessboard = Chessboard(square_size, shape) image_points = save_class['image_points'] # Convert to numpy format for id_camera in image_points: for angle in image_points[id_camera]: chessboard.image_points[id_camera][float(angle)] = \ numpy.array(image_points[id_camera][angle]).astype( numpy.float) return chessboard