2006년 10월 07일
SciPy
Matlab은 수학 관련 연산을 많이 해야 하는 코드를 짤 때, 특히 매트릭스 연산을 해야 할 때에는 정말 편하게 쓸 수 있는 강력한 언어(?)이다. 강력한 하이레벨 언어이면서 엄청나게 많은 기능을 제공한다. 특히 이미지 프로세싱 관련 기능은 너무나도 편리해 자주 사용해 왔다.
다만 상용 소프트웨어란 점과 매트랩 언어 자체가 수학 연산에만 특화되어 있기 때문에, 다른 언어에서 사용하던 문법 같은 것을 사용하기 어렵다는 단점이 있다. 두번째 단점은 C++이나 다른 OOP 랭귀지를 많이 사용하던 유저가 매트랩을 사용할 경우 은근히 불편하게 느껴지는 점이다. (나만 그런지도 모르겠다.) 또한 첫번째 단점은 돈없는 나같은 유저에게는 너무나 크리티컬한 단점이다.
어둠의 경로를 이용하기엔 양심의 가책을 느낀 나머지, 매트랩을 대체할 것을 찾다가 SciPy라는 패키지를 알게 되었고, 현재에는 이것을 너무나 유용하게 사용하고 있다. SciPy는 파이썬에서 수학이나 과학과 관련된 연산을 쉽게 할 수 있도록 여러 기능을 제공해 주는 패키지로 다음 사이트에서 자세한 정보를 얻을 수 있다.
http://www.scipy.org
그러나 이미지 프로세싱과 관련된 기능은 매트랩보다 부족한게 사실이다. 매트랩에서 제공하는 기능 중 가장 빈번하게 이용하는 plot기능과 이미지 입출력을 이용할 수가 없다. 이를 이용해 두가지 패키지를 더 이용해야 하는데, 하나는 matplotlib이고 하나는 PIL(Python Image Library)이다.
matplotlib - http://matplotlib.sourceforge.net
PIL - http://www.pythonware.com/products/pil/
matplotlib은 홈페이지의 소개에서도 알 수 있듯이 매트랩 스타일의 plotting 라이브러리이다. 또한 scipy의 array와 완벽히 호환되므로 매우 편리하게 사용할 수 있다. 홈페이지에 있는 스크린샷을 통해 얼마나 멋지게 그래프 등을 그릴 수 있는지 확인할 수 있다. 물론 plotting 외에도 여러 기능들을 제공하지만, 나는 전혀 이용하지 않고 있다. 아무래도 이것저것 섞어 쓰면 불편하기 마련이다.
matplotlib에서도 imread라는 함수로 이미지 파일을 로드하는 것을 지원하지만, 파일 포맷이 매우 제한되어 있다. 또한 이미지를 파일로 저장하는 기능을 제공하지 않는다는 치명적인 단점이 있다. 그래서 찾게 된 것이 바로 PIL이다.
PIL은 파이썬 이미지 프로세싱 라이브러리로 이미지 프로세싱에 관련된 기능들을 제공한다. 다만 scipy와 데이터 타입이 호환되지 않기 때문에 같이 쓰기가 번거롭다. 또한 PIL은 이미지 프로세싱에 관한 기능만을 제공하며, 현재까지의 버전에서는 이미지를 배열처럼 다루기 힘들기 때문에, (앞으론 가능할 것이라 한다.) 여러 다양한 연산을 편하게 하기가 쉽지가 않다. 따라서 내 경우에는 지금까지는 단순히 PIL을 이미지를 입출력하는 데만 사용해 왔다.
그러나 이것도 쉽지가 않은게, 현재까지의 PIL에서는 PIL 이미지를 scipy의 배열로, 또 scipy의 배열에서 PIL이미지로 컨버팅하는 기능을 제공하지 않는다. 다음 버전에서는 제공할 것이라고는 하지만, 아직은 개발 버전으로나 이용할 수 있을 뿐이다. 또한 scipy 홈페이지의 http://www.scipy.org/Cookbook/PIL 에서 제공하는 패치는 완벽하게 동작하지 않았다. scipy의 array를 이미지로 바꾸는 Image.fromarray() 함수는 모든 데이터 타입에 대해 동작하지 않는 것으로 기억한다. 예를 들어 64bit floating point 형은 지원하지 않는다. 그리고 코드 자체에 버그도 있다. 또한 이미지를scipy의 어레이로 바꾸는 함수는 알 수 없는 이유로 파이썬 전체가 죽어버렸다.
그래서 그 패치를 바탕으로 간략하게 작성한 코드가 다음과 같다.
다만 상용 소프트웨어란 점과 매트랩 언어 자체가 수학 연산에만 특화되어 있기 때문에, 다른 언어에서 사용하던 문법 같은 것을 사용하기 어렵다는 단점이 있다. 두번째 단점은 C++이나 다른 OOP 랭귀지를 많이 사용하던 유저가 매트랩을 사용할 경우 은근히 불편하게 느껴지는 점이다. (나만 그런지도 모르겠다.) 또한 첫번째 단점은 돈없는 나같은 유저에게는 너무나 크리티컬한 단점이다.
어둠의 경로를 이용하기엔 양심의 가책을 느낀 나머지, 매트랩을 대체할 것을 찾다가 SciPy라는 패키지를 알게 되었고, 현재에는 이것을 너무나 유용하게 사용하고 있다. SciPy는 파이썬에서 수학이나 과학과 관련된 연산을 쉽게 할 수 있도록 여러 기능을 제공해 주는 패키지로 다음 사이트에서 자세한 정보를 얻을 수 있다.
http://www.scipy.org
그러나 이미지 프로세싱과 관련된 기능은 매트랩보다 부족한게 사실이다. 매트랩에서 제공하는 기능 중 가장 빈번하게 이용하는 plot기능과 이미지 입출력을 이용할 수가 없다. 이를 이용해 두가지 패키지를 더 이용해야 하는데, 하나는 matplotlib이고 하나는 PIL(Python Image Library)이다.
matplotlib - http://matplotlib.sourceforge.net
PIL - http://www.pythonware.com/products/pil/
matplotlib은 홈페이지의 소개에서도 알 수 있듯이 매트랩 스타일의 plotting 라이브러리이다. 또한 scipy의 array와 완벽히 호환되므로 매우 편리하게 사용할 수 있다. 홈페이지에 있는 스크린샷을 통해 얼마나 멋지게 그래프 등을 그릴 수 있는지 확인할 수 있다. 물론 plotting 외에도 여러 기능들을 제공하지만, 나는 전혀 이용하지 않고 있다. 아무래도 이것저것 섞어 쓰면 불편하기 마련이다.
matplotlib에서도 imread라는 함수로 이미지 파일을 로드하는 것을 지원하지만, 파일 포맷이 매우 제한되어 있다. 또한 이미지를 파일로 저장하는 기능을 제공하지 않는다는 치명적인 단점이 있다. 그래서 찾게 된 것이 바로 PIL이다.
PIL은 파이썬 이미지 프로세싱 라이브러리로 이미지 프로세싱에 관련된 기능들을 제공한다. 다만 scipy와 데이터 타입이 호환되지 않기 때문에 같이 쓰기가 번거롭다. 또한 PIL은 이미지 프로세싱에 관한 기능만을 제공하며, 현재까지의 버전에서는 이미지를 배열처럼 다루기 힘들기 때문에, (앞으론 가능할 것이라 한다.) 여러 다양한 연산을 편하게 하기가 쉽지가 않다. 따라서 내 경우에는 지금까지는 단순히 PIL을 이미지를 입출력하는 데만 사용해 왔다.
그러나 이것도 쉽지가 않은게, 현재까지의 PIL에서는 PIL 이미지를 scipy의 배열로, 또 scipy의 배열에서 PIL이미지로 컨버팅하는 기능을 제공하지 않는다. 다음 버전에서는 제공할 것이라고는 하지만, 아직은 개발 버전으로나 이용할 수 있을 뿐이다. 또한 scipy 홈페이지의 http://www.scipy.org/Cookbook/PIL 에서 제공하는 패치는 완벽하게 동작하지 않았다. scipy의 array를 이미지로 바꾸는 Image.fromarray() 함수는 모든 데이터 타입에 대해 동작하지 않는 것으로 기억한다. 예를 들어 64bit floating point 형은 지원하지 않는다. 그리고 코드 자체에 버그도 있다. 또한 이미지를scipy의 어레이로 바꾸는 함수는 알 수 없는 이유로 파이썬 전체가 죽어버렸다.
그래서 그 패치를 바탕으로 간략하게 작성한 코드가 다음과 같다.
# SciPy Utility Module
import sys
import scipy
import PIL.Image
def PIL_to_array(pil_image):
arr = scipy.array(pil_image.getdata())
if len(arr.shape) == 2:
ncomponents = arr.shape[1]
arr = arr.reshape(pil_image.size[1], pil_image.size[0], arr.shape[1])
else:
arr = arr.reshape(pil_image.size[1], pil_image.size[0])
return scipy.flipud(arr)
def __fromarray(obj, mode=None):
if sys.byteorder == 'little':
_ENDIAN = '<'
else:
_ENDIAN = '>'
arr = obj.__array_interface__
shape = arr['shape']
ndim = len(shape)
try:
strides = arr['strides']
except KeyError:
strides = None
if mode is None:
typestr = arr['typestr']
if not (typestr[0] == '|' or typestr[0]== _ENDIAN or
typestr[1:] not in ['u1', 'b1', 'i4', 'f4']):
raise TypeError, "cannot handle data-type"
typestr = typestr[1:3]
if typestr == 'i4':
mode = 'I'
elif typestr == 'f4':
mode = 'F'
elif typestr == 'b1':
mode = '1'
elif ndim == 2:
mode = 'L'
elif ndim == 3:
mode = 'RGB'
elif ndim == 4:
mode = 'RGBA'
else:
raise TypeError, "Do not understand data."
ndmax = 4
bad_dims = 0
if mode in ['1', 'L', 'I', 'P', 'F']:
ndmax = 2
elif mode == 'RGB':
ndmax = 3
if ndim > ndmax:
raise ValueError, "Too many dimensions."
size = shape[:2][::-1]
if strides is not None:
obj = obj.tostring()
return PIL.Image.frombuffer(mode, size, obj)
def array_to_PIL(arr, convert_to_byte = False):
if convert_to_byte == True:
return __fromarray((arr * 255.0).astype(byte))
else:
return __fromarray(arr.astype(float32))
if __name__ == "__main__":
from pylab import *
a = PIL.Image.open('waterlilies.jpg')
img = PIL_to_array(a) / 255.0
figure()
imshow(img, origin='image')
show()
또한 이를 바탕으로 imread와 imwrite를 간단하게 새로 작성해서 이용하고 있다.
이렇게 scipy와 matplotlib, PIL을 이용하면 파이썬의 강력한 기능들과 깔끔한 문법들을 이용하면서 또한 매트랩 부럽지 않은 다양한 연산들을 쉽게 이용할 수 있다.
여러 오픈 소스 프로젝트가 그렇듯이 잘 되어 있는 듯하면서도 제대로 되어 있지 않은 documentation때문에 적응하는 기간이 좀 있었지만, 현재에는 이 세가지 패키지를 이용하면서 아주 행복하게 여러가지 코딩을 하고 있다.
마지막으로 한가지를 더 소개하고 글을 마치고자 한다. 바로 Python enthough edition이다.
http://code.enthought.com/enthon/
파이썬 인터프리터와 함께 여러가지 다양한 패키지들을 한꺼번에 설치해서 이용할 수 있는 아주 편리한 패키지이다. 아직 파이썬이 깔려 있지 않다면 이것을 이용하면 아주 편리하게 파이썬 인터프리터와 다양한 패키지들을 한번에 설치할 수 있다. 다만 아직 파이썬 2.5 등의 새로운 내용들이 아직 적용되어 있지 않다는 단점이 있지만, 큰 문제는 아닐 것이다.
# by | 2006/10/07 00:58 | 공부 | 트랙백(1) | 덧글(1)





☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
제목 : SciPy
SciPy Matlab은 수학 관련 연산을 많이 해야 하는 코드를 짤 때, 특히 매트릭스 연산을 해야 할 때에는 정말 편하게 쓸 수 있는 강력한 언어(?)이다. 강력한 하이레벨 언어이면서 엄청나게 많은 기능을 제공한다. 특히 이미지 프로세싱 관련 기능은 너무나도 편리해 자주 사용해 왔다.다만 상용 소프트웨어란 점과 매트랩 언어 자체가 수학 연산에만 특화되어 있기 때문에, 다른 언어에서 사용하던 문법 같은 것을 사용하기 어렵다......more