[英]how to convert an RGB image to numpy array?
我有一個 RGB 圖像。 我想將它轉換為 numpy 數組。 我做了以下
im = cv.LoadImage("abc.tiff")
a = numpy.asarray(im)
它創建一個沒有形狀的數組。 我假設它是一個 iplimage object。
您可以使用較新的 OpenCV python 接口(如果我沒記錯的話,它從 OpenCV 2.2 開始可用)。 它本身使用 numpy 數組:
import cv2
im = cv2.imread("abc.tiff",mode='RGB')
print type(im)
結果:
<type 'numpy.ndarray'>
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" )
您也可以為此使用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
將是一個 numpy 類型的數組:
<class 'numpy.ndarray'>
遲到的答案,但與其他替代方案imageio
,我更喜歡imageio
模塊
import imageio
im = imageio.imread('abc.tiff')
與cv2.imread()
類似,它默認生成一個 numpy 數組,但采用 RGB 形式。
您需要使用 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)
當使用 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() 可用於所有文件,但速度較慢,因此我僅在其他方法失敗時才使用它。
您可以通過使用Image from PIL
numpy
和Image from PIL
輕松獲取 rgb 圖像的 numpy 數組
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
OpenCV 圖像格式支持 numpy 數組接口。 可以使輔助函數支持灰度或彩色圖像。 這意味着可以使用 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 進行圖像處理,而不僅僅是圖像顯示。 為此,uint8s 很笨拙,因此我將其轉換為 0 到 1 之間的浮點值。
保存圖像時,我注意到我必須自己刪除超出范圍的值,否則我最終會得到一個非常灰色的輸出。 (灰色輸出是 imageio 將整個范圍(在 [0, 256)之外壓縮到范圍內的值的結果。)
還有其他一些奇怪的事情,我在評論中提到過。
使用 Keras:
from keras.preprocessing import image
img = image.load_img('path_to_image', target_size=(300, 300))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
images = np.vstack([x])
我們可以使用以下function的open CV2來轉換BGR 2 RGB格式。
RBG_Image = cv2.cvtColor(Image, cv.COLOR_BGR2RGB)
嘗試對將圖像加載到 numpy 數組的選項進行計時,它們非常相似。 為了簡單和速度,去plt.imread
。
def time_this(function, times=100):
cum_time = 0
for t in range(times):
st = time.time()
function()
cum_time += time.time() - st
return cum_time / times
import matplotlib.pyplot as plt
def load_img_matplotlib(img_path):
return plt.imread(img_path)
import cv2
def load_img_cv2(img_path):
return cv2.cvtColor(cv2.imread(img_path), cv2.COLOR_BGR2RGB)
from PIL import Image
import numpy as np
def load_img_pil(img_path):
img = Image.open(img_path)
img.load()
return np.asarray( img, dtype="int32" )
if __name__=='__main__':
img_path = 'your_image_path'
for load_fn in [load_img_pil, load_img_cv2, load_img_matplotlib]:
print('-'*20)
print(time_this(lambda: load_fn(img_path)), 10000)
結果:
--------------------
0.0065201687812805175 10000 PIL, as in [the second answer][1]https://stackoverflow.com/a/7769424/16083419)
--------------------
0.0053211402893066405 10000 CV2
--------------------
0.005320906639099121 10000 matplotlib
你可以試試下面的方法。 這是文檔的鏈接。
tf.keras.preprocessing.image.img_to_array(img, data_format=None, dtype=None)
from PIL import Image
img_data = np.random.random(size=(100, 100, 3))
img = tf.keras.preprocessing.image.array_to_img(img_data)
array = tf.keras.preprocessing.image.img_to_array(img)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.