web-dev-qa-db-ja.com

RGB画像をnumpy配列に変換する方法は?

RGB画像があります。 numpy配列に変換したいです。私は次のことをしました

im = cv.LoadImage("abc.tiff")
a = numpy.asarray(im)

形状のない配列を作成します。 iplimageオブジェクトだと思います。

77
Shan

新しいOpenCV pythonインターフェイスを使用できます(私が間違えなければ、OpenCV 2.2以降で使用可能です)。ネイティブでnumpy配列を使用します:

import cv2
im = cv2.imread("abc.tiff",mode='RGB')
print type(im)

結果:

<type 'numpy.ndarray'>
103
Andrey Kamaev

PIL(Python Imaging Library)とNumpyはうまく連携します。

私は次の機能を使用します。

from PIL import Image
import numpy as np

def load_image( infilename ) :
    img = Image.open( infilename )
    img.load()
    data = np.asarray( img, dtype="int32" )
    return data

def save_image( npdata, outfilename ) :
    img = Image.fromarray( np.asarray( np.clip(npdata,0,255), dtype="uint8"), "L" )
    img.save( outfilename )

着信データを[0,255]にクリップし、バイトに変換してからグレースケールイメージを作成するため、「Image.fromarray」は少しいです。私は主に灰色で働いています。

RGB画像は次のようになります。

 outimg = Image.fromarray( ycc_uint8, "RGB" )
 outimg.save( "ycc.tif" )
56
David Poole

これには matplotlib を使用することもできます。

from matplotlib.image import imread

img = imread('abc.tiff')
print(type(img))

出力:<class 'numpy.ndarray'>

37

遅い答えですが、私は他の選択肢よりimageioモジュールを好むようになりました

import imageio
im = imageio.imread('abc.tiff')

cv2.imread()と同様に、デフォルトではnumpy配列を生成しますが、RGB形式です。

10
slizb

Cv.LoadImageの代わりにcv.LoadImageMを使用する必要があります。

In [1]: import cv
In [2]: import numpy as np
In [3]: x = cv.LoadImageM('im.tif')
In [4]: im = np.asarray(x)
In [5]: im.shape
Out[5]: (487, 650, 3)
6
Justin Peel

現在、あなたの最善の策は以下を使用することです:

img = cv2.imread(image_path)   # reads an image in the BGR format
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)   # BGR -> RGB

imgは型のnumpy配列になります:

<class 'numpy.ndarray'>
6
belvederef
def opencv_image_as_array(im):
  """Interface image from OpenCV's native format to a numpy array.

  note: this is a slicing trick, and modifying the output array will also change
  the OpenCV image data.  if you want a copy, use .copy() method on the array!
  """
  import numpy as np
  w, h, n = im.width, im.height, im.channels
  modes = {1:"L", 3:"RGB"}#, 4:"RGBA"}
  if n not in modes:
    raise StandardError('unsupported number of channels: {0}'.format(n))
  out = np.asarray(im) if n == 1 else np.asarray(im)[:,:,::-1]  ## BGR -> RGB
  return out
2
wim

David Pooleからの回答を使用すると、グレースケールのPNGやその他のファイルでSystemErrorが発生します。私の解決策は次のとおりです。

import numpy as np
from PIL import Image

img = Image.open( filename )
try:
    data = np.asarray( img, dtype='uint8' )
except SystemError:
    data = np.asarray( img.getdata(), dtype='uint8' )

実際にはimg.getdata()はすべてのファイルで機能しますが、速度が遅いため、他の方法が失敗した場合にのみ使用します。

1
daign

私もimageioを採用しましたが、前処理と後処理に次の機械が役立つことがわかりました。

import imageio
import numpy as np

def imload(*a, **k):
    i = imageio.imread(*a, **k)
    i = i.transpose((1, 0, 2))  # x and y are mixed up for some reason...
    i = np.flip(i, 1)  # make coordinate system right-handed!!!!!!
    return i/255


def imsave(i, url, *a, **k):
    # Original order of arguments was counterintuitive. It should
    # read verbally "Save the image to the URL" — not "Save to the
    # URL the image."

    i = np.flip(i, 1)
    i = i.transpose((1, 0, 2))
    i *= 255

    i = i.round()
    i = np.maximum(i, 0)
    i = np.minimum(i, 255)

    i = np.asarray(i, dtype=np.uint8)

    imageio.imwrite(url, i, *a, **k)

その理由は、単に画像を表示するだけでなく、画像処理にnumpyを使用しているからです。このため、uint8は扱いにくいため、0〜1の範囲の浮動小数点値に変換します。

画像を保存するときに、範囲外の値を自分でカットする必要があることに気付きました。そうしないと、本当にグレーの出力になってしまいました。 (グレーの出力は、[0、256]の外側にある全範囲を、範囲内の値にimageio圧縮した結果です。)

他にもいくつかの奇妙な点があり、コメントで言及しました。

0