Source code for openalea.phenomenal.image.morphology

# -*- 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
#
# ==============================================================================
"""
Post-processing algorithms to improve binarization of an image
"""

# ==============================================================================
from __future__ import division, print_function

import numpy
import skimage


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


[docs] def dilate_erode(binary_image, kernel_shape=(2, 2), iterations=1, mask=None): """ Applied a morphology (dilate & erode) on binary_image on a ROI. Parameters ---------- binary_image : numpy.ndarray 2-D array kernel_shape: (N, M) of integers, optional kernel shape of (dilate & erode) applied to binary_image iterations: int, optional number of successive iteration of (dilate & erode) mask : numpy.ndarray, optional Array of same shape as `image`. Only points at which mask == True will be processed. Returns ------- out : numpy.ndarray Binary Image """ # ========================================================================== # Check Parameters if not isinstance(binary_image, numpy.ndarray): raise TypeError("binary_image must be a numpy.ndarray") if binary_image.ndim != 2: raise ValueError("image must be 2D array") if mask is not None: if not isinstance(mask, numpy.ndarray): raise TypeError("mask must be a numpy.ndarray") if mask.ndim != 2: raise ValueError("mask must be 2D array") # ========================================================================== if mask is not None: out = numpy.bitwise_and(binary_image, mask) else: out = binary_image.copy() element = numpy.pad(numpy.array([[0, 1, 0], [1, 1, 1], [0, 1, 0]]), kernel_shape) for _ in range(iterations): out = skimage.morphology.dilation(out, element) for _ in range(iterations): out = skimage.morphology.erosion(out, element) if mask is not None: res = numpy.subtract(binary_image, mask) out = numpy.add(res, out) return out
[docs] def erode_dilate(binary_image, kernel_shape=(2, 2), iterations=1, mask=None): """ Applied a morphology (erode & dilate) on binary_image on mask ROI. Parameters ---------- binary_image : numpy.ndarray 2-D array kernel_shape: (N, M) of integers, optional kernel shape of (erode & dilate) applied to binary_image iterations: int, optional number of successive iteration of (erode & dilate) mask : numpy.ndarray, optional Array of same shape as `image`. Only points at which mask == True will be processed. Returns ------- out : numpy.ndarray Binary Image """ # ========================================================================== # Check Parameters if not isinstance(binary_image, numpy.ndarray): raise TypeError("binary_image must be a numpy.ndarray") if binary_image.ndim != 2: raise ValueError("binary_image must be 2D array") if mask is not None: if not isinstance(mask, numpy.ndarray): raise TypeError("mask must be a numpy.ndarray") if mask.ndim != 2: raise ValueError("mask must be 2D array") # ========================================================================== if mask is not None: out = numpy.bitwise_and(binary_image, mask) else: out = binary_image.copy() element = numpy.pad(numpy.array([[0, 1, 0], [1, 1, 1], [0, 1, 0]]), kernel_shape) for _ in range(iterations): out = skimage.morphology.erosion(out, element) for _ in range(iterations): out = skimage.morphology.dilation(out, element) if mask is not None: res = numpy.subtract(binary_image, mask) out = numpy.add(res, out) return out
[docs] def close(binary_image, kernel_shape=(6, 6), mask=None): """ Applied a morphology close on binary_image on mask ROI. Parameters ---------- binary_image : numpy.ndarray 2-D array kernel_shape: (N, M) of integers kernel shape of morphology close applied to binary_image mask : numpy.ndarray, optional Array of same shape as `image`. Only points at which mask == True will be processed. Returns ------- out : numpy.ndarray Binary Image """ # ========================================================================== # Check Parameters if not isinstance(binary_image, numpy.ndarray): raise TypeError("image must be a numpy.ndarray") if binary_image.ndim != 2: raise ValueError("image must be 2D array") if mask is not None: if not isinstance(mask, numpy.ndarray): raise TypeError("mask must be a numpy.ndarray") if mask.ndim != 2: raise ValueError("mask must be 2D array") # ========================================================================== if mask is not None: out = numpy.bitwise_and(binary_image, mask) else: out = binary_image.copy() kernel = numpy.ones(kernel_shape, numpy.uint8) out = skimage.morphology.closing(out, kernel) if mask is not None: out = numpy.add(binary_image, out) return out