回答:
新しいOpenCV pythonインターフェイスを使用できます(私が誤っていない場合は、OpenCV 2.2以降で使用できます)。numpy配列をネイティブに使用します。
import cv2
im = cv2.imread("abc.tiff",mode='RGB')
print type(im)
結果:
<type 'numpy.ndarray'>
$ pip install opencv-python
opencvをインストールする
TypeError: 'mode' is an invalid keyword argument for imread()
mode
議論を落としたようです。更新された方法については、以下の私の回答を参照してください。
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" )
TypeError: long() argument must be a string or a number, not 'PixelAccess'
PILのPixelAccess
クラスのドキュメントを見ると、np.array
基礎となるデータをndarray
形式に変換できるメソッドを提供していないようです。の使用を省略img.load()
して、の結果のみを処理する必要がありImage.open(...)
ます。
これには、matplotlibを使用することもできます。
from matplotlib.image import imread
img = imread('abc.tiff')
print(type(img))
出力:
<class 'numpy.ndarray'>
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)
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()はすべてのファイルで機能しますが、速度が遅いため、他のメソッドが失敗した場合にのみ使用します。
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
私も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が範囲内の値に圧縮した結果です。)
他にもいくつか奇妙な点がありましたが、私はそれをコメントで述べました。
あなたはとを使用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
cv
がOpenCVモジュールの場合は、そのようにタグ付けする必要があります。このリンクは役立つことがあります。 opencv.willowgarage.com/documentation/python/...を