diff --git a/include/aidge/backend/opencv.hpp b/include/aidge/backend/opencv.hpp
index 01f1de6c8141961f55c6a967a523d9b1ebde1c17..41f01a50c4728b6619f0cafaa11544c2c2748c25 100644
--- a/include/aidge/backend/opencv.hpp
+++ b/include/aidge/backend/opencv.hpp
@@ -9,12 +9,13 @@
  *
  ********************************************************************************/
 
-#ifndef AIDGE_OPENCV_IMPORTS_H_
-#define AIDGE_OPENCV_IMPORTS_H_
+#ifndef AIDGE_OPENCV_OPENCV_H_
+#define AIDGE_OPENCV_OPENCV_H_
 
+#include "aidge/backend/opencv/data/DataUtils.hpp"
 #include "aidge/backend/opencv/data/TensorImpl.hpp"
-#include "aidge/backend/opencv/stimuli/StimuliImpl_opencv_imread.hpp"
 #include "aidge/backend/opencv/database/MNIST.hpp"
+#include "aidge/backend/opencv/stimuli/StimulusImpl_opencv_imread.hpp"
 #include "aidge/backend/opencv/utils/Utils.hpp"
 
-#endif /* AIDGE_OPENCV_IMPORTS_H_ */
\ No newline at end of file
+#endif /* AIDGE_OPENCV_OPENCV_H_ */
\ No newline at end of file
diff --git a/include/aidge/backend/opencv/data/DataUtils.hpp b/include/aidge/backend/opencv/data/DataUtils.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..b58267a35f27c6b1e4b40dc86452413b37684b9c
--- /dev/null
+++ b/include/aidge/backend/opencv/data/DataUtils.hpp
@@ -0,0 +1,49 @@
+/********************************************************************************
+ * Copyright (c) 2023 CEA-List
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+#ifndef AIDGE_OPENCV_DATA_DATAUTILS_H_
+#define AIDGE_OPENCV_DATA_DATAUTILS_H_
+
+
+#include "opencv2/core.hpp"
+
+#include <cstdint>
+
+namespace Aidge {
+
+namespace detail {
+template <typename T> struct CV_C1_CPP { static constexpr int value = -1; };
+template <> struct CV_C1_CPP<std::int8_t> {
+    static constexpr int value = CV_8SC1;
+};
+template <> struct CV_C1_CPP<std::int16_t> {
+    static constexpr int value = CV_16SC1;
+};
+template <> struct CV_C1_CPP<std::int32_t> {
+    static constexpr int value = CV_32SC1;
+};
+template <> struct CV_C1_CPP<std::uint8_t> {
+    static constexpr int value = CV_8UC1;
+};
+template <> struct CV_C1_CPP<std::uint16_t> {
+    static constexpr int value = CV_16UC1;
+};
+template <> struct CV_C1_CPP<float> {
+    static constexpr int value = CV_32FC1;
+};
+template <> struct CV_C1_CPP<double> {
+    static constexpr int value = CV_64FC1;
+};
+template <typename T> constexpr int CV_C1_CPP_v = CV_C1_CPP<T>::value;
+} // namespace detail
+} // namespace Aidge
+
+#endif /* AIDGE_OPENCV_DATA_DATAUTILS_H_ */
\ No newline at end of file
diff --git a/include/aidge/backend/opencv/data/TensorImpl.hpp b/include/aidge/backend/opencv/data/TensorImpl.hpp
index 1fe5ed12852d06482eef46f6ce7eaa8d60227fa8..fc1d5e52123e42ab2c4a69ab8d5a1ea0306d52ca 100644
--- a/include/aidge/backend/opencv/data/TensorImpl.hpp
+++ b/include/aidge/backend/opencv/data/TensorImpl.hpp
@@ -1,5 +1,16 @@
-#ifndef TensorImpl_opencv_H_
-#define TensorImpl_opencv_H_
+/********************************************************************************
+ * Copyright (c) 2023 CEA-List
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+#ifndef AIDGE_OPENCV_DATA_TENSORIMPL_H_
+#define AIDGE_OPENCV_DATA_TENSORIMPL_H_
 
 #include "opencv2/core.hpp"
 
@@ -9,23 +20,11 @@
 #include "aidge/utils/Types.h"
 #include "aidge/utils/ErrorHandling.hpp"
 #include "aidge/utils/future_std/span.hpp"
+#include "aidge/backend/opencv/data/DataUtils.hpp"
 
-#include <iostream>
-
-namespace {
-template <typename T> struct OpenCvType { static const int type; };
-template <> const int OpenCvType<char>::type = CV_8SC1;
-template <> const int OpenCvType<signed char>::type = CV_8SC1;
-template <> const int OpenCvType<short>::type = CV_16SC1;
-template <> const int OpenCvType<int>::type = CV_32SC1;
-template <> const int OpenCvType<unsigned char>::type = CV_8UC1;
-template <> const int OpenCvType<unsigned short>::type = CV_16UC1;
-template <> const int OpenCvType<float>::type = CV_32FC1;
-template <> const int OpenCvType<double>::type = CV_64FC1;
-} // namespace
 
 namespace Aidge {
-  
+
 class TensorImpl_opencv_ {
 public:
     virtual const cv::Mat& getCvMat() const = 0;
@@ -39,8 +38,8 @@ private:
 
     future_std::span<cv::Mat> mData;
 
-    std::unique_ptr<cv::Mat> mDataOwner = std::unique_ptr<cv::Mat>(new cv::Mat(0,0,OpenCvType<T>::type));
-    
+    std::unique_ptr<cv::Mat> mDataOwner = std::unique_ptr<cv::Mat>(new cv::Mat(0, 0, detail::CV_C1_CPP_v<T>));
+
 public:
     static constexpr const char *Backend = "opencv";
 
@@ -51,7 +50,7 @@ public:
         // Create iterators for both matrices
         cv::MatConstIterator_<T> it1 = mDataOwner->begin<T>();
         const future_std::span<cv::Mat> tmp = reinterpret_cast<const TensorImpl_opencv<T> &>(otherImpl).data();
-        
+
         const cv::Mat otherData = *(tmp.data());
         cv::MatConstIterator_<T> it2 = otherData.begin<T>();
 
@@ -71,9 +70,9 @@ public:
     // native interface
     const future_std::span<cv::Mat> data() const { return mData; }
 
-    std::size_t scalarSize() const override { return sizeof(T); }
+    inline std::size_t scalarSize() const override { return sizeof(T); }
 
-    std::size_t size() const override { return mData.size(); }
+    inline std::size_t size() const override { return mData.size(); }
 
     void setDevice(DeviceIdx_t device) override {
         AIDGE_ASSERT(device == 0, "device cannot be != 0 for Opencv backend");
@@ -91,56 +90,57 @@ public:
         }
 
         AIDGE_ASSERT(length <= mData.size() || length <= mTensor.size(), "copy length is above capacity");
-        if (srcDt == DataType::Float64) {
-            std::copy(static_cast<const double*>(src), static_cast<const double*>(src) + length,
+        switch (srcDt) {
+            case DataType::Float64:
+                std::copy(static_cast<const double*>(src), static_cast<const double*>(src) + length,
                     static_cast<T *>(rawPtr()));
-        }
-        else if (srcDt == DataType::Float32) {
-            std::copy(static_cast<const float*>(src), static_cast<const float*>(src) + length,
+                break;
+            case DataType::Float32:
+                std::copy(static_cast<const float*>(src), static_cast<const float*>(src) + length,
                     static_cast<T *>(rawPtr()));
-        }
-        else if (srcDt == DataType::Float16) {
-            std::copy(static_cast<const half_float::half*>(src), static_cast<const half_float::half*>(src) + length,
+                break;
+            case DataType::Float16:
+                std::copy(static_cast<const half_float::half*>(src), static_cast<const half_float::half*>(src) + length,
                     static_cast<T *>(rawPtr()));
-        }
-        else if (srcDt == DataType::Int64) {
-            std::copy(static_cast<const int64_t*>(src), static_cast<const int64_t*>(src) + length,
+                break;
+            case DataType::Int64:
+                std::copy(static_cast<const int64_t*>(src), static_cast<const int64_t*>(src) + length,
                     static_cast<T *>(rawPtr()));
-        }
-        else if (srcDt == DataType::UInt64) {
-            std::copy(static_cast<const uint64_t*>(src), static_cast<const uint64_t*>(src) + length,
+                break;
+            case DataType::UInt64:
+                std::copy(static_cast<const uint64_t*>(src), static_cast<const uint64_t*>(src) + length,
                     static_cast<T *>(rawPtr()));
-        }
-        else if (srcDt == DataType::Int32) {
-            std::copy(static_cast<const int32_t*>(src), static_cast<const int32_t*>(src) + length,
+                break;
+            case DataType::Int32:
+                std::copy(static_cast<const int32_t*>(src), static_cast<const int32_t*>(src) + length,
                     static_cast<T *>(rawPtr()));
-        }
-        else if (srcDt == DataType::UInt32) {
-            std::copy(static_cast<const uint32_t*>(src), static_cast<const uint32_t*>(src) + length,
+                break;
+            case DataType::UInt32:
+                std::copy(static_cast<const uint32_t*>(src), static_cast<const uint32_t*>(src) + length,
                     static_cast<T *>(rawPtr()));
-        }
-        else if (srcDt == DataType::Int16) {
-            std::copy(static_cast<const int16_t*>(src), static_cast<const int16_t*>(src) + length,
+                break;
+            case DataType::Int16:
+                std::copy(static_cast<const int16_t*>(src), static_cast<const int16_t*>(src) + length,
                     static_cast<T *>(rawPtr()));
-        }
-        else if (srcDt == DataType::UInt16) {
-            std::copy(static_cast<const uint16_t*>(src), static_cast<const uint16_t*>(src) + length,
+                break;
+            case DataType::UInt16:
+                std::copy(static_cast<const uint16_t*>(src), static_cast<const uint16_t*>(src) + length,
                     static_cast<T *>(rawPtr()));
-        }
-        else if (srcDt == DataType::Int8) {
-            std::copy(static_cast<const int8_t*>(src), static_cast<const int8_t*>(src) + length,
+                break;
+            case DataType::Int8:
+                std::copy(static_cast<const int8_t*>(src), static_cast<const int8_t*>(src) + length,
                     static_cast<T *>(rawPtr()));
-        }
-        else if (srcDt == DataType::UInt8) {
-            std::copy(static_cast<const uint8_t*>(src), static_cast<const uint8_t*>(src) + length,
+                break;
+            case DataType::UInt8:
+                std::copy(static_cast<const uint8_t*>(src), static_cast<const uint8_t*>(src) + length,
                     static_cast<T *>(rawPtr()));
-        }
-        else {
-            AIDGE_THROW_OR_ABORT(std::runtime_error, "Unsupported data type.");
+                break;
+            default:
+                AIDGE_THROW_OR_ABORT(std::runtime_error, "Unsupported data type.");
         }
     }
 
-    
+
     void copyFromDevice(const void *src, NbElts_t length, const std::pair<std::string, DeviceIdx_t>& device) override {
         AIDGE_ASSERT(device.first == Backend, "backend must match");
         AIDGE_ASSERT(device.second == 0, "device cannot be != 0 for CPU backend");
@@ -181,7 +181,7 @@ public:
 
     const cv::Mat& getCvMat() const override { return *mDataOwner.get(); }
     void setCvMat(const cv::Mat& mat) override {mDataOwner.reset(new cv::Mat(std::move(mat)));}
-    
+
 
   virtual ~TensorImpl_opencv() = default;
 
@@ -198,14 +198,14 @@ private:
                                                     : (mTensor.nbDims() > 0) ? 1
                                                                             : 0),
                             (mTensor.nbDims() > 0) ? static_cast<int>(mTensor.dims()[0]) : 0,
-                            OpenCvType<T>::type);
+                            detail::CV_C1_CPP_v<T>);
         } else {
             std::vector<cv::Mat> channels;
 
             for (std::size_t k = 0; k < mTensor.dims()[2]; ++k) {
                 channels.push_back(cv::Mat(static_cast<int>(mTensor.dims()[1]),
                                         static_cast<int>(mTensor.dims()[0]),
-                                        OpenCvType<T>::type));
+                                        detail::CV_C1_CPP_v<T>));
             }
 
             cv::merge(channels, myNewMatrix);
@@ -213,7 +213,7 @@ private:
 
         mDataOwner.reset(new cv::Mat(std::forward<cv::Mat>(myNewMatrix)));
         mData = future_std::span<cv::Mat>(mDataOwner.get(), mTensor.size());
-      
+
     }
   }
 };
@@ -224,16 +224,16 @@ static Registrar<Tensor> registrarTensorImpl_opencv_Float64(
 static Registrar<Tensor> registrarTensorImpl_opencv_Float32(
         {"opencv", DataType::Float32}, Aidge::TensorImpl_opencv<float>::create);
 static Registrar<Tensor> registrarTensorImpl_opencv_Int32(
-        {"opencv", DataType::Int32}, Aidge::TensorImpl_opencv<int>::create);
+        {"opencv", DataType::Int32}, Aidge::TensorImpl_opencv<std::int32_t>::create);
 static Registrar<Tensor> registrarTensorImpl_opencv_Int16(
-        {"opencv", DataType::Int16}, Aidge::TensorImpl_opencv<int16_t>::create);
+        {"opencv", DataType::Int16}, Aidge::TensorImpl_opencv<std::int16_t>::create);
 static Registrar<Tensor> registrarTensorImpl_opencv_UInt16(
-        {"opencv", DataType::UInt16}, Aidge::TensorImpl_opencv<uint16_t>::create);
+        {"opencv", DataType::UInt16}, Aidge::TensorImpl_opencv<std::uint16_t>::create);
 static Registrar<Tensor> registrarTensorImpl_opencv_Int8(
-        {"opencv", DataType::Int8}, Aidge::TensorImpl_opencv<int8_t>::create);
+        {"opencv", DataType::Int8}, Aidge::TensorImpl_opencv<std::int8_t>::create);
 static Registrar<Tensor> registrarTensorImpl_opencv_UInt8(
-        {"opencv", DataType::UInt8}, Aidge::TensorImpl_opencv<uint8_t>::create);                              
+        {"opencv", DataType::UInt8}, Aidge::TensorImpl_opencv<std::uint8_t>::create);
 } // namespace
 } // namespace Aidge
 
-#endif /* TensorImpl_opencv_H_ */
+#endif /* AIDGE_OPENCV_DATA_TENSORIMPL_H_ */
diff --git a/include/aidge/backend/opencv/database/MNIST.hpp b/include/aidge/backend/opencv/database/MNIST.hpp
index e3a9b6bec4c98bb0cc815ccdafc30d17970f5352..af77e67fd0aff6aa7895b2f05ba942e58557a881 100644
--- a/include/aidge/backend/opencv/database/MNIST.hpp
+++ b/include/aidge/backend/opencv/database/MNIST.hpp
@@ -1,19 +1,29 @@
-#ifndef MNIST_H
-#define MNIST_H
-
-#include <fstream>
-#include <iomanip>
-#include <tuple>
-
-#include "opencv2/core.hpp"
-#include <opencv2/opencv.hpp>
+/********************************************************************************
+ * Copyright (c) 2023 CEA-List
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+#ifndef AIDGE_OPENCV_DATABASE_MNIST_H_
+#define AIDGE_OPENCV_DATABASE_MNIST_H_
+
+#include <algorithm>  // std::reverse
+#include <cstddef>    // std:size_t
+#include <cstdint>    // std::uint32_t
+#include <string>
+#include <tuple>      // std::tuple_size
+#include <vector>
 
 #include "aidge/data/Database.hpp"
-#include "aidge/stimuli/Stimuli.hpp"
-#include "aidge/graph/GraphView.hpp"
-#include "aidge/scheduler/Scheduler.hpp"
+#include "aidge/stimuli/Stimulus.hpp"
+// #include "aidge/graph/GraphView.hpp"
+// #include "aidge/scheduler/Scheduler.hpp"
 #include "aidge/data/Tensor.hpp"
-#include "aidge/backend/opencv/utils/Utils.hpp"
 
 // #include "aidge/backend/opencv/data/TensorImpl.hpp"
 
@@ -21,7 +31,7 @@ namespace Aidge {
 
 template <class T> void swapEndian(T& obj)
 {
-    unsigned char* memp = reinterpret_cast<unsigned char*>(&obj);
+    std::uint8_t* memp = reinterpret_cast<unsigned char*>(&obj);
     std::reverse(memp, memp + sizeof(T));
 }
 
@@ -35,40 +45,12 @@ inline bool isBigEndian()
     return bint.c[0] == 1;
 }
 
+
 class MNIST : public Database {
 public:
-    MNIST(const std::string& dataPath, 
-            // const GraphView transformations, 
-            bool train,
-            bool loadDataInMemory = false)
-    : Database(),
-      mDataPath(dataPath),
-    // mDataTransformations(transformations),
-      mTrain(train),
-      mLoadDataInMemory(loadDataInMemory)
-    {
-        // Uncompress train database 
-        if (mTrain){
-            MNIST::uncompress(mDataPath + "/train-images-idx3-ubyte",
-                                dataPath + "/train-labels-idx1-ubyte");
-        }else { // Uncompress test database 
-            MNIST::uncompress(mDataPath + "/t10k-images-idx3-ubyte",
-                                dataPath + "/t10k-labels-idx1-ubyte");
-        }
-    }
-    
-    std::vector<std::shared_ptr<Tensor>> getItem(std::size_t index) override;
-
-    void uncompress(const std::string& dataPath,
-                    const std::string& labelPath);
-
-    std::size_t getLen() override;
-
-    std::size_t getNbModalities() override;
-
     union MagicNumber {
-        unsigned int value;
-        unsigned char byte[4];
+        std::uint32_t value;
+        std::uint8_t byte[4];
     };
 
     enum DataType {
@@ -78,25 +60,24 @@ public:
         Int = 0x0C,
         Float = 0x0D,
         Double = 0x0E
-    }; 
+    };
 
 protected:
+    /// Stimulus data path
+    const std::string mDataPath;
 
-    /// Stimuli data path
-    std::string mDataPath;
-    
     // True select the train database, False Select the test database
     bool mTrain;
 
     // True Load images in memory, False reload at each call
     bool mLoadDataInMemory;
 
-    /// Stimuli data
+    /// Stimulus data
     // Each index of the vector is one item of the database
     // One item of the MNIST database is the tuple <Image,label>
     // First stimuli of the tuple is a gray scale image stimuli of a writen digit
     // Second stimuli of the tuple is the label associated to the digit : unsigned integer 0-9
-    std::vector<std::tuple<Stimuli,Stimuli>> mStimulis;
+    mutable std::vector<std::tuple<Stimulus,Stimulus>> mStimuli;
 
     /// Data Transformations
     // Data transformations use the GraphView mecanism
@@ -106,7 +87,43 @@ protected:
     // Scheduler to run the graph of data transformations
     // Scheduler mScheduler;
 
+public:
+    MNIST(const std::string& dataPath,
+            // const GraphView transformations,
+            bool train,
+            bool loadDataInMemory = false)
+    : Database(),
+      mDataPath(dataPath),
+    // mDataTransformations(transformations),
+      mTrain(train),
+      mLoadDataInMemory(loadDataInMemory)
+    {
+        // Uncompress train database
+        if (mTrain) {
+            uncompress(mDataPath + "/train-images-idx3-ubyte",
+                            dataPath + "/train-labels-idx1-ubyte");
+        } else { // Uncompress test database
+            uncompress(mDataPath + "/t10k-images-idx3-ubyte",
+                            dataPath + "/t10k-labels-idx1-ubyte");
+        }
+    }
+
+    ~MNIST() noexcept;
+
+public:
+    std::vector<std::shared_ptr<Tensor>> getItem(const std::size_t index) const override final;
+
+    inline std::size_t getLen() const noexcept override final {
+        return mStimuli.size();
+    }
+
+    inline std::size_t getNbModalities() const noexcept override final {
+        return std::tuple_size<decltype(mStimuli)::value_type>::value;
+    }
+
+private:
+    void uncompress(const std::string& dataPath, const std::string& labelPath);
 };
 }
 
-#endif // MNIST_H
+#endif // AIDGE_OPENCV_DATABASE_MNIST_H_
diff --git a/include/aidge/backend/opencv/stimuli/StimuliImpl_opencv_imread.hpp b/include/aidge/backend/opencv/stimuli/StimuliImpl_opencv_imread.hpp
deleted file mode 100644
index 78590a16fc9236e06f8afd34bcf9735dae0314fd..0000000000000000000000000000000000000000
--- a/include/aidge/backend/opencv/stimuli/StimuliImpl_opencv_imread.hpp
+++ /dev/null
@@ -1,59 +0,0 @@
-/********************************************************************************
- * Copyright (c) 2023 CEA-List
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0.
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- ********************************************************************************/
-
-#ifndef LOAD_H_
-#define LOAD_H_
-
-#include <cstring>
-#include <memory>
-#include <iostream>
-
-#include "opencv2/core.hpp"
-#include <opencv2/imgcodecs.hpp>
-
-#include "aidge/data/Data.hpp"
-#include "aidge/data/Tensor.hpp"
-#include "aidge/backend/StimuliImpl.hpp"
-#include "aidge/stimuli/Stimuli.hpp"
-#include "aidge/backend/opencv/data/TensorImpl.hpp"
-#include "aidge/backend/opencv/utils/Utils.hpp"
-
-
-namespace Aidge {
-class StimuliImpl_opencv_imread : public StimuliImpl {
-public:
-    StimuliImpl_opencv_imread(const std::string& dataPath="", int colorFlag=cv::IMREAD_COLOR) : 
-            mDataPath(dataPath),
-            mColorFlag(colorFlag) {}
-    virtual ~StimuliImpl_opencv_imread() {};
-
-    std::shared_ptr<Tensor> load() override;
-
-    static std::unique_ptr<StimuliImpl_opencv_imread> create(const std::string& dataPath) {
-        return std::make_unique<StimuliImpl_opencv_imread>(dataPath);
-    }
-
-protected: 
-
-    /// Stimuli data path
-    std::string mDataPath;
-    int mColorFlag;
-
-};
-namespace {
-static Registrar<Aidge::Stimuli> registrarStimuliImpl_opencv_png(
-        {"opencv", "png"}, Aidge::StimuliImpl_opencv_imread::create);
-static Registrar<Aidge::Stimuli> registrarStimuliImpl_opencv_pgm(
-        {"opencv", "pgm"}, Aidge::StimuliImpl_opencv_imread::create);
-}  // namespace
-} // namespace Aidge
-
-#endif /* LOAD_H_ */
diff --git a/include/aidge/backend/opencv/stimuli/StimulusImpl_opencv_imread.hpp b/include/aidge/backend/opencv/stimuli/StimulusImpl_opencv_imread.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..3db56da874507e738d3a2b5987306c1ca96b304c
--- /dev/null
+++ b/include/aidge/backend/opencv/stimuli/StimulusImpl_opencv_imread.hpp
@@ -0,0 +1,61 @@
+/********************************************************************************
+ * Copyright (c) 2023 CEA-List
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+#ifndef AIDGE_OPENCV_STIMULI_STIMULUSIMPLOPENCVIMREAD_H_
+#define AIDGE_OPENCV_STIMULI_STIMULUSIMPLOPENCVIMREAD_H_
+
+#include <string>
+#include <memory>
+
+#include <opencv2/imgcodecs.hpp>   // cv::IMREAD_COLOR
+
+#include "aidge/data/Tensor.hpp"
+#include "aidge/backend/StimulusImpl.hpp"
+#include "aidge/stimuli/Stimulus.hpp"
+#include "aidge/backend/opencv/data/TensorImpl.hpp"
+
+
+namespace Aidge {
+class StimulusImpl_opencv_imread : public StimulusImpl {
+private:
+    /// Stimulus data path
+    const std::string mDataPath;
+    const int mColorFlag;
+
+public:
+    StimulusImpl_opencv_imread(const std::string& dataPath="", std::int32_t colorFlag=cv::IMREAD_COLOR)
+    : mDataPath(dataPath),
+      mColorFlag(colorFlag)
+    {
+        // ctor
+    }
+
+    ~StimulusImpl_opencv_imread() noexcept;
+
+public:
+    static std::unique_ptr<StimulusImpl_opencv_imread> create(const std::string& dataPath) {
+        return std::make_unique<StimulusImpl_opencv_imread>(dataPath);
+    }
+
+public:
+    std::shared_ptr<Tensor> load() const override;
+};
+
+namespace {
+static Registrar<Aidge::Stimulus> registrarStimulusImpl_opencv_png(
+        {"opencv", "png"}, Aidge::StimulusImpl_opencv_imread::create);
+static Registrar<Aidge::Stimulus> registrarStimulusImpl_opencv_pgm(
+        {"opencv", "pgm"}, Aidge::StimulusImpl_opencv_imread::create);
+}  // namespace
+
+} // namespace Aidge
+
+#endif /* AIDGE_OPENCV_STIMULI_STIMULUSIMPLOPENCVIMREAD_H_ */
diff --git a/include/aidge/backend/opencv/utils/Utils.hpp b/include/aidge/backend/opencv/utils/Utils.hpp
index 3caa6f96e04f4c3bdc59de36d7a47fecceb2e6b1..8f978db51ccda0d9e86b28319a90425528263a4e 100644
--- a/include/aidge/backend/opencv/utils/Utils.hpp
+++ b/include/aidge/backend/opencv/utils/Utils.hpp
@@ -9,92 +9,49 @@
  *
  ********************************************************************************/
 
