RGB görüntüsü numpy dizisine nasıl dönüştürülür?


113

RGB resmim var. Onu numpy dizisine dönüştürmek istiyorum. Aşağıdakileri yaptım

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

Şekli olmayan bir dizi oluşturur. Bunun bir iplimage nesnesi olduğunu varsayıyorum.


2
Eğer cvOpenCV modülüdür, o zaman gibi etiketlemelisiniz. Bu bağlantı yardımcı olabilir: opencv.willowgarage.com/documentation/python/…
Paul

Yanıtlar:


143

Daha yeni OpenCV python arayüzünü kullanabilirsiniz (yanılmıyorsam, OpenCV 2.2'den beri mevcuttur). Doğal olarak numpy dizileri kullanır:

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

sonuç:

<type 'numpy.ndarray'>

95
Cv2.imread () işlevinin RGB değil BGR'de bir numpy dizi döndürdüğüne dikkat edin.
pnd

7
@pnd yorumunuz kutsaldır!
Eduardo Pignatelli

4
Gelecekteki referans için: $ pip install opencv-pythonopencv'yi yüklemek için
Kyle C

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

8
OpenCV modetartışmayı bırakmış görünüyor . Güncellenmiş bir yöntem için aşağıdaki cevabıma bakın.
belvederef

73

PIL (Python Görüntüleme Kitaplığı) ve Numpy birlikte iyi çalışır.

Aşağıdaki işlevleri kullanıyorum.

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' biraz çirkin çünkü gelen verileri [0,255] 'e kırpıyorum, bayta dönüştürüyorum ve ardından gri tonlamalı bir görüntü oluşturuyorum. Çoğunlukla gri renkte çalışıyorum.

Bir RGB görüntüsü şöyle bir şey olabilir:

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

1
Bu, bir hatayla başarısız olur TypeError: long() argument must be a string or a number, not 'PixelAccess've PIL'in PixelAccesssınıfına ilişkin belgelere bakıldığında np.array, temel verilerini bir ndarrayformata dönüştürmeyi sağlayacak yöntemler sunmadığı görülmektedir . Kullanımını atlamanız img.load()ve yalnızca sonucuyla ilgilenmeniz gerekir Image.open(...).
ely

İmg.load (), PIL'de tuhaf bir önbelleğe alma sorunu etrafında çalışır. Veriler açıkça gerekmedikçe yüklenmeyecektir. Yastık ile çalışırken (PIL çatalı) "Görüntüyü içe aktar" ı "PIL içe aktarım Görüntüsünden" olarak değiştirmek dışında bu örnek benim için hala işe yarıyor.
David Poole

OpenCV'yi değil, yalnızca PIL'i kullanmak için oy verin. Yine de OpenCV'ye karşı değilim.
progyammer


20

Bugünden itibaren en iyi seçeneğiniz şunları kullanmaktır:

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

imgUyuşmuş bir tür dizisi göreceksiniz :

<class 'numpy.ndarray'>

12

Geç cevap, ama imageiomodülü diğer alternatiflere tercih etmeye geldim

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

Benzer şekilde cv2.imread(), varsayılan olarak, ancak RGB biçiminde bir uyuşmuş dizi üretir.


7

Cv.LoadImage yerine cv.LoadImageM kullanmanız gerekir:

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)

Çok teşekkürler ... Ayrıca 'cv.CreateImage (genişlik, yükseklik, kanallar)' kullanarak bir görüntü oluşturursam ... Bunu nasıl numpy dizisine dönüştürülebilir?
Shan

Bunun yerine cv.CreateMat kullanmanız veya cv.CreateMat kullanmanız ve cv.CvtColor veya benzeri bir şey kullanarak görüntüden mat'a kopyalamanız gerektiğini düşünüyorum. Paul'ün yukarıda gönderdiği bağlantıya bir göz atın.
Justin Peel 1411

3

David Poole'un cevabını kullanırken gri tonlamalı PNG'ler ve belki başka dosyalar içeren bir SystemError alıyorum. Benim çözümüm:

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' )

Aslında img.getdata () tüm dosyalar için çalışır, ancak daha yavaştır, bu yüzden onu yalnızca diğer yöntem başarısız olduğunda kullanırım.


2

OpenCV görüntü formatı, numpy dizi arayüzünü destekler. Gri tonlamalı veya renkli görüntüleri desteklemek için yardımcı bir işlev yapılabilir. Bu, BGR -> RGB dönüşümünün, görüntü verilerinin tam bir kopyası değil, uyuşmuş bir dilimle rahatlıkla yapılabileceği anlamına gelir.

Not: Bu adım adım bir numaradır, bu nedenle çıktı dizisini değiştirmek OpenCV görüntü verilerini de değiştirecektir. Bir kopya istiyorsanız .copy(), dizide yöntemi kullanın !

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

Ayrıca imageio'yu da kullandım, ancak aşağıdaki makineyi ön ve son işlem için yararlı buldum:

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)

Gerekçe, sadece görüntüyü görüntülemek için değil, görüntü işleme için numpy kullanıyorum. Bu amaçla, uint8'ler gariptir, bu yüzden 0 ile 1 arasında değişen kayan nokta değerlerine dönüştürüyorum.

Görüntüleri kaydederken, aralık dışı değerleri kendim kesmem gerektiğini fark ettim, yoksa gerçekten gri bir çıktı elde ettim. (Gri çıktı, imageio'nun [0, 256) dışındaki tüm aralığı aralığın içindeki değerlere sıkıştırmasının sonucuydu.)

Yorumlarda bahsettiğim birkaç tuhaflık daha vardı.


1

numpyVe kullanarak kolayca rgb görüntü dizisi elde edebilirsiniz.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

görüntüyü aşağıdaki sözdizimini kullanarak yükleyin: -

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.