Program Club

RGB 이미지를 numpy 배열로 변환하는 방법은 무엇입니까?

proclub 2020. 10. 8. 21:48
반응형

RGB 이미지를 numpy 배열로 변환하는 방법은 무엇입니까?


RGB 이미지가 있습니다. 나는 그것을 numpy 배열로 변환하고 싶습니다. 나는 다음을했다

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

모양이없는 배열을 만듭니다. 나는 그것이 iplimage 객체라고 가정합니다.


최신 OpenCV 파이썬 인터페이스를 사용할 수 있습니다 (오락하지 않으면 OpenCV 2.2부터 사용할 수 있습니다). 기본적으로 numpy 배열을 사용합니다.

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

결과:

<type 'numpy.ndarray'>

PIL (Python Imaging Library)과 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'>


늦은 답변이지만 imageio다른 대안 보다 모듈을 선호하게되었습니다.

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

와 유사하게 cv2.imread()기본적으로 numpy 배열을 생성하지만 RGB 형식입니다.


cv.LoadImage 대신 cv.LoadImageM을 사용해야합니다.

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)

오늘부터 가장 좋은 방법은 다음을 사용하는 것입니다.

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

def opencv_image_as_array(im):
  """Interface image from OpenCV's native format to a numpy array.

  note: this is a slicing trick, and modifying the output array will also change
  the OpenCV image data.  if you want a copy, use .copy() method on the array!
  """
  import numpy as np
  w, h, n = im.width, im.height, im.channels
  modes = {1:"L", 3:"RGB"}#, 4:"RGBA"}
  if n not in modes:
    raise StandardError('unsupported number of channels: {0}'.format(n))
  out = np.asarray(im) if n == 1 else np.asarray(im)[:,:,::-1]  ## BGR -> RGB
  return out

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 ()는 모든 파일에서 작동하지만 속도가 느리므로 다른 방법이 실패 할 때만 사용합니다.


또한 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 사이의 부동 소수점 값으로 변환합니다.

When saving images, I noticed I had to cut the out-of-range values myself, or else I ended up with a really gray output. (The gray output was the result of imageio compressing the full range, which was outside of [0, 256), to values that were inside the range.)

There were a couple other oddities, too, which I mentioned in the comments.

참고URL : https://stackoverflow.com/questions/7762948/how-to-convert-an-rgb-image-to-numpy-array

반응형