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.