Відповіді:
Ви можете використовувати новіший інтерфейс python OpenCV (якщо я не помиляюся, він доступний з OpenCV 2.2). Він споконвічно використовує масивні масиви:
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) та 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'
і, дивлячись на документацію для PixelAccess
класу PIL , здається, не пропонуються методи, які дозволять np.array
перетворити основні дані у ndarray
формат. Вам потрібно опустити використання img.load()
та мати справу лише з результатом Image.open(...)
.
Для цього також можна використовувати matplotlib .
from matplotlib.image import imread
img = imread('abc.tiff')
print(type(img))
вихід:
<class 'numpy.ndarray'>
На сьогоднішній день найкраще використовувати:
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'>
Вам потрібно використовувати cv.LoadImageM замість cv.LoadImage:
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)
Під час використання відповіді від Девіда Пула я отримую SystemError із PNG-сірою шкалою та, можливо, іншими файлами. Моє рішення:
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 підтримує інтерфейс масивного масиву. Допоміжна функція може бути підтримана або в кольорах сірого, або в кольоровому зображенні. Це означає, що перетворення 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 для обробки зображень, а не лише для зображення. З цією метою uint8s незручно, тому я перетворюю на значення з плаваючою комою від 0 до 1.
Зберігаючи зображення, я помітив, що мені довелося самостійно вирізати значення поза межами діапазону, інакше я отримав справді сірий вихід. (Вихід сірого кольору був результатом стиснення зображення, яке було за межами [0, 256) до значень, що знаходяться в межах діапазону.)
Було ще пару дивацтв, про які я згадував у коментарях.
Ви можете легко отримати nummy масив 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
завантажте зображення за допомогою наступного синтаксису: -
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
це модуль OpenCV, то слід позначити його як такий. Це посилання може допомогти: opencv.willowgarage.com/documentation/python/…