본문 바로가기

Python

이미지 읽는 방법 / cv.imdecode( ), io.BytesIO( )

320x100
320x100

 

 

이미지를 읽는 방법에는 여러가지가 있다. OpenCV를 사용해서 읽는 방법도 있고, PIL를 이용해서 읽는 방법도 있다. 그리고 최근에는 이미지 파일을 Binary 형태로 읽은 다음 ( = byte 단위로 읽는다는 의미 ) jpg로 decoding하는 방법도 있다는 걸 알게 됐다. 하나씩 그 사용법에 대해 정리해보도록 하자.

 

1. cv2.imread( )

import cv2
path = './test_image.jpg'
img = cv2.imread(path)

내가 주로 사용하는 함수다.

 

2. PIL.Image.open( )

from PIL import Image
path = './test_image.jpg'
img = Image.open(path)​

가끔 코드 검색을 하다 보면 접하게 되는 함수다. 직접적으로 사용하진 않는다.

 

 

 

 

 

이제 Binary 형태로 이미지 데이터 읽은 다음 decode하는 방법에 대해 알아보자.

cv2.imdecode( ) 함수를 사용하는 방식과 io.BytesIO( )를 사용하는 방식으로 나뉜다. 

1. cv2.imdecode( )

import cv2
path = './test_image.jpg'
with open(path, 'rb') as f:
    data = f.read()
encoded_img = np.fromstring(data, dtype = np.uint8)
img = cv2.imdecode(encoded_img, cv2.IMREAD_COLOR)​
  • [Line 4]
    이미지를 binary mode로 읽었기 때문에 data에는 byte 단위로 데이터가 저장된다.
  • [Line 5]
    np.fromarray( )에 대해 아직 정확하게 이해하진 못했지만,
    출력해보면 data 정보를 uint8 형태로 반환하는 것을 확인할 수 있다.
  • [Line 6]
    cv2.imdecoded( ) 함수를 통해 1D-array인 encoded_img를 3D-array로 만들어준다.
    encoded_img를 어떤 흐름으로 3차원 이미지로 변환하는 지는 아직 알아내지 못했다
  • 정리해보면,
    byte 단위로 읽은 이미지는 np.fromarray( )와 cv2.imdecode( ) 함수를 통해 이미지로 변환해 줄 수 있다.

 

2. io.BytesIO( )

import io
from PIL import Image
path = './test_image.jpg'
with open(path, 'rb') as f:
    data = f.read()
data_io = io.BytesIO(data)
img = Image.open(data_io)​
  • [Line 6,7]
    Image.open( ) 함수에는 보통 이미지 파일 경로를 매개변수로 넘겨주지만,
    때에 따라선 io.BytesIO( ) 객체를 넘겨줄 수도 있다.
  • io.BytedIO( ) 객체를 넘겨주면 객체 내에 저장된 bytes 정보를 불러와 이미지로 읽어주는 흐름인 것 같다.

 

3. cv2.imdecode( ) vs io.BytesIO( )

두 방법 중 연산 속도를 비교해보면 cv2.imdecode( )가 더 빠른 것을 확인할 수 있다.

import cv2, io, time
from PIL import Image
path = './test_image.jpg'
with open(path, 'rb') as f:
    data = f.read()

time_cv = time.time()
encoded_img = np.fromstring(data, dtype = np.uint8)
img_cv = cv2.imdecode(encoded_img, cv2.IMREAD_COLOR)
print('openCV :', time.time() - time_cv)

time_pil = time.time()
data_io = io.BytesIO(data)
img_pil = Image.open(data_io)
print('PIL :', time.time() - time_pil)​

 

< 코드 실행 결과 >

 

 


 

 

추가로 이미지를 binary 형태로 변환하는 방법에 대해서도 정리해두고자 한다.

import cv2, io, time
from PIL import Image
path = './test_image.jpg'
img_cv = cv2.imread(path)
img_pil = Image.open(path)

binary_cv = cv2.imencode('.PNG', img_cv)[1].tobytes()

output = io.BytesIO()
img_pil.save(output, 'PNG')
binary_pil = output.getvalue()​

 

< 코드 실행 결과 >

 

 

 

! 광고와 함께 끝 !

728x90