matplotlib의 colormap을 사용하여 2D 데이터를 빠르게 이미지화
11555 단어 이미징파이썬pillowmatplotlib
정리하면
2차원 데이터를 이미징하고 저장하려면 matplotlib.pyplot.imshow()
가 느리므로 matplotlib의 Colormap
를 사용하여 직접 저장할 수 있습니다.
문제 설정
어느 2차원 데이터가 (많이) 있고, 이미지화하고 싶다고 합니다.
import numpy as np
from matplotlib import pyplot as plt
data = np.arange(100).reshape(10,10)
plt.imshow(data)
plt.savefig("test.png")
하지만 아시다시피 matplotlib는 느립니다. 느린 것은 일일이 그래픽 렌더러를 불러 렌더링해 그 결과를 보존하고 있기 때문입니다.
하지만 하고 싶은 것은, data
를 어떠한 변환으로 RGB에 밀어 넣어 보존하는 것입니다.
컬러 맵을 사용할 수 있으면 기쁩니다.
이미지 데이터로 밀어넣기만 하면 다음과 같이 하면 됩니다.
import PIL.Image
def quantize(arr):
arr = np.floor((arr - arr.min()) * 255 / (arr.max() - arr.min())).astype(np.uint8)
img = PIL.Image.fromarray(quantize(data))
img = img.resize([400,400], resample=PIL.Image.NEAREST) #拡大しているだけ
img.save("test.png")
컬러 이미지라면
img = np.zeros(data.shape+(3,), dtype=np.uint8) # キャンバスの用意
img[:,:,0] = 255 # 適当に1
img[:,:,1] = 255 - quantize(data) # 適当に2
img[:,:,2] = quantize(data) # 適当に3
img = PIL.Image.fromarray(img)
img = img.resize([400,400], resample=PIL.Image.NEAREST) #拡大しているだけ
img.save("test.png")
로 「적당」이라고 쓴 곳에 적당한 함수를 할당하면 됩니다만, 그 적당한 함수를 스스로 준비하는 것은 엄격한 것이 있다. 라고 할까 처음에 나타낸 imshow()
의 거리의 그림을 얻으려면 어떻게 하면 좋겠지요, 라고 하는 것이 됩니다.
Colormap 사용법
아시다시피 (?)matplotlib에는 컬러 맵이라는 개념이 있습니다.
값에서 색상 (RGB 값)으로 매핑합니다. plt.imshow(data, cmap=hoge)
등으로 지정할 수 있지요.
컬러맵의 변형에 대해서는 blog: matplotlib의 cmap (colormap) 매개 변수 목록입니다. 등 참조.
matplotlib 내에서 컬러맵은 matplotlib.colors.Colormap
객체로 표현됩니다 1
Colormap
객체는 2d-array를 받고 RGBA 값이 들어있는 3d (2d*4ch) array를 반환하는 함수(에 머리카락이 생긴 것)로 취급할 수 있습니다.matplotlib.pyplot.get_cmap()
에 컬러맵의 이름을 지정하면 Colormap
가 반환됩니다. 즉,
cmap = matplotlib.pyplot.get_cmap(NAME_OF_COLORMAP)
image = Colormap(raw_array)
라는 느낌으로, 화상화가 완성입니다.
이 이미지를 렌더러에 표시시키는 것이 plt.imshow()
그래서, 이미지를 원하면
PIL.Image.fromarray(image).save("filename.png")
쪽이 훨씬 빠르다는 것이 되네요. 예를 보여줍니다.
import matplotlib.pyplot as plt
def minmax(arr):
arr = (arr - arr.min()) / (arr.max() - arr.min())
return arr
cmap = plt.get_cmap("viridis")
data = minmax(data)
img = cmap(data, bytes=True)
img = PIL.Image.fromarray(img)
img = img.resize([220,220], resample=PIL.Image.NEAREST) #拡大しているだけ
img.save("test.png")
어느 2차원 데이터가 (많이) 있고, 이미지화하고 싶다고 합니다.
import numpy as np
from matplotlib import pyplot as plt
data = np.arange(100).reshape(10,10)
plt.imshow(data)
plt.savefig("test.png")
하지만 아시다시피 matplotlib는 느립니다. 느린 것은 일일이 그래픽 렌더러를 불러 렌더링해 그 결과를 보존하고 있기 때문입니다.
하지만 하고 싶은 것은,
data
를 어떠한 변환으로 RGB에 밀어 넣어 보존하는 것입니다.컬러 맵을 사용할 수 있으면 기쁩니다.
이미지 데이터로 밀어넣기만 하면 다음과 같이 하면 됩니다.
import PIL.Image
def quantize(arr):
arr = np.floor((arr - arr.min()) * 255 / (arr.max() - arr.min())).astype(np.uint8)
img = PIL.Image.fromarray(quantize(data))
img = img.resize([400,400], resample=PIL.Image.NEAREST) #拡大しているだけ
img.save("test.png")
컬러 이미지라면
img = np.zeros(data.shape+(3,), dtype=np.uint8) # キャンバスの用意
img[:,:,0] = 255 # 適当に1
img[:,:,1] = 255 - quantize(data) # 適当に2
img[:,:,2] = quantize(data) # 適当に3
img = PIL.Image.fromarray(img)
img = img.resize([400,400], resample=PIL.Image.NEAREST) #拡大しているだけ
img.save("test.png")
로 「적당」이라고 쓴 곳에 적당한 함수를 할당하면 됩니다만, 그 적당한 함수를 스스로 준비하는 것은 엄격한 것이 있다. 라고 할까 처음에 나타낸
imshow()
의 거리의 그림을 얻으려면 어떻게 하면 좋겠지요, 라고 하는 것이 됩니다.Colormap 사용법
아시다시피 (?)matplotlib에는 컬러 맵이라는 개념이 있습니다.
값에서 색상 (RGB 값)으로 매핑합니다. plt.imshow(data, cmap=hoge)
등으로 지정할 수 있지요.
컬러맵의 변형에 대해서는 blog: matplotlib의 cmap (colormap) 매개 변수 목록입니다. 등 참조.
matplotlib 내에서 컬러맵은 matplotlib.colors.Colormap
객체로 표현됩니다 1
Colormap
객체는 2d-array를 받고 RGBA 값이 들어있는 3d (2d*4ch) array를 반환하는 함수(에 머리카락이 생긴 것)로 취급할 수 있습니다.matplotlib.pyplot.get_cmap()
에 컬러맵의 이름을 지정하면 Colormap
가 반환됩니다. 즉,
cmap = matplotlib.pyplot.get_cmap(NAME_OF_COLORMAP)
image = Colormap(raw_array)
라는 느낌으로, 화상화가 완성입니다.
이 이미지를 렌더러에 표시시키는 것이 plt.imshow()
그래서, 이미지를 원하면
PIL.Image.fromarray(image).save("filename.png")
쪽이 훨씬 빠르다는 것이 되네요. 예를 보여줍니다.
import matplotlib.pyplot as plt
def minmax(arr):
arr = (arr - arr.min()) / (arr.max() - arr.min())
return arr
cmap = plt.get_cmap("viridis")
data = minmax(data)
img = cmap(data, bytes=True)
img = PIL.Image.fromarray(img)
img = img.resize([220,220], resample=PIL.Image.NEAREST) #拡大しているだけ
img.save("test.png")
cmap = matplotlib.pyplot.get_cmap(NAME_OF_COLORMAP)
image = Colormap(raw_array)
PIL.Image.fromarray(image).save("filename.png")
import matplotlib.pyplot as plt
def minmax(arr):
arr = (arr - arr.min()) / (arr.max() - arr.min())
return arr
cmap = plt.get_cmap("viridis")
data = minmax(data)
img = cmap(data, bytes=True)
img = PIL.Image.fromarray(img)
img = img.resize([220,220], resample=PIL.Image.NEAREST) #拡大しているだけ
img.save("test.png")
주의점 1.
viridis
는 matplotlib의 기본 컬러맵 이름입니다. 참고 2.
[0.,1.]
(float)인가 [0, 255]
(uint)의 범위의 데이터가 기대되고 있으므로, 먼저 minmax 정규화에 의해 값의 범위를 조정하고 있습니다. 참고 3.
bytes=True
를 지정하면 [0, 255]
의 데이터가 반환됩니다. 기본적으로 [0.,1.]
의 데이터가 반환됩니다. PIL.Image에서는 RGBA는 밖에 [0, 255]
취급할 수 없기 때문에 조금 주의합니다. 이상으로 plt.imshow()와 동등한 것이 매우 빨리 실현될 수 있습니다.
참고: 자작 colormap의 만드는 방법이나 기존 컬러맵의 내용을 분석하는 방법에 대해서는 다음이 상세합니다.
실제로는
Colormap
객체를 상속한 LinearSegmentedColormap
이나 ListedColormap
로서 표현되고 있습니다. ↩Reference
이 문제에 관하여(matplotlib의 colormap을 사용하여 2D 데이터를 빠르게 이미지화), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/tancematrix/items/f64d7918bb3e39e897a4텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)