-#ifndef AIDGE_BACKEND_OPENCV_UTILS_ATTRIBUTES_H_
-#define AIDGE_BACKEND_OPENCV_UTILS_ATTRIBUTES_H_
-
+#ifndef AIDGE_OPENCV_UTILS_UTILS_H_
+#define AIDGE_OPENCV_UTILS_UTILS_H_
 
+#include <opencv2/core/mat.hpp>  // cv::Mat
+#include <memory>
 #include <tuple>
+#include <vector>
 
-#include "opencv2/core.hpp"
-#include <opencv2/opencv.hpp>
-
-#include "aidge/data/Tensor.hpp"
-#include "aidge/backend/opencv/data/TensorImpl.hpp"
-#include "aidge/backend/cpu/data/TensorImpl.hpp"
 #include "aidge/data/Data.hpp"
+#include "aidge/data/Tensor.hpp"
+#include "aidge/utils/Types.h"
 
 namespace Aidge {
 
-    /**
-     * @brief Instanciate an aidge tensor with backend "opencv" from an opencv matrix
-     * 
-     * @param mat the cv::mat to instanciate the tensor from
-     * @return std::shared_ptr<Tensor> aidge tensor
-     */
-    inline std::shared_ptr<Tensor> tensorOpencv(cv::Mat mat){
-        // Get Mat dims
-        std::vector<DimSize_t> matDims = std::vector<DimSize_t>({static_cast<DimSize_t>(mat.cols),
-                                                                static_cast<DimSize_t>(mat.rows),
-                                                                static_cast<DimSize_t>(mat.channels())});
-        // Create tensor from the dims of the Cv::Mat
-        std::shared_ptr<Tensor> tensor = std::make_shared<Tensor>(matDims);
-        // Set beackend opencv 
-        tensor->setBackend("opencv");
-        // Set Data Type
-        switch (mat.depth()) {
-            case CV_8U:
-                tensor->setDataType(Aidge::DataType::UInt8);
-                break;
-            case CV_8S:
-                tensor->setDataType(Aidge::DataType::Int8);
-                break;
-            case CV_16U:
-                tensor->setDataType(Aidge::DataType::UInt16);
-                break;
-            case CV_16S:
-                tensor->setDataType(Aidge::DataType::Int16);
-                break;
-            case CV_32S:
-                tensor->setDataType(Aidge::DataType::Int32);
-                break;
-            case CV_32F:
-                tensor->setDataType(Aidge::DataType::Float32);
-                break;
-            case CV_64F:
-                tensor->setDataType(Aidge::DataType::Float64);
-                break;
-            default:
-                throw std::runtime_error(
-                    "Cannot convert cv::Mat to Tensor: incompatible types.");
-            }
+/**
+ * @brief Instanciate an aidge tensor with backend "opencv" from an opencv matrix
+ *
+ * @param mat the cv::mat to instanciate the tensor from
+ * @return std::shared_ptr<Tensor> aidge tensor
+ */
+std::shared_ptr<Tensor> tensorOpencv(cv::Mat mat);
+
+/**
+ * @brief Copy the data from a source 2D cv::mat to a destination pointer with an offset
+ *
+ * @tparam CV_T The standard type corresponding to the opencv data type
+ * @param mat opencv 2D mat to copy the data from
+ * @param data destination pointer
+ * @param offset offset an the destination data pointer
+ */
+template <class CV_T>
+void convert(const cv::Mat& mat, void* data, std::size_t offset);
 
-        // Cast the tensorImpl to access setCvMat function
-        TensorImpl_opencv_* tImpl_opencv = dynamic_cast<TensorImpl_opencv_*>(tensor->getImpl().get());
-        tImpl_opencv->setCvMat(mat);
-        return tensor;
-    }
 
-    /**
-     * @brief Copy the data from a source 2D cv::mat to a destination pointer with an offset
-     * 
-     * @tparam CV_T The standard type corresponding to the opencv data type
-     * @param mat opencv 2D mat to copy the data from
-     * @param data destination pointer 
-     * @param offset offset an the destination data pointer 
-     */
-    template <class CV_T>
-    void convert(const cv::Mat& mat, void* data, size_t offset);
+/**
+ * @brief Convert a tensor backend opencv into a tensor backend cpu
+ *
+ * @param tensorOpencv tensor with backend opencv (contains a cv::mat)
+ * @return std::shared_ptr<Tensor> tensor backend cpu (contains a std::vector)
+ */
+std::shared_ptr<Tensor> convertCpu(std::shared_ptr<Aidge::Tensor> tensorOpencv);
 
-    
-    /**
-     * @brief Convert a tensor backend opencv into a tensor backend cpu
-     * 
-     * @param tensorOpencv tensor with backend opencv (contains a cv::mat)
-     * @return std::shared_ptr<Tensor> tensor backend cpu (contains a std::vector)
-     */
-    std::shared_ptr<Tensor> convertCpu(std::shared_ptr<Aidge::Tensor> tensorOpencv);
 
-    
 }  // namespace
 
