def deserialize_hdf5(cls, h5py_group):
        model_str = h5py_group['serialized_model'][()]
        model = iiboost.Booster()
        model.deserialize(model_str)

        known_labels = list(h5py_group['known_labels'][:])
        feature_count = h5py_group['feature_count'][()]
        return IIBoostLazyflowClassifier(model, known_labels, feature_count)
    def create_and_train_pixelwise(self,
                                   feature_images,
                                   label_images,
                                   axistags=None,
                                   feature_names=None):
        """
        feature_images: A sequence of ND images.  See note above regarding required structure.  
                        Last axis must be channel.
        label_images: A sequence of ND label images.  Last axis must be channel (size=1).
        axistags: Optional.  A vigra.AxisTags object describing ALL feature_images.
                  (Used to compute the anisotropy of the data.)
        """
        logger.debug('training with IIBoost')

        # Instantiate the classifier
        model = iiboost.Booster()

        # IIBoost requires both labels to be uint8, 3D only
        converted_labels = []
        for label_image in label_images:
            assert len(
                label_image.shape
            ) == 4, "IIBoost expects 4D data (including channel dimension)."
            assert label_image.shape[
                -1] == 1, "Expected label image to have only one channel."
            converted = numpy.array(
                numpy.asarray(label_image[..., 0], dtype=numpy.uint8))
            converted_labels.append(converted)

        # Save for future reference
        flattened_labels = map(numpy.ndarray.flatten, converted_labels)
        all_labels = numpy.concatenate(flattened_labels)
        known_labels = numpy.unique(all_labels)
        if known_labels[0] == 0:
            known_labels = known_labels[1:]

        assert set([1, 2]).issuperset(
            known_labels), "IIBoost only accepts two label values: 1 and 2"

        # We can't train if there not labels from both classes.
        if set(known_labels) != set([1, 2]):
            return None

        # IIBoost requires raw images to be uint8, 3D only
        # NOTE: we assume that the raw data can be found in channel 0.
        raw_images = []
        for image in feature_images:
            assert len(image.shape
                       ) == 4, "IIBoost expects 4D data (including channel)."
            # (Even though copy=False here, we'll probably get a copy anyway. That's fine. Same for cases below, too.)
            raw = image[..., 0].astype(dtype=numpy.uint8,
                                       order='C',
                                       copy=False)
            raw_images.append(raw)

        # Extract the hessian eigenvector (hev) images
        hev_images = []
        for image in feature_images:
            hev_image = image[..., 1:10]
            hev_image = hev_image.astype(dtype=numpy.float32,
                                         order='C',
                                         copy=False)
            hev_image = hev_image.reshape(hev_image.shape[:-1] + (3, 3))
            hev_images.append(hev_image)

        integral_images = []
        for image in feature_images:
            assert len(
                image.shape
            ) == 4, "IIBoost expects 4D data (including channel dimension)."

            # Select integral channels (see note above about input data)
            integral_image = image[..., 10:]

            # Put channel first
            integral_image = integral_image.transpose(3, 0, 1, 2)

            # IIBoost requires filter images to be float32, in C-order
            integral_image = integral_image.astype(dtype=numpy.float32,
                                                   copy=False,
                                                   order='C')

            integral_images.append(integral_image)

        # Calculate anisotropy factor.
        z_anisotropy_factor = 1.0
        if axistags:
            x_tag = axistags['x']
            z_tag = axistags['z']
            if z_tag.resolution != 0.0 and x_tag.resolution != 0.0:
                z_anisotropy_factor = z_tag.resolution / x_tag.resolution

        model.trainWithChannels(raw_images, hev_images, converted_labels,
                                integral_images, z_anisotropy_factor,
                                self.num_stumps, *self._args, **self._kwargs)

        return IIBoostLazyflowClassifier(model,
                                         known_labels,
                                         feature_count=len(integral_images[0]),
                                         feature_names=feature_names)