Source code for model.matconvnet_model

# Copyright or © or Copr. IETR/INSA Rennes (2019)
# 
# Contributors :
#     Eduardo Fernandes-Montesuma eduardo.fernandes-montesuma@insa-rennes.fr (2019)
#     Florian Lemarchand florian.lemarchand@insa-rennes.fr (2019)
# 
# 
# OpenDenoising is a computer program whose purpose is to benchmark image
# restoration algorithms.
# 
# This software is governed by the CeCILL-C license under French law and
# abiding by the rules of distribution of free software. You can  use,
# modify and/ or redistribute the software under the terms of the CeCILL-C
# license as circulated by CEA, CNRS and INRIA at the following URL
# "http://www.cecill.info".
# 
# As a counterpart to the access to the source code and rights to copy,
# modify and redistribute granted by the license, users are provided only
# with a limited warranty  and the software's author, the holder of the
# economic rights, and the successive licensors have only  limited
# liability.
# 
# In this respect, the user's attention is drawn to the risks associated
# with loading, using, modifying and/or developing or reproducing the
# software by the user in light of its specific status of free software,
# that may mean  that it is complicated to manipulate,  and  that  also
# therefore means  that it is reserved for developers  and  experienced
# professionals having in-depth computer knowledge. Users are therefore
# encouraged to load and test the software's suitability as regards their
# requirements in conditions enabling the security of their systems and/or
# data to be ensured and, more generally, to use and operate it in the
# same conditions as regards security.
# 
# The fact that you are presently reading this means that you have had
# knowledge of the CeCILL-C license and that you accept its terms.


import os
import numpy as np
from OpenDenoising.model import module_logger
from OpenDenoising.model import AbstractDeepLearningModel

try:
    import matlab.engine
    MATLAB_IMPORTED = True
except ImportError as err:
    module_logger.warning("Matlab engine was not installed correctly. Take a look on the documentation's tutorial for \
                          its installation.")
    MATLAB_IMPORTED = False


[docs]class MatconvnetModel(AbstractDeepLearningModel): """Matlab Matconvnet wrapper class. Notes ----- Matconvnet models are available only for inference. Attributes ---------- model_path : str String containing the path to model files. denoising_func : :class:`function` Function object representing the Matlab function responsable for denoising images. model_file_path : str String containing the path to the model saved weights. See Also -------- :class:`model.AbstractDenoiser` : for the basic functionalities of Image Denoisers. :class:`model.AbstractDeepLearningModel` : for the basic functionalities of Deep Learning based Denoisers. """
[docs] def __init__(self, model_name="MatconvnetModel", return_diff=False): global MATLAB_IMPORTED assert MATLAB_IMPORTED, "Got expcetion {} while importing matlab.engine. Check Matlab's Engine installation.".format(err) try: self.engine = matlab.engine.start_matlab() except matlab.engine.EngineError as err: module_logger.exception("Matlab license error. Make sure you have a valid Matlab license.") raise err super().__init__(model_name, framework="Matconvnet", return_diff=return_diff) self.model_path = None self.denoise_func = None
[docs] def charge_model(self, model_path=None): """This method charges a matlab function corresponding to the denoising action into the class wrapper. Parameters ---------- model_path : str String containing the path to the Matlab denoising function, as well as the networks weights (saved as a .mat file) """ assert (model_path is not None), "Unspecified model_path." self.model_path = model_path model_dir = os.path.dirname(self.model_path) # Adds entire folder to Matlab path self.engine.addpath(self.engine.fullfile(model_dir)) # Lists files in model directory files = os.listdir(model_dir) # Search for .m and .mat files in model_dir. denoise_func_name = None for file in files: if "denoise" in file: # Founded denoise function denoise_func_name = file.split(".m")[0] assert (denoise_func_name is not None), "Expected 'denoise' to be substring in at least one file in {},"\ "but found files: {}".format(model_dir, self.model_path) self.denoise_func = getattr(self.engine, denoise_func_name)
def train(self, train_generator, valid_generator=None, n_epochs=100, n_stages=5e+2, learning_rate=1e-3, optimizer_name="Adam", valid_steps=10): raise NotImplementedError("Training of matconvnet-based is not supported.")
[docs] def __call__(self, image): """Denoises a batch of images. Parameters ---------- image: :class:`numpy.ndarray` 4D batch of noised images. It has shape: (batch_size, height, width, channels) Returns ------- :class:`numpy.ndarray`: Restored batch of images, with same shape as the input. """ predicted_image = [] for img in image: img = np.squeeze(img) # If image is grayscale, converts 3D array to 2D array. m_img = matlab.single(img.tolist()) # Converts array to matlab m_img_res = self.denoise_func(self.model_path, m_img, matlab.logical([True])) predicted_image.append(np.asarray(m_img_res)) predicted_image = np.asarray(predicted_image) if self.return_diff: return image - predicted_image else: return predicted_image
[docs] def __len__(self): """Counts the number of parameters in the networks. Returns ------- nparams : int Number of parameters in the network. """ nparams = self.engine.vl_count_params(self.model_path) return int(np.asarray(nparams))