-#endif // AIDGE_BACKEND_OPENCV_UTILS_ATTRIBUTES_H_
\ No newline at end of file
+#endif // AIDGE_OPENCV_UTILS_UTILS_H_
\ No newline at end of file
diff --git a/src/database/MNIST.cpp b/src/database/MNIST.cpp
index d9145f6e1f367296452b9fa36acec530270a328e..fd92f57c4f66cfa4c02a42cdb3192f82ac3339a8 100644
--- a/src/database/MNIST.cpp
+++ b/src/database/MNIST.cpp
@@ -1,5 +1,28 @@
+/********************************************************************************
+ * Copyright (c) 2023 CEA-List
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
 #include "aidge/backend/opencv/database/MNIST.hpp"
 
+#include <cstdint>
+#include <fstream>
+#include <iomanip>
+#include <tuple>
+
+#include "opencv2/core.hpp"
+#include <opencv2/opencv.hpp>
+#include "aidge/backend/opencv/utils/Utils.hpp"
+
+
+Aidge::MNIST::~MNIST() noexcept = default;
+
 void Aidge::MNIST::uncompress(const std::string& dataPath,
                             const std::string& labelPath)
 {
@@ -10,9 +33,9 @@ void Aidge::MNIST::uncompress(const std::string& dataPath,
         throw std::runtime_error("Could not open images file: " + dataPath);
 
     MagicNumber magicNumber;
-    unsigned int nbImages;
-    unsigned int nbRows;
-    unsigned int nbColumns;
+    std::uint32_t nbImages;
+    std::uint32_t nbRows;
+    std::uint32_t nbColumns;
 
     images.read(reinterpret_cast<char*>(&magicNumber.value),
                 sizeof(magicNumber));
@@ -27,8 +50,9 @@ void Aidge::MNIST::uncompress(const std::string& dataPath,
         Aidge::swapEndian(nbColumns);
     }
 
-    if (magicNumber.byte[3] != 0 || magicNumber.byte[2] != 0
-        || magicNumber.byte[1] != Unsigned || magicNumber.byte[0] != 3) {
+    // if (magicNumber.byte[3] != 0 || magicNumber.byte[2] != 0
+    //     || magicNumber.byte[1] != Unsigned || magicNumber.byte[0] != 3) {
+    if (magicNumber.value != 0x00000803) { // 0, 0, unisgned, 3
         throw std::runtime_error("Wrong file format for images file: "
                                  + dataPath);
     }
@@ -40,7 +64,7 @@ void Aidge::MNIST::uncompress(const std::string& dataPath,
         throw std::runtime_error("Could not open labels file: " + labelPath);
 
     MagicNumber magicNumberLabels;
-    unsigned int nbItemsLabels;
+    std::uint32_t nbItemsLabels;
 
     labels.read(reinterpret_cast<char*>(&magicNumberLabels.value),
                 sizeof(magicNumberLabels));
@@ -51,9 +75,10 @@ void Aidge::MNIST::uncompress(const std::string& dataPath,
         Aidge::swapEndian(nbItemsLabels);
     }
 
-    if (magicNumberLabels.byte[3] != 0 || magicNumberLabels.byte[2] != 0
-        || magicNumberLabels.byte[1] != Unsigned
-        || magicNumberLabels.byte[0] != 1) {
+    // if (magicNumberLabels.byte[3] != 0 || magicNumberLabels.byte[2] != 0
+    //     || magicNumberLabels.byte[1] != Unsigned
+    //     || magicNumberLabels.byte[0] != 1) {
+    if (magicNumberLabels.value != 0x00000801) { // 0, 0, unsigned, 1
         throw std::runtime_error("Wrong file format for labels file: "
                                  + labelPath);
     }
@@ -63,8 +88,8 @@ void Aidge::MNIST::uncompress(const std::string& dataPath,
             "The number of images and the number of labels does not match.");
 
     // For each image...
-    for (unsigned int i = 0; i < nbImages; ++i) {
-        unsigned char buff;
+    for (std::uint32_t i = 0; i < nbImages; ++i) {
+        std::uint8_t buff;
 
         std::ostringstream nameStr;
         nameStr << dataPath << "[" << std::setfill('0') << std::setw(5) << i
@@ -74,10 +99,10 @@ void Aidge::MNIST::uncompress(const std::string& dataPath,
         if (!std::ifstream(nameStr.str()).good()) {
             cv::Mat frame(cv::Size(nbColumns, nbRows), CV_8UC1);
 
-            for (unsigned int y = 0; y < nbRows; ++y) {
-                for (unsigned int x = 0; x < nbColumns; ++x) {
+            for (std::uint32_t y = 0; y < nbRows; ++y) {
+                for (std::uint32_t x = 0; x < nbColumns; ++x) {
                     images.read(reinterpret_cast<char*>(&buff), sizeof(buff));
-                    frame.at<unsigned char>(y, x) = buff;
+                    frame.at<std::uint8_t>(y, x) = buff;
                 }
             }
 
@@ -90,18 +115,18 @@ void Aidge::MNIST::uncompress(const std::string& dataPath,
         }
 
         // Create the stimuli of the image
-        Aidge::Stimuli StimuliImg(nameStr.str(), mLoadDataInMemory);
-        StimuliImg.setBackend("opencv");
-          
-        // Create the stimuli of the corresponding label by filing integer to the stimuli directly
+        Aidge::Stimulus StimulusImg(nameStr.str(), mLoadDataInMemory);
+        StimulusImg.setBackend("opencv");
+
+        // Create the stimulus of the corresponding label by filing integer to the stimulus directly
         labels.read(reinterpret_cast<char*>(&buff), sizeof(buff));
-        int label = static_cast<int>(buff);
+        const std::int32_t label = std::move(static_cast<std::int32_t>(buff));
 
         std::shared_ptr<Tensor> lbl = std::make_shared<Tensor>(Array1D<int, 1>{label});
-        Aidge::Stimuli StimuliLabel(lbl);
-        
+        Aidge::Stimulus StimulusLabel(lbl);
+
         // Push back the corresponding image & label in the vector
-        mStimulis.push_back(std::make_tuple(StimuliImg, StimuliLabel));
+        mStimuli.push_back(std::make_tuple(StimulusImg, StimulusLabel));
     }
 
     if (images.eof())
@@ -124,23 +149,14 @@ void Aidge::MNIST::uncompress(const std::string& dataPath,
 }
 
 
-std::vector<std::shared_ptr<Aidge::Tensor>> Aidge::MNIST::getItem(std::size_t index) {
+std::vector<std::shared_ptr<Aidge::Tensor>> Aidge::MNIST::getItem(const std::size_t index) const {
     std::vector<std::shared_ptr<Tensor>> item;
-    // Load the digit tensor 
+    // Load the digit tensor
     // TODO : Currently converts the tensor Opencv but this operation will be carried by a convert operator in the preprocessing graph
-    item.push_back(Aidge::convertCpu((std::get<0>(mStimulis.at(index))).load()));
-    // item.push_back((std::get<0>(mStimulis.at(index))).load());
-    // Load the label tensor 
-    item.push_back((std::get<1>(mStimulis.at(index))).load());
-    
-    return item;
-}
+    item.push_back(Aidge::convertCpu((std::get<0>(mStimuli.at(index))).load()));
+    // item.push_back((std::get<0>(mStimuli.at(index))).load());
+    // Load the label tensor
+    item.push_back((std::get<1>(mStimuli.at(index))).load());
 
-std::size_t  Aidge::MNIST::getLen(){
-    return mStimulis.size();
-}
-
-std::size_t  Aidge::MNIST::getNbModalities(){
-    size_t tupleSize = std::tuple_size<decltype(mStimulis)::value_type>::value;
-    return tupleSize;
+    return item;
 }
\ No newline at end of file
diff --git a/src/operator/StimulImpl_opencv_imread.cpp b/src/operator/StimulImpl_opencv_imread.cpp
deleted file mode 100644
index cf5b0233007bc0bd40a38130d870c2e68a71b133..0000000000000000000000000000000000000000
--- a/src/operator/StimulImpl_opencv_imread.cpp
+++ /dev/null
@@ -1,10 +0,0 @@
-#include "aidge/backend/opencv/stimuli/StimuliImpl_opencv_imread.hpp"
-
-std::shared_ptr<Aidge::Tensor> Aidge::StimuliImpl_opencv_imread::load() {
-    cv::Mat cvImg = cv::imread(mDataPath, mColorFlag);
-    if (cvImg.empty()) {
-        throw std::runtime_error("Could not open images file: " + mDataPath);
-    }
-
-    return tensorOpencv(cvImg);
-}
diff --git a/src/stimuli/StimulusImpl_opencv_imread.cpp b/src/stimuli/StimulusImpl_opencv_imread.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1872c0b0297ae084d241fa0655979a6ce6b56364
--- /dev/null
+++ b/src/stimuli/StimulusImpl_opencv_imread.cpp
@@ -0,0 +1,32 @@
+/********************************************************************************
+ * Copyright (c) 2023 CEA-List
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+#include "aidge/backend/opencv/stimuli/StimulusImpl_opencv_imread.hpp"
+
+#include <memory>
+#include <stdexcept>
+#include <string>
+
+#include "opencv2/core.hpp"
+
+#include "aidge/data/Tensor.hpp"
+#include "aidge/backend/opencv/utils/Utils.hpp"
+
+Aidge::StimulusImpl_opencv_imread::~StimulusImpl_opencv_imread() noexcept = default;
+
+std::shared_ptr<Aidge::Tensor> Aidge::StimulusImpl_opencv_imread::load() const {
+    cv::Mat cvImg = cv::imread(mDataPath, mColorFlag);
+    if (cvImg.empty()) {
+        throw std::runtime_error("Could not open images file: " + mDataPath);
+    }
+
+    return tensorOpencv(cvImg);
+}
diff --git a/src/utils/Utils.cpp b/src/utils/Utils.cpp
index af7809cdeb064a10d235455207e6475211872360..d27a81361271bf39817d7c8bb230e8a3969eee49 100644
--- a/src/utils/Utils.cpp
+++ b/src/utils/Utils.cpp
@@ -1,15 +1,93 @@
+/********************************************************************************
+ * Copyright (c) 2023 CEA-List
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+#include <cassert>
+#include <opencv2/core.hpp>  // cv::Mat, cv::split
+#include <cstddef>
+#include <cstdint>
+#include <cstring>   // std::memcpy, std::strcmp
+#include <stdexcept> // std::runtime_error
+#include <memory>
+#include <vector>
+
 #include "aidge/backend/opencv/utils/Utils.hpp"
+#include "aidge/backend/opencv/data/DataUtils.hpp"  // detail::CvtoAidge
+#include "aidge/backend/cpu/data/TensorImpl.hpp"
+#include "aidge/backend/opencv/data/TensorImpl.hpp"
+#include "aidge/data/Data.hpp"
+#include "aidge/utils/Types.h"                      // DimSize_t
+
+static Aidge::DataType CVtoAidge(const int matDepth) {
+    Aidge::DataType res;
+    switch (matDepth) {
+        case CV_8U:
+            res = Aidge::DataType::UInt8;
+            break;
+        case CV_8S:
+            res = Aidge::DataType::Int8;
+            break;
+        case CV_16U:
+            res = Aidge::DataType::UInt16;
+            break;
+        case CV_16S:
+            res = Aidge::DataType::Int16;
+            break;
+        case CV_16F:
+            res = Aidge::DataType::Float16;
+            break;
+        case CV_32S:
+            res = Aidge::DataType::Int32;
+            break;
+        case CV_32F:
+            res = Aidge::DataType::Float32;
+            break;
+        case CV_64F:
+            res = Aidge::DataType::Float64;
+            break;
+        default:
+            throw std::runtime_error(
+                "Cannot convert cv::Mat to Tensor: incompatible types.");
+        }
+    return res;
+}
+
+std::shared_ptr<Aidge::Tensor> Aidge::tensorOpencv(cv::Mat mat) {
+    // Get Mat dims
+    const std::vector<DimSize_t> matDims = std::vector<DimSize_t>({static_cast<DimSize_t>(mat.cols),
+                                                            static_cast<DimSize_t>(mat.rows),
+                                                            static_cast<DimSize_t>(mat.channels())});
+    // Create tensor from the dims of the Cv::Mat
+    std::shared_ptr<Tensor> tensor = std::make_shared<Tensor>(matDims);
+    // Set beackend opencv
+    tensor->setBackend("opencv");
+    // Set Data Type
+    tensor->setDataType(CVtoAidge(mat.depth()));
+
+    // Cast the tensorImpl to access setCvMat function
+    TensorImpl_opencv_* tImpl_opencv = dynamic_cast<TensorImpl_opencv_*>(tensor->getImpl().get());
+    tImpl_opencv->setCvMat(mat);
+    return tensor;
+}
+
 
 template <class CV_T>
-void Aidge::convert(const cv::Mat& mat, void* data, size_t offset)
-{   
+void Aidge::convert(const cv::Mat& mat, void* data, std::size_t offset)
+{
     if (mat.isContinuous())
         std::memcpy(reinterpret_cast<void*>(reinterpret_cast<CV_T*>(data) + offset), mat.ptr<CV_T>(), sizeof(CV_T)*(mat.cols*mat.rows));
     else {
         throw std::runtime_error(
                 "Poui pwoup convert not support if matrix not contiguous");
     }
-    
+
 }
 
 
@@ -29,40 +107,15 @@ std::shared_ptr<Aidge::Tensor> Aidge::convertCpu(std::shared_ptr<Aidge::Tensor>
     cv::split(dataOpencv, channels);
 
     // set the datatype of the cpu tensor
-    switch (channels[0].depth()) {
-        case CV_8U:
-            tensorCpu->setDataType(Aidge::DataType::UInt8);
-            break;
-        case CV_8S:
-            tensorCpu->setDataType(Aidge::DataType::Int8);
-            break;
-        case CV_16U:
-            tensorCpu->setDataType(Aidge::DataType::UInt16);
-            break;
-        case CV_16S:
-            tensorCpu->setDataType(Aidge::DataType::Int16);
-            break;
-        case CV_32S:
-            tensorCpu->setDataType(Aidge::DataType::Int32);
-            break;
-        case CV_32F:
-            tensorCpu->setDataType(Aidge::DataType::Float32);
-            break;
-        case CV_64F:
-            tensorCpu->setDataType(Aidge::DataType::Float64);
-            break;
-        default:
-            throw std::runtime_error(
-                "Cannot convert cv::Mat to Tensor: incompatible types.");
-    }
-    
-    // Set backend cpu 
+    tensorCpu->setDataType(CVtoAidge(channels[0].depth()));
+
+    // Set backend cpu
     tensorCpu->setBackend("cpu");
 
     // Convert & copy the cv::Mat into the tensor using the rawPtr of tensor cpu
     std::size_t count = 0;
-    for (std::vector<cv::Mat>::const_iterator itChannel = channels.begin();
-        itChannel != channels.end();
+    for (std::vector<cv::Mat>::const_iterator itChannel = channels.cbegin();
+        itChannel != channels.cend();
         ++itChannel)
     {
         switch ((*itChannel).depth()) {
@@ -94,4 +147,4 @@ std::shared_ptr<Aidge::Tensor> Aidge::convertCpu(std::shared_ptr<Aidge::Tensor>
         ++count;
     }
     return tensorCpu;
-} 
+}
diff --git a/unit_tests/Test_DataProvider.cpp b/unit_tests/Test_DataProvider.cpp
index b956fd2f38c4de6e5cd3028acf797e83e896e0dc..69f4f7b871c60cbbe074e4f8f4a700c7fa68899c 100644
--- a/unit_tests/Test_DataProvider.cpp
+++ b/unit_tests/Test_DataProvider.cpp
@@ -1,3 +1,14 @@
+/********************************************************************************
+ * Copyright (c) 2023 CEA-List
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
 #include <catch2/catch_test_macros.hpp>
 
 #include "aidge/backend/opencv/database/MNIST.hpp"
@@ -11,7 +22,7 @@
 using namespace Aidge;
 
 TEST_CASE("DataProvider instanciation & test mnist","[Data][OpenCV]") {
-    
+
     // Create database
     std::string path = "/data1/is156025/tb256203/dev/eclipse_aidge/aidge/user_tests/test_mnist_database";
     bool train = false;
@@ -20,7 +31,7 @@ TEST_CASE("DataProvider instanciation & test mnist","[Data][OpenCV]") {
     // DataProvider settings
     unsigned int batchSize = 256;
     unsigned int number_batch = std::ceil(mnist.getLen() / batchSize);
-    
+
     // Instanciate the dataloader
     DataProvider provider(mnist, batchSize);
 
@@ -29,7 +40,7 @@ TEST_CASE("DataProvider instanciation & test mnist","[Data][OpenCV]") {
         auto batch = provider.readBatch(i*batchSize);
         auto data_batch_ptr = static_cast<uint8_t*>(batch[0]->getImpl()->rawPtr());
         auto label_batch_ptr = static_cast<int*>(batch[1]->getImpl()->rawPtr());
-        
+
         for (unsigned int s = 0; s < batchSize; ++s){
             auto data = mnist.getItem(i*batchSize+s)[0];
             auto label = mnist.getItem(i*batchSize+s)[1];
diff --git a/unit_tests/Test_Stimuli.cpp b/unit_tests/Test_Stimulus.cpp
similarity index 68%
rename from unit_tests/Test_Stimuli.cpp
rename to unit_tests/Test_Stimulus.cpp
index 7f50012c9d24bb3f023c0a050f6766928631a78d..3510062a7d25c76b04f8d801993189f1d415851a 100644
--- a/unit_tests/Test_Stimuli.cpp
+++ b/unit_tests/Test_Stimulus.cpp
@@ -1,24 +1,35 @@
+/********************************************************************************
+ * Copyright (c) 2023 CEA-List
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
 #include <catch2/catch_test_macros.hpp>
 #include "opencv2/core.hpp"
 #include <opencv2/imgcodecs.hpp>
 #include <memory>
 #include <iostream>
 
-#include "aidge/stimuli/Stimuli.hpp"
+#include "aidge/stimuli/Stimulus.hpp"
 #include "aidge/backend/opencv/data/TensorImpl.hpp"
 #include "aidge/data/Tensor.hpp"
 
 
 using namespace Aidge;
 
-TEST_CASE("Stimuli creation", "[Stimuli][OpenCV]") {
+TEST_CASE("Stimulus creation", "[Stimulus][OpenCV]") {
     SECTION("Instanciation & load an image") {
         //  Load image with imread
         cv::Mat true_mat = cv::imread("/data1/is156025/tb256203/dev/eclipse_aidge/aidge/user_tests/train-images-idx3-ubyte[00001].pgm");
         REQUIRE(true_mat.empty()==false);
 
-        // Create Stimuli
-        Stimuli stimg("/data1/is156025/tb256203/dev/eclipse_aidge/aidge/user_tests/train-images-idx3-ubyte[00001].pgm", true);
+        // Create Stimulus
+        Stimulus stimg("/data1/is156025/tb256203/dev/eclipse_aidge/aidge/user_tests/train-images-idx3-ubyte[00001].pgm", true);
         stimg.setBackend("opencv");
 
         // Load the image in a tensor & save it in memory
@@ -35,7 +46,7 @@ TEST_CASE("Stimuli creation", "[Stimuli][OpenCV]") {
         // This time the tensor is already loaded in memory
         std::shared_ptr<Tensor> tensor_load_2;
         tensor_load_2 = stimg.load();
-        
+
         // Access the cv::Mat with the tensor
         TensorImpl_opencv_* tImpl_opencv_2 = dynamic_cast<TensorImpl_opencv_*>(tensor_load_2->getImpl().get());
 
diff --git a/unit_tests/Test_StimuliImpl_opencv_imread.cpp b/unit_tests/Test_StimulusImpl_opencv_imread.cpp
similarity index 53%
rename from unit_tests/Test_StimuliImpl_opencv_imread.cpp
rename to unit_tests/Test_StimulusImpl_opencv_imread.cpp
index fd5173ba6b85658f0623ae736e8d31c52ce5cc79..f487b4aad36daf2c2a108e3867064a2c51a0d46f 100644
--- a/unit_tests/Test_StimuliImpl_opencv_imread.cpp
+++ b/unit_tests/Test_StimulusImpl_opencv_imread.cpp
@@ -1,29 +1,40 @@
+/********************************************************************************
+ * Copyright (c) 2023 CEA-List
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
 #include <catch2/catch_test_macros.hpp>
 #include "opencv2/core.hpp"
 #include <opencv2/imgcodecs.hpp>
 #include <memory>
 #include <iostream>
 
-#include "aidge/backend/opencv/stimuli/StimuliImpl_opencv_imread.hpp"
+#include "aidge/backend/opencv/stimuli/StimulusImpl_opencv_imread.hpp"
 #include "aidge/backend/opencv/data/TensorImpl.hpp"
 #include "aidge/data/Tensor.hpp"
 
 
 using namespace Aidge;
 
-TEST_CASE("StimuliImpl_opencv_imread creation", "[StimuliImpl_opencv_imread][OpenCV]") {
+TEST_CASE("StimulusImpl_opencv_imread creation", "[StimulusImpl_opencv_imread][OpenCV]") {
     SECTION("Instanciation & load an image") {
         //  Load image with imread
         // cv::Mat true_mat = cv::imread("/data1/is156025/tb256203/dev/eclipse_aidge/aidge/user_tests/Lenna.png");
         cv::Mat true_mat = cv::imread("/data1/is156025/tb256203/dev/eclipse_aidge/aidge/user_tests/train-images-idx3-ubyte[00001].pgm");
         REQUIRE(true_mat.empty()==false);
 
-        // Create StimuliImpl_opencv_imread
-        // StimuliImpl_opencv_imread stImpl("/data1/is156025/tb256203/dev/eclipse_aidge/aidge/user_tests/Lenna.png");
-        StimuliImpl_opencv_imread stImpl("/data1/is156025/tb256203/dev/eclipse_aidge/aidge/user_tests/train-images-idx3-ubyte[00001].pgm");
+        // Create StimulusImpl_opencv_imread
+        // StimulusImpl_opencv_imread stImpl("/data1/is156025/tb256203/dev/eclipse_aidge/aidge/user_tests/Lenna.png");
+        StimulusImpl_opencv_imread stImpl("/data1/is156025/tb256203/dev/eclipse_aidge/aidge/user_tests/train-images-idx3-ubyte[00001].pgm");
         std::shared_ptr<Tensor> tensor_load;
         tensor_load = stImpl.load();
-        
+
         // Access the cv::Mat with the tensor
         TensorImpl_opencv_* tImpl_opencv = dynamic_cast<TensorImpl_opencv_*>(tensor_load->getImpl().get());
 
diff --git a/unit_tests/Test_TensorImpl.cpp b/unit_tests/Test_TensorImpl.cpp
index 7da8cca4b7d5fe638fc7196da08e8d55f93b2475..33c54c08dba4679b26e660a171d4654d5616130f 100644
--- a/unit_tests/Test_TensorImpl.cpp
+++ b/unit_tests/Test_TensorImpl.cpp
@@ -1,3 +1,14 @@
+/********************************************************************************
+ * Copyright (c) 2023 CEA-List
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
 #include <catch2/catch_test_macros.hpp>
 
 #include "aidge/data/Tensor.hpp"
diff --git a/unit_tests/Tests_Utils.cpp b/unit_tests/Tests_Utils.cpp
index d2a80c4f46c5a3bfaedda0cc10b432cc6228a91c..8c613e94a6f18e60434efc78aadf106d4c239d7a 100644
--- a/unit_tests/Tests_Utils.cpp
+++ b/unit_tests/Tests_Utils.cpp
@@ -1,3 +1,14 @@
+/********************************************************************************
+ * Copyright (c) 2023 CEA-List
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
 #include <catch2/catch_test_macros.hpp>
 #include <catch2/catch_template_test_macros.hpp>
 #include <memory>
@@ -25,7 +36,7 @@ cv::Mat createRandomMat(int rows, int cols) {
 // TEMPLATE_TEST_CASE("Opencv Utils", "[Utils][OpenCV]", char, unsigned char, short, unsigned short, int, float, double) {
 // TODO : perform test for char and double
 TEMPLATE_TEST_CASE("Opencv Utils", "[Utils][OpenCV]", signed char, unsigned char, short, unsigned short, int, float, double) {
-    
+
     constexpr int num_test_matrices = 50;
 
     SECTION("Test create tensor from opencv and convert to cpu") {
@@ -42,7 +53,7 @@ TEMPLATE_TEST_CASE("Opencv Utils", "[Utils][OpenCV]", signed char, unsigned char
             for (int c = 0; c < ch; ++c){
                 // Create a random matrix
                 cv::Mat randomMat = createRandomMat<TestType>(rows, cols);
-                // Add each random matrix to the vector 
+                // Add each random matrix to the vector
                 channels.push_back(randomMat);
             }
             // Merge the vector of cv mat into one cv mat
@@ -65,7 +76,7 @@ TEMPLATE_TEST_CASE("Opencv Utils", "[Utils][OpenCV]", signed char, unsigned char
             // Check the matrix inside the tensor coorresponds to the matrix
             TensorImpl_opencv_* tImpl_opencv = dynamic_cast<TensorImpl_opencv_*>(tensorOcv->getImpl().get());
             auto mat_tensor = tImpl_opencv->getCvMat();
-            
+
             REQUIRE(mat_tensor.size() == mat.size());
             REQUIRE(cv::countNonZero(mat_tensor != mat) == 0);