PIL과 opencv에서의 image 변환.
필요성
tensorflow 나, pytorch등에서 에서의 image
를 이용한 이미지 로딩의 경우,PIL.Image.Image
를 기본적으로 이미지를 위한 class 타입으로 사용함.
from tensorflow.keras.preprocessing import image
image_tf = image.load_img('test.gif')
print(f'type : {type(image_tf)}')
결과는 다음과 같음
type : <class 'PIL.Image.Image'>
opencv
or scikit-image
를 이용한 전처리 수행하고 싶은 경우에는 이 두 라이브러리의 데이터 간 변환이 필요함.
간단한 전처리가 아닌 computer vision 분야의 알고리즘을 이용하려고 할 경우, opencv 또는 scikit-image 가 많이 사용되기 때문임.
둘 패키지 모두 NumPy의 ndarray를 사용하여 이미지를 다룸: channel 순서만 차이가 있음 (BGR or RGB)
방법
방법 자체는 매우 간단한데,opencv
의 python라이브러리는 실제로 numpy
의 ndarray
를 기본 이미지 class로 사용하기 때문에PIL.Image.Image
와 numpy
의 array간의 변환을 이용하면 된다.
- 단, color image를 처리할 때 opencv의 경우 BGR Color-space를 기본으로 사용한다는 점을 주의할 것.
변환은 다음 코드를 참조하자.
import numpy as np
from PIL import Image
import cv2
def PIL2opencv(pilimage):
return cv2.cvtColor(np.array(pilimage),cv2.COLOR_RGB2BGR)
def opencv2PIL(cv2image):
return Image.fromarray(cv2image)
이들을 테스트하기 위해, 특정 url에서 image를 로드하여 opencv
의 이미지 타입인 numpy.ndarray
로 읽고 이들간의 변환을 해보면 다음과 같다.
import urllib
import cv2
import numpy as np
import urllib.request
from PIL import Image
url_str = 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTmYnfxeVfCSqG514OtmU_Lw4VKmqDuf-UU9A&usqp=CAU'
# url에서 byte단위로 읽어들인 경우, opencv에서 사용가능한 image 로딩하는 방법.
resp = urllib.request.urlopen(url_str)
img1D = np.asarray(bytearray(resp.read()), dtype=np.uint8)
print(f'type : {type(img1D)}, shape:{img1D.shape}')
cv2img = cv2.imdecode(img1D,cv2.IMREAD_COLOR)
print(f'type : {type(cv2img)}, shape:{cv2img.shape}')
pilimage = opencv2PIL(cv2img)
print(f'type : {type(pilimage)}')
cv2img_new = PIL2opencv(pilimage)
print(f'type : {type(cv2img_new)}')
pilimage.save('test.gif')
결과는 다음과 같다.
type : <class 'numpy.ndarray'>, shape:(9527,)
type : <class 'numpy.ndarray'>, shape:(254, 199, 3)
type : <class 'PIL.Image.Image'>
type : <class 'numpy.ndarray'>
이를 matplotlib.pyplot
을 이용하여 살펴보면 다음과 같음.
import matplotlib.pyplot as plt
matimg = plt.imread('test.gif')
plt.subplot(1,3,1)
plt.imshow(matimg)
plt.axis('off')
plt.subplot(1,3,2)
plt.imshow(np.array(pilimage))
plt.axis('off')
plt.subplot(1,3,3)
plt.imshow(cv2img_new[:,:,::-1])
plt.axis('off')
plt.show()
tensorflow.keras.preprocessing.image
내부적으로 PIL
을 이용하여 이미지를 로딩한다.
from tensorflow.keras.preprocessing import image
image_tf = image.load_img('test.gif')
print(f'type : {type(image_tf)}')
결과는 다음과 같음.
type : <class 'PIL.Image.Image'>
Tensorflow 라이브러리를 이용한 URL통한 이미지 로드.
tensorflow.keras.utils.get_file
을 이용한다.
import tensorflow as tf
import os
import matplotlib.pyplot as plt
url_str = 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTmYnfxeVfCSqG514OtmU_Lw4VKmqDuf-UU9A&usqp=CAU'
bname = os.path.basename(url_str)
bname = bname.split('?')[0]
img_url = tf.keras.utils.get_file(bname, origin=url_str)
pilimg = tf.keras.preprocessing.image.load_img(img_url, target_size=(224,224))
print(img_url) #/root/.keras/datasets/img
os.remove(img_url) # Remove the cached file
#plt.imshow(np.array(pilimg))
#plt.axis('off')
#plt.show()
결과는 다음과 같음.
Downloading data from https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTmYnfxeVfCSqG514OtmU_Lw4VKmqDuf-UU9A&usqp=CAU
16384/9527 [===================================================] - 0s 0us/step
24576/9527 [=============================================================================] - 0s 0us/step
/root/.keras/datasets/images
같이 보면 좋은 자료들
'Programming > DIP' 카테고리의 다른 글
[OpenCV] cv2.cvtColor (0) | 2022.07.14 |
---|---|
[Math] Hessian: Summary (0) | 2022.06.05 |
Conda backup for DIP 2021 (0) | 2021.09.18 |
NumPy : sum, mean, std, and so on (0) | 2021.09.17 |
NumPy 검색 (0) | 2021.09.11 |