diff --git a/README.md b/README.md
index 60aeaba404909fd20d03aa5fb1acb77c97f6a70a..8f94e4e06fe6f80621aceb2a9c52197c2021a99f 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@ Requirements:
 pip install pyotb
 ```
 
-For Python>=3.6, latest version available is pyotb 1.2.3. For Python 3.5, latest version available is pyotb 1.2.2
+For Python>=3.6, latest version available is pyotb 1.3. For Python 3.5, latest version available is pyotb 1.2.2
 
 ## Quickstart: running an OTB app as a oneliner
 pyotb has been written so that it is more convenient to run an application in Python.
diff --git a/pyotb/__init__.py b/pyotb/__init__.py
index 91fbcf51727b7f17fcc63176cdec241c228a190c..8a2994661fa57dc2b62d3f8728fd53fe18c828ae 100644
--- a/pyotb/__init__.py
+++ b/pyotb/__init__.py
@@ -1,5 +1,5 @@
 # -*- coding: utf-8 -*-
-__version__ = "1.2.3"
+__version__ = "1.3"
 
 from .apps import *
 from .core import App, Output, Input, get_nbchannels, get_pixel_type
diff --git a/pyotb/core.py b/pyotb/core.py
index 8465840a98f619ecabdc0a7b8cfd619345717001..cb74243294c7b88b01f66bd83791c22f7e3916a4 100644
--- a/pyotb/core.py
+++ b/pyotb/core.py
@@ -114,7 +114,7 @@ class otbObject(ABC):
         elif isinstance(key, tuple) and len(key) == 2:
             # adding a 3rd dimension
             key = key + (slice(None, None, None),)
-        (rows, cols, channels) = key
+        (cols, rows, channels) = key
         return Slicer(self, rows, cols, channels)
 
     def __getattr__(self, name):
@@ -231,16 +231,32 @@ class otbObject(ABC):
     def __hash__(self):
         return id(self)
 
-    def __array__(self):
+    def to_numpy(self, propagate_pixel_type=False):
         """
-        This is called when running np.asarray(pyotb_object)
+        Export a pyotb object to numpy array
         :return: a numpy array
         """
         if hasattr(self, 'output_parameter_key'):  # this is for Input, Output, Operation, Slicer
             output_parameter_key = self.output_parameter_key
         else:  # this is for App
             output_parameter_key = self.output_parameters_keys[0]
-        return self.app.ExportImage(output_parameter_key)['array']
+        # we make a copy to avoid some segfault if the reference to app is lost
+        array = self.app.ExportImage(output_parameter_key)['array'].copy()
+        if propagate_pixel_type:
+            otb_pixeltype = get_pixel_type(self)
+            otb_pixeltype_to_np_pixeltype = {0: np.uint8, 1: np.int16, 2: np.uint16, 3: np.int32, 4: np.uint32,
+                                             5: np.float32, 6: np.float64}
+            np_pixeltype = otb_pixeltype_to_np_pixeltype[otb_pixeltype]
+            array = array.astype(np_pixeltype)
+        return array
+
+    def __array__(self):
+        """
+        This is called when running np.asarray(pyotb_object)
+        :return: a numpy array
+        """
+
+        return self.to_numpy()
 
     def __array_ufunc__(self, ufunc, method, *inputs, **kwargs):
         """
@@ -303,7 +319,7 @@ class Slicer(otbObject):
         :param channels:
         """
         # Initialize the app that will be used for writing the slicer
-        app = App('ExtractROI', {"in": input, 'mode': 'extent'})
+        app = App('ExtractROI', {"in": input, 'mode': 'extent'}, propagate_pixel_type=True)
         self.output_parameter_key = 'out'
         self.name = 'Slicer'
 
@@ -363,7 +379,7 @@ class Input(otbObject):
     Class for transforming a filepath to pyOTB object
     """
     def __init__(self, filepath):
-        self.app = App('ExtractROI', filepath).app
+        self.app = App('ExtractROI', filepath, propagate_pixel_type=True).app
         self.output_parameter_key = 'out'
         self.filepath = filepath
         self.name = f'Input from {filepath}'
@@ -412,7 +428,7 @@ class App(otbObject):
         # This will only store if app has been excuted, then find_output() is called when accessing the property
         self._finished = val
 
-    def __init__(self, appname, *args, execute=True, image_dic=None, otb_stdout=True, **kwargs):
+    def __init__(self, appname, *args, execute=True, image_dic=None, otb_stdout=True, propagate_pixel_type=False, **kwargs):
         """
         Enables to run an otb app as a oneliner. Handles in-memory connection between apps
         :param appname: name of the app, e.g. 'Smoothing'
@@ -426,6 +442,9 @@ class App(otbObject):
                           the result of app.ExportImage(). Use it when the app takes a numpy array as input.
                           See this related issue for why it is necessary to keep reference of object:
                           https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/-/issues/1824
+        :param otb_stdout: whether to print logs of the app
+        :param propagate_pixel_type: Propagate the pixel type from inputs to output. If several inputs, the type of an
+                                     arbitrary input is considered. If several outputs, all will have the same type.
         :param kwargs: keyword arguments e.g. il=['input1.tif', App_object2, App_object3.out], out='output.tif'
         """
         self.appname = appname
@@ -446,6 +465,8 @@ class App(otbObject):
         # Run app, write output if needed, update `finished` property
         if execute:
             self.execute()
+        if propagate_pixel_type:
+            self.__propagate_pixel_type()
         # 'Saving' outputs as attributes, i.e. so that they can be accessed like that: App.out
         # Also, thanks to __getitem__ method, the outputs can be accessed as App["out"]. This is useful when the key
         # contains reserved characters such as a point eg "io.out"
@@ -587,6 +608,21 @@ class App(otbObject):
         else:
             self.app.SetParameterValue(param, obj)
 
+    def __propagate_pixel_type(self):
+        """Propagate the pixel type from inputs to output. If several inputs, the type of an arbitrary input
+           is considered. If several outputs, all outputs will have the same type."""
+        pixel_type = None
+        for param in self.parameters.values():
+            try:
+                pixel_type = get_pixel_type(param)
+            except TypeError:
+                pass
+        if not pixel_type:
+            logger.warning(f"{self.name}: Could not propagate pixel type from inputs to output, " +
+                           f"no valid input found")
+        else:
+            for out_key in self.output_parameters_keys:
+                self.app.SetParameterOutputImagePixelType(out_key, pixel_type)
 
     def __with_output(self):
         """Check if App has any output parameter key"""
@@ -890,26 +926,27 @@ def get_pixel_type(inp):
     """
     Get the encoding of input image pixels
     :param inp: a filepath, or any pyotb object
-    :return pixel_type: either a dict of pixel types (in case of an App where there are several outputs)
-                        format is like `otbApplication.ImagePixelType_uint8'
+    :return pixel_type: format is like `otbApplication.ImagePixelType_uint8'. For an App with several outputs, only the
+                        pixel type of the first output is returned
+
     """
     if isinstance(inp, str):
         # Executing the app, without printing its log
-        info = App("ReadImageInfo", inp, otb_stdout=False)
-        datatype = info.GetParameterInt("datatype")  # which is such as short, float...
-        dataype_to_pixeltype = {
-            'unsigned_char': 'uint8', 'short': 'int16', 'unsigned_short': 'uint16', 
-            'int': 'int32', 'unsigned_int': 'uint32', 'long': 'int32', 'ulong': 'uint32', 
-            'float': 'float','double': 'double'
-        }
+        try:
+            info = App("ReadImageInfo", inp, otb_stdout=False)
+        except Exception:  # this happens when we pass a str that is not a filepath
+            raise TypeError(f'Could not get the pixel type of `{inp}`. Not a filepath or wrong filepath')
+        datatype = info.GetParameterString("datatype")  # which is such as short, float...
+        dataype_to_pixeltype = {'unsigned_char': 'uint8', 'short': 'int16', 'unsigned_short': 'uint16',
+                                'int': 'int32', 'unsigned_int': 'uint32', 'long': 'int32', 'ulong': 'uint32',
+                                'float': 'float', 'double': 'double'}
         pixel_type = dataype_to_pixeltype[datatype]
         pixel_type = getattr(otb, f'ImagePixelType_{pixel_type}')
-    elif isinstance(inp, (Input, Output, Operation)):
-        pixel_type = inp.GetImageBasePixelType(inp.output_parameter_key)
+    elif isinstance(inp, (Input, Output, Operation, Slicer)):
+        pixel_type = inp.GetParameterOutputImagePixelType(inp.output_parameter_key)
     elif isinstance(inp, App):
-        if len(inp.output_parameters_keys) > 1:
-            pixel_type = inp.GetImageBasePixelType(inp.output_parameters_keys[0])
-        else:
-            pixel_type = {key: inp.GetImageBasePixelType(key) for key in inp.output_parameters_keys}
+        pixel_type = inp.GetParameterOutputImagePixelType(inp.output_parameters_keys[0])
+    else:
+        raise TypeError(f'Could not get the pixel type. Not supported type: {inp}')
 
     return pixel_type
diff --git a/setup.py b/setup.py
index b0762e5c16670c8e1d63a35670e96e08eff46826..5c78ce9a3336dfb238dc817badb9d35db127cc92 100644
--- a/setup.py
+++ b/setup.py
@@ -6,7 +6,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
 
 setuptools.setup(
     name="pyotb",
-    version="1.2.3",
+    version="1.3",
     author="Nicolas Narçon",
     author_email="nicolas.narcon@gmail.com",
     description="Library to enable easy use of the Orfeo Tool Box (OTB) in Python",