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


113

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

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

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


2
cvがOpenCVモジュールの場合は、そのようにタグ付けする必要があります。このリンクは役立つことがあります。 opencv.willowgarage.com/documentation/python/...を
ポール・

回答:


142

新しいOpenCV pythonインターフェイスを使用できます(私が誤っていない場合は、OpenCV 2.2以降で使用できます)。numpy配列をネイティブに使用します。

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

結果:

<type 'numpy.ndarray'>

94
cv2.imread()はRGBではなくBGRでnumpy配列を返すことに注意してください。
2017年

6
@あなたのコメントは神聖です!
エドゥアルドピニャテリ

4
今後の参考のために: $ pip install opencv-pythonopencvをインストールする
カイルC

2
TypeError: 'mode' is an invalid keyword argument for imread()
Rishabh Agrahari

8
OpenCVはmode議論を落としたようです。更新された方法については、以下の私の回答を参照してください。
ベルベデレフ

73

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 )

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

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

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

1
これはエラーで失敗し、TypeError: long() argument must be a string or a number, not 'PixelAccess'PILのPixelAccessクラスのドキュメントを見ると、np.array基礎となるデータをndarray形式に変換できるメソッドを提供していないようです。の使用を省略img.load()して、の結果のみを処理する必要がありImage.open(...)ます。
エリー

img.load()は、PILの奇妙なキャッシュの問題を回避します。明示的に必要になるまで、データは読み込まれません。この例は、Pillow(PILフォーク)での作業時に「インポートイメージ」を「PILインポートイメージから」に変更することを除いて、引き続き機能します。
デビッドプール

OpenCVではなくPILのみを使用することに賛成します。私はOpenCVに反対しているわけではありません。
progyammer


19

今日の時点で、最善の策は以下を使用することです。

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

imgのタイプの配列が表示されます。

<class 'numpy.ndarray'>

12

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

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

と同じようにcv2.imread()、デフォルトでは派手な配列を生成しますが、RGB形式です。


7

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)

どうもありがとう...また、 'cv.CreateImage(width、height、channels)'を使用して画像を作成した場合、それを確認するのを手伝っていただけませんか...どのようにnumpy配列に変換できますか?
シャン

代わりにcv.CreateMatを使用するか、cv.CreateMatを使用して、画像からマットにcv.CvtColorまたは類似のものを使用してコピーする必要があると思います。Paulが上記に投稿したリンクを見てください。
Justin Peel

3

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()はすべてのファイルで機能しますが、速度が遅いため、他のメソッドが失敗した場合にのみ使用します。


2

OpenCV画像形式は、numpy配列インターフェースをサポートしています。ヘルパー関数を作成して、グレースケールまたはカラー画像をサポートできます。つまり、BGR-> RGB変換は、画像データの完全なコピーではなく、派手なスライスで簡単に実行できます。

注:これはストライドトリックなので、出力配列を変更するとOpenCV画像データも変更されます。コピーが必要な場合.copy()は、配列のメソッドを使用してください!

import numpy as np

def img_as_array(im):
    """OpenCV's native format to a numpy array view"""
    w, h, n = im.width, im.height, im.channels
    modes = {1: "L", 3: "RGB", 4: "RGBA"}
    if n not in modes:
        raise Exception('unsupported number of channels: {0}'.format(n))
    out = np.asarray(im)
    if n != 1:
        out = out[:, :, ::-1]  # BGR -> RGB conversion
    return out

1

私も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が範囲内の値に圧縮した結果です。)

他にもいくつか奇妙な点がありましたが、私はそれをコメントで述べました。


1

あなたはとを使用numpyして簡単にrgb画像のnumpy配列を取得できますImage from PIL

import numpy as np
from PIL import Image
import matplotlib.pyplot as plt

im = Image.open('*image_name*') #These two lines
im_arr = np.array(im) #are all you need
plt.imshow(im_arr) #Just to verify that image array has been constructed properly

0

次の構文を使用してイメージをロードします。

from keras.preprocessing import image

X_test=image.load_img('four.png',target_size=(28,28),color_mode="grayscale"); #loading image and then convert it into grayscale and with it's target size 
X_test=image.img_to_array(X_test); #convert image into array
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.