【问题标题】:AttributeError: module 'scipy.misc' has no attribute 'toimage'AttributeError:模块“scipy.misc”没有属性“toimage”
【发布时间】:2019-12-23 23:42:25
【问题描述】:

在执行以下代码时:

scipy.misc.toimage(output * 255, high=255, low=0, cmin=0, cmax=255).save(
    params.result_dir + 'final/%5d_00_%d_out.png' % (test_id, ratio))

我收到以下错误:

AttributeError: 模块 'scipy.misc' 没有属性 'toimage'

我尝试按照此处所述安装 Pillow:scipy.misc module has no attribute imread? 但同样的错误仍然存​​在。请帮忙。谢谢。

【问题讨论】:

    标签: python scipy python-imaging-library rawimage


    【解决方案1】:

    当前scipy 1.3.0 版不包括​​toimage() 1.3.0 docs here 尝试安装 scipy 1.2.01.1.0 1.2.0 docs here 并包含 toimage()

    【讨论】:

      【解决方案2】:

      scipy.misc.toimage() 函数在 Scipy 1.0.0 中已弃用,并在版本 1.3.0 中完全删除。来自1.3.0 release notes

      来自scipy.interpolate 的函数(splevalsplinesplmakespltopp)和来自scipy.misc 的函数(bytescalefromimageimread、@987654 987654335@、imrotateimsaveimshowtoimage) 已被删除。前一组自 v0.19.0 起已弃用,而后者自 v1.0.0 起已弃用。

      注释链接到 v1.1.0 文档,该文档显示了改用什么;来自scipy.misc.toimage() documentation for v1.1.0

      请直接使用 Pillow 的 Image.fromarray

      然而,这个函数比Image.fromarray 能做的工作更多。你可以port the original function:

      import numpy as np
      from PIL import Image
      
      
      _errstr = "Mode is unknown or incompatible with input array shape."
      
      
      def bytescale(data, cmin=None, cmax=None, high=255, low=0):
          """
          Byte scales an array (image).
          Byte scaling means converting the input image to uint8 dtype and scaling
          the range to ``(low, high)`` (default 0-255).
          If the input image already has dtype uint8, no scaling is done.
          This function is only available if Python Imaging Library (PIL) is installed.
          Parameters
          ----------
          data : ndarray
              PIL image data array.
          cmin : scalar, optional
              Bias scaling of small values. Default is ``data.min()``.
          cmax : scalar, optional
              Bias scaling of large values. Default is ``data.max()``.
          high : scalar, optional
              Scale max value to `high`.  Default is 255.
          low : scalar, optional
              Scale min value to `low`.  Default is 0.
          Returns
          -------
          img_array : uint8 ndarray
              The byte-scaled array.
          Examples
          --------
          >>> from scipy.misc import bytescale
          >>> img = np.array([[ 91.06794177,   3.39058326,  84.4221549 ],
          ...                 [ 73.88003259,  80.91433048,   4.88878881],
          ...                 [ 51.53875334,  34.45808177,  27.5873488 ]])
          >>> bytescale(img)
          array([[255,   0, 236],
                 [205, 225,   4],
                 [140,  90,  70]], dtype=uint8)
          >>> bytescale(img, high=200, low=100)
          array([[200, 100, 192],
                 [180, 188, 102],
                 [155, 135, 128]], dtype=uint8)
          >>> bytescale(img, cmin=0, cmax=255)
          array([[91,  3, 84],
                 [74, 81,  5],
                 [52, 34, 28]], dtype=uint8)
          """
          if data.dtype == np.uint8:
              return data
      
          if high > 255:
              raise ValueError("`high` should be less than or equal to 255.")
          if low < 0:
              raise ValueError("`low` should be greater than or equal to 0.")
          if high < low:
              raise ValueError("`high` should be greater than or equal to `low`.")
      
          if cmin is None:
              cmin = data.min()
          if cmax is None:
              cmax = data.max()
      
          cscale = cmax - cmin
          if cscale < 0:
              raise ValueError("`cmax` should be larger than `cmin`.")
          elif cscale == 0:
              cscale = 1
      
          scale = float(high - low) / cscale
          bytedata = (data - cmin) * scale + low
          return (bytedata.clip(low, high) + 0.5).astype(np.uint8)
      
      
      def toimage(arr, high=255, low=0, cmin=None, cmax=None, pal=None,
                  mode=None, channel_axis=None):
          """Takes a numpy array and returns a PIL image.
          This function is only available if Python Imaging Library (PIL) is installed.
          The mode of the PIL image depends on the array shape and the `pal` and
          `mode` keywords.
          For 2-D arrays, if `pal` is a valid (N,3) byte-array giving the RGB values
          (from 0 to 255) then ``mode='P'``, otherwise ``mode='L'``, unless mode
          is given as 'F' or 'I' in which case a float and/or integer array is made.
          .. warning::
              This function uses `bytescale` under the hood to rescale images to use
              the full (0, 255) range if ``mode`` is one of ``None, 'L', 'P', 'l'``.
              It will also cast data for 2-D images to ``uint32`` for ``mode=None``
              (which is the default).
          Notes
          -----
          For 3-D arrays, the `channel_axis` argument tells which dimension of the
          array holds the channel data.
          For 3-D arrays if one of the dimensions is 3, the mode is 'RGB'
          by default or 'YCbCr' if selected.
          The numpy array must be either 2 dimensional or 3 dimensional.
          """
          data = np.asarray(arr)
          if np.iscomplexobj(data):
              raise ValueError("Cannot convert a complex-valued array.")
          shape = list(data.shape)
          valid = len(shape) == 2 or ((len(shape) == 3) and
                                      ((3 in shape) or (4 in shape)))
          if not valid:
              raise ValueError("'arr' does not have a suitable array shape for "
                               "any mode.")
          if len(shape) == 2:
              shape = (shape[1], shape[0])  # columns show up first
              if mode == 'F':
                  data32 = data.astype(np.float32)
                  image = Image.frombytes(mode, shape, data32.tostring())
                  return image
              if mode in [None, 'L', 'P']:
                  bytedata = bytescale(data, high=high, low=low,
                                       cmin=cmin, cmax=cmax)
                  image = Image.frombytes('L', shape, bytedata.tostring())
                  if pal is not None:
                      image.putpalette(np.asarray(pal, dtype=np.uint8).tostring())
                      # Becomes a mode='P' automagically.
                  elif mode == 'P':  # default gray-scale
                      pal = (np.arange(0, 256, 1, dtype=np.uint8)[:, np.newaxis] *
                             np.ones((3,), dtype=np.uint8)[np.newaxis, :])
                      image.putpalette(np.asarray(pal, dtype=np.uint8).tostring())
                  return image
              if mode == '1':  # high input gives threshold for 1
                  bytedata = (data > high)
                  image = Image.frombytes('1', shape, bytedata.tostring())
                  return image
              if cmin is None:
                  cmin = np.amin(np.ravel(data))
              if cmax is None:
                  cmax = np.amax(np.ravel(data))
              data = (data*1.0 - cmin)*(high - low)/(cmax - cmin) + low
              if mode == 'I':
                  data32 = data.astype(np.uint32)
                  image = Image.frombytes(mode, shape, data32.tostring())
              else:
                  raise ValueError(_errstr)
              return image
      
          # if here then 3-d array with a 3 or a 4 in the shape length.
          # Check for 3 in datacube shape --- 'RGB' or 'YCbCr'
          if channel_axis is None:
              if (3 in shape):
                  ca = np.flatnonzero(np.asarray(shape) == 3)[0]
              else:
                  ca = np.flatnonzero(np.asarray(shape) == 4)
                  if len(ca):
                      ca = ca[0]
                  else:
                      raise ValueError("Could not find channel dimension.")
          else:
              ca = channel_axis
      
          numch = shape[ca]
          if numch not in [3, 4]:
              raise ValueError("Channel axis dimension is not valid.")
      
          bytedata = bytescale(data, high=high, low=low, cmin=cmin, cmax=cmax)
          if ca == 2:
              strdata = bytedata.tostring()
              shape = (shape[1], shape[0])
          elif ca == 1:
              strdata = np.transpose(bytedata, (0, 2, 1)).tostring()
              shape = (shape[2], shape[0])
          elif ca == 0:
              strdata = np.transpose(bytedata, (1, 2, 0)).tostring()
              shape = (shape[2], shape[1])
          if mode is None:
              if numch == 3:
                  mode = 'RGB'
              else:
                  mode = 'RGBA'
      
          if mode not in ['RGB', 'RGBA', 'YCbCr', 'CMYK']:
              raise ValueError(_errstr)
      
          if mode in ['RGB', 'YCbCr']:
              if numch != 3:
                  raise ValueError("Invalid array shape for mode.")
          if mode in ['RGBA', 'CMYK']:
              if numch != 4:
                  raise ValueError("Invalid array shape for mode.")
      
          # Here we know data and mode is correct
          image = Image.frombytes(mode, shape, strdata)
          return image
      

      这可以根据使用的实际参数进一步简化;例如,您的示例代码不使用 pal 参数。

      【讨论】:

        【解决方案3】:

        卸载 SciPy 并安装 SciPy v1.2.0

        $ pip uninstall scipy
        
        $ pip install scipy==1.2.0
        

        【讨论】:

          【解决方案4】:

          试试 !pip install scipy==1.1.0

          这对我有用。

          【讨论】:

            【解决方案5】:

            @Martijn Pieters 为我工作,但我也找到了另一种可能更适合某些人的解决方案。您还可以使用下面的代码导入 keras.preprocessing.image, array_to_img 而不是 scipy.misc.toimage,正如@Martijn Pieters 已经提到的那样,它在 Scipy 1.0.0 中已被弃用。

            所以作为一个使用 keras API 处理图像转换的例子:

            # example of converting an image with the Keras API
            from keras.preprocessing.image import load_img
            from keras.preprocessing.image import img_to_array
            from keras.preprocessing.image import array_to_img
            
            # load the image
            img = load_img('image.jpg')
            print(type(img))
            
            # convert to numpy array
            img_array = img_to_array(img)
            print(img_array.dtype)
            print(img_array.shape)
            
            # convert back to image
            img_pil = array_to_img(img_array)
            print(type(img_pil))
            
            # show image
            fig = plt.figure()
            ax = fig.add_subplot()
            ax.imshow(img_pil)
            

            并使用 keras 保存图像:

            from keras.preprocessing.image import save_img
            from keras.preprocessing.image import load_img
            from keras.preprocessing.image import img_to_array
            
            # load image
            img = load_img('image.jpg')
            
            # convert image to a numpy array
            img_array = img_to_array(img)
            
            # save the image with a new filename
            save_img('image_save.jpg', img_array)
            
            # load the image to confirm it was saved correctly
            img = load_img('image_save.jpg')
            
            print(type(img))
            print(img.format)
            print(img.mode)
            print(img.size)
            

            【讨论】:

              猜你喜欢
              • 2013-02-27
              • 2020-07-22
              • 2018-04-14
              • 2019-02-18
              • 1970-01-01
              • 1970-01-01
              • 2019-12-06
              • 2020-01-01
              相关资源
              最近更新 更多