본문 바로가기
Error 잡기

PIL 이미지를 NumPy로 변환하여 저장하지 마세요.

by davidlds 2024. 3. 5.
반응형

딥러닝 특히 CV 분야를 공부하다 보면 다양한 형태의 이미지를 다뤄야한다.

특히 파이토치 객체, 넘파이 객체, PIL 객체 를 왔다갔다 해야한다.

또 jpg를 쓸지, png를 쓸지, RGB 3채널일때, R 1채널일때 등 다양한 문제가 생긴다.

 

그런데 내가 오늘 발견한 것은 PIL이미지를 NumPy로 변환할때 치명적인 에러가 발생하는 것이다.

결론적으로 PIL 이미지는 그대로 저장하거나 파이토치 함수로 변환해야만 에러가 나지 않는다.

 

RGB를 각각 따로 딥러닝 한 뒤 R, G, B를 저장하여 값을 보고 있었다.

파이토치 객체에서 부터 넘어와 저장해야 하기 때문에 이런 저런 변환을 거친 뒤 저장하는데,

 

이렇게 저장했다. (이 코드는 내가 작성한 것은 아니고 선행 연구자가 작성한 것이다.)

 

그런데 이렇게 저장하니 값이 너무 터무니 없이 나왔다.

그래서 중간중간의 과정을 들여다봤다.

 

아래 코드는 20x20 크기의 pixel value = 12의 이미지를 저장하는 과정이다.(파이토치에선 12/255인 0.479)

x0 = torch.full((1, 20, 20), 0.04790814220905304)
x1 = torch.clip(x0,0.,1.).squeeze(0)
x2 = T.ToPILImage()(x1)
x3 = np.array(x2)
plt.imsave('./save/test.jpg', x3, cmap='gray')
x4 = plt.imread('./save/test.jpg')

flattened_tensor = x0.view(-1)
unique, counts = torch.unique(flattened_tensor, return_counts=True)
most_frequent_index = torch.argmax(counts)
most_frequent_number = unique[most_frequent_index]
print("x0 Main Value:", most_frequent_number.item())

flattened_tensor = x1.view(-1)
unique, counts = torch.unique(flattened_tensor, return_counts=True)
most_frequent_index = torch.argmax(counts)
most_frequent_number = unique[most_frequent_index]
print("x1 Main Value:", most_frequent_number.item())

from collections import Counter
pixel_values = list(x2.getdata())
pixel_freq = Counter(pixel_values)
most_common_pixel = pixel_freq.most_common(1)[0][0]
print("x2 Main Value:", most_common_pixel)

unique_values, counts = np.unique(x3, return_counts=True)
most_frequent_index = np.argmax(counts)
most_frequent_value = unique_values[most_frequent_index]
print("x3 Main Value:", most_frequent_value)

x4_flat = x4.flatten().astype(int)
mode_value = np.bincount(x4_flat).argmax()
print("x4 Main Value:", mode_value)

 

결과는 아래와 같다.

 

잘 진행되다가 imsave를 하는 순간(x4에서) 변했다.

 

이는 원래 넘파이가 가지고 있던 정보들이 PIL 이미지로 변환되고 다시 넘파이로 변환되면서 꼬였기 때문이다.

따라서 아래처럼 PIL 내장 함수로 바로 저장하면,

 

결과가 잘 나온다.

 

PIL 이미지와 NumPy 변환 간에 주의와 검증이 필요해보인다.

 

끝.

반응형