Esteja ciente de que cv2.imread () retorna um array numpy em BGR e não em RGB.
PND
6
@pnd seu comentário é sagrado!
Eduardo Pignatelli
4
Para referência futura: $ pip install opencv-pythonpara instalar o opencv
Kyle C
2
TypeError: 'mode' is an invalid keyword argument for imread()
Rishabh Agrahari
8
OpenCV parece ter abandonado o modeargumento. Veja minha resposta abaixo para um método atualizado.
belvederef
73
PIL (Python Imaging Library) e Numpy funcionam bem juntos.
Eu uso as seguintes funções.
from PIL importImageimport 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 )
O 'Image.fromarray' é um pouco feio porque recortei os dados recebidos para [0,255], converti em bytes e, em seguida, crio uma imagem em tons de cinza. Eu trabalho principalmente em cinza.
Isso falha com um erro TypeError: long() argument must be a string or a number, not 'PixelAccess'e , examinando a documentação da PixelAccessclasse PIL , não parece oferecer métodos que permitiriam np.arrayconverter seus dados subjacentes em um ndarrayformato. Você precisa omitir o uso de img.load()e lidar apenas com o resultado de Image.open(...).
ely
O img.load () contorna um problema estranho de cache no PIL. Os dados não seriam carregados até que fossem explicitamente necessários. O exemplo ainda funciona para mim, com exceção de alterar "import Image" para "from PIL import Image" ao trabalhar com Pillow (o fork PIL).
David Poole
Voto positivo para usar apenas PIL e não OpenCV. Não sou contra o OpenCV.
Muito obrigado ... Você também poderia me ajudar a descobrir que se eu criar uma imagem usando 'cv.CreateImage (largura, altura, canais)' ... Como ela poderia ser convertida em array numpy?
Shan,
Eu acho que você precisa usar cv.CreateMat em vez disso ou usar cv.CreateMat e copiar da imagem para o tapete usando cv.CvtColor ou algo semelhante. Dê uma olhada no link que Paul postou acima.
Justin Peel,
3
Ao usar a resposta de David Poole, recebo um SystemError com PNGs em escala de cinza e talvez outros arquivos. Minha solução é:
import numpy as np
from PIL importImage
img =Image.open( filename )try:
data = np.asarray( img, dtype='uint8')exceptSystemError:
data = np.asarray( img.getdata(), dtype='uint8')
Na verdade, img.getdata () funcionaria para todos os arquivos, mas é mais lento, então eu o uso apenas quando o outro método falha.
O formato de imagem OpenCV suporta a interface numpy array. Uma função auxiliar pode ser criada para suportar imagens em tons de cinza ou coloridas. Isso significa que a conversão BGR -> RGB pode ser feita convenientemente com uma fatia numpy, não uma cópia completa dos dados da imagem.
Nota: este é um truque de passos largos, portanto, modificar a matriz de saída também mudará os dados da imagem OpenCV. Se você quiser uma cópia, use o .copy()método no array!
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 notin modes:raiseException('unsupported number of channels: {0}'.format(n))
out = np.asarray(im)if n !=1:
out = out[:,:,::-1]# BGR -> RGB conversionreturn out
Eu também adotei a imageio, mas achei a seguinte máquina útil para pré e pós-processamento:
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/255def 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)
O raciocínio é que estou usando o numpy para processamento de imagens, não apenas para exibição de imagens. Para este propósito, uint8s são estranhos, então eu converto em valores de ponto flutuante que variam de 0 a 1.
Ao salvar imagens, percebi que eu mesmo tive que cortar os valores fora do intervalo, ou então acabei com uma saída realmente cinza. (A saída cinza foi o resultado da compressão de imageio em toda a faixa, que estava fora de [0, 256), para valores que estavam dentro da faixa.)
Havia algumas outras curiosidades também, que mencionei nos comentários.
Você pode obter uma matriz numpy de imagem rgb facilmente usando numpyeImage from PIL
import numpy as np
from PIL importImageimport 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
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
cv
for o módulo OpenCV, você deve marcá-lo como tal. Este link pode ajudar: opencv.willowgarage.com/documentation/python/…Respostas:
Você pode usar a interface python OpenCV mais recente (se não me engano, ela está disponível desde o OpenCV 2.2). Ele usa matrizes numpy nativamente:
resultado:
fonte
$ pip install opencv-python
para instalar o opencvTypeError: 'mode' is an invalid keyword argument for imread()
mode
argumento. Veja minha resposta abaixo para um método atualizado.PIL (Python Imaging Library) e Numpy funcionam bem juntos.
Eu uso as seguintes funções.
O 'Image.fromarray' é um pouco feio porque recortei os dados recebidos para [0,255], converti em bytes e, em seguida, crio uma imagem em tons de cinza. Eu trabalho principalmente em cinza.
Uma imagem RGB seria algo como:
fonte
TypeError: long() argument must be a string or a number, not 'PixelAccess'
e , examinando a documentação daPixelAccess
classe PIL , não parece oferecer métodos que permitiriamnp.array
converter seus dados subjacentes em umndarray
formato. Você precisa omitir o uso deimg.load()
e lidar apenas com o resultado deImage.open(...)
.Você também pode usar matplotlib para isso.
resultado:
<class 'numpy.ndarray'>
fonte
A partir de hoje, sua melhor aposta é usar:
Você verá
img
que será uma matriz numpy do tipo:fonte
Resposta tardia, mas passei a preferir o
imageio
módulo às outras alternativasSemelhante a
cv2.imread()
, ele produz uma matriz numpy por padrão, mas no formato RGB.fonte
Você precisa usar cv.LoadImageM em vez de cv.LoadImage:
fonte
Ao usar a resposta de David Poole, recebo um SystemError com PNGs em escala de cinza e talvez outros arquivos. Minha solução é:
Na verdade, img.getdata () funcionaria para todos os arquivos, mas é mais lento, então eu o uso apenas quando o outro método falha.
fonte
O formato de imagem OpenCV suporta a interface numpy array. Uma função auxiliar pode ser criada para suportar imagens em tons de cinza ou coloridas. Isso significa que a conversão BGR -> RGB pode ser feita convenientemente com uma fatia numpy, não uma cópia completa dos dados da imagem.
Nota: este é um truque de passos largos, portanto, modificar a matriz de saída também mudará os dados da imagem OpenCV. Se você quiser uma cópia, use o
.copy()
método no array!fonte
Eu também adotei a imageio, mas achei a seguinte máquina útil para pré e pós-processamento:
O raciocínio é que estou usando o numpy para processamento de imagens, não apenas para exibição de imagens. Para este propósito, uint8s são estranhos, então eu converto em valores de ponto flutuante que variam de 0 a 1.
Ao salvar imagens, percebi que eu mesmo tive que cortar os valores fora do intervalo, ou então acabei com uma saída realmente cinza. (A saída cinza foi o resultado da compressão de imageio em toda a faixa, que estava fora de [0, 256), para valores que estavam dentro da faixa.)
Havia algumas outras curiosidades também, que mencionei nos comentários.
fonte
Você pode obter uma matriz numpy de imagem rgb facilmente usando
numpy
eImage from PIL
fonte
carregue a imagem usando a seguinte sintaxe: -
fonte