看了<<用python做科学计算>>后, 研究了一下图像处理, opencv很好, 但很不pythonic , PIL有点弱, 后来发现了这个 scikits.image , pypi上得10分的图像处理库, 但安装过程很坎坷, 最后总算搞定, 想和大家分享.
scikits 是针对scipy写的一些toolkits, 相当于matlab里的工具箱了, 开源社区真是强大啊!
scikits.image 是其中的图像处理工具箱, 具有以下优势:
1.对OpenCV进行了封装, 使得cvMat类型在其内部隐藏, 包括图像处理函数的输入和输出, 其外部接口全部用numpy的ndarray表示, 这样就可以方便使用numpy和scipy的强大功能, 包括scipy的ndimage Processing库, 自己写个算法也方便多了. 这个很强大!
>> import scikits.image.io as io
>> lena=io.imread("d:/lena.jpg")
>> type(lena)
<type 'numpy.ndarray'>
>> lena.shape,lena.dtype
((512, 512, 3), dtype('uint8'))
2.使用opencv函数时, 自动产生目标图像, 方便而且内部实现高效
使用pyopencv将lena.jpg转换为灰度图像, 需要手工创建目标图像, 麻烦且易出错:
>> import pyopencv as cv
>> lena=cv.imread("d:/lena.jpg")
>> grayLena=cv.Mat(lena.size(),cv.CV_8UC3)
>> cv.cvtColor(lena,grayLena,cv.CV_RGB2GRAY)
>> grayLena.ndarray.dtype
dtype('uint8')
而使用scikits.image将lena.jpg转换为灰度图像, 就方便不少:
>> import scikits.image.opencv as cv
>> import scikits.image.io as io
>> lena=io.imread("d:/lena.jpg")
>> grayLena=cv.cvCvtColor(lena,cv.CV_RGB2GRAY)
>> grayLena.dtype
dtype('uint8')
3.image包括其它的一些opencv中没有的算法, 包括trasform, gragh, morphology, filter, OpenCV只是其中的一个模块, 不是全部.
安装注意事项:
安装很麻烦, 但解决麻烦的过程是一种乐趣, 与大家分享
1.官方和pypi的0.22版本在XP下安装失败, 库也不全, 应该使用0.3版本, 下载地址:https://github.com/stefanv/scikits.image , 点download, 选择0.2.1( 就是0.3版本, 不知道它怎么弄的)下载
2. 自带的_libimport文件有问题, 需要更改, 安装(需要numpy,scipy,cython, pyqt , pil , matplot , 装了pythonxy就都有了)完成后, 找到opencv模块的_libimport.py文件(我的是D:\Python26\Lib\site-packages\scikits.image-0.3dev-py2.6-win32.egg\scikits\image\opencv\_libimport) , 该文件主要是找到opencv的cv.dll和cxcore.dll文件, 但照源文件的方法一般都找不到, 更改为如下(请参照自己的opencv路径和版本, 最新的opencv2.2 不支持):
__all__ = ["cv", "cxcore"]
import ctypes
cv = ctypes.CDLL("d:/OpenCV/Opencv2.1/bin/cv210.dll")
cxcore = ctypes.CDLL('d:/OpenCV/Opencv2.1/bin/cxcore210.dll')
3.自带的io的plugin机制有点麻烦, 默认情况下使用PIL的imread, imsave和imshow, PIL的imshow有点难看(不贴图了,自己试试), 要想使用opencv风格的imshow则需要这样:
>> io.imshow(lena,plugin='qt')
#通过指定plugin为qt, 弹出一个qt窗口,显示图像,窗口标题还不能设定
解决方案如下:
方法一:
a. 将io模块的__init__.py文件的13行更改为如下:
use_plugin('pil') → use_plugin('pil','imread'); use_plugin('qt', 'imshow');
理论上改成这样就可以了, 但我试了后还是不行,就需要继续b和c的步骤了, 希望大家也试试.
b.将io模块的io.py文件的第132行做如下更改:
def imshow(arr, plugin=None, **plugin_args): → def imshow(arr, plugin='qt', **plugin_args):
c.更改完后io的imshow不能显示窗口标题, 也就是说,每回显示的imshow窗口,标题都是一样的, 是"scikits.imge", 有时候希望可以为窗口指定标题, 我用这个方法:
将io模块的io.py文件的第132行(上面说的那个)做如下更改:
def imshow(arr, plugin='qt', **plugin_args): → def imshow(arr, title="Image", plugin='qt', **plugin_args):
将io.py第150行更改如下:
return call_plugin('imshow', arr ,plugin=plugin, **plugin_args) → return call_plugin('imshow', arr, title=title,plugin=plugin, **plugin_args)
将io模块下的_plugin模块中的qt_plugin.py第80行更改如下:def imshow(arr, fancy=False):→def imshow(arr, title="Image", fancy=False):
将qt_plugin.py第88行更改如下:
iw = ImageWindow(arr, window_manager) → iw = ImageWindow(arr, window_manager); iw.setWindowTitle(title);
方法二:
因为默认使用PIL的imread, imshow 和imsave方法, 因此可以直接更改 pil的 imshow 方法(这样还省去了对qt的依赖)
a.将io模块的io.py文件的第1行加上#coding=utf-8
将io模块的io.py文件的第132行做如下更改:
def imshow(arr, plugin=None, **plugin_args): →
def imshow(arr, title=u"图像" , plugin=None, **plugin_args):
#方法一中title似乎不能使用中文, 但方法二可以
将io.py第150行更改如下:
return call_plugin('imshow', arr ,plugin=plugin, **plugin_args) → return call_plugin('imshow', arr, title=title,plugin=plugin, **plugin_args)
b.将io模块下的_plugin模块中的pil_plugin.py第后行(imshow的方法体)更改如下:
def imshow(arr,title=u"图像"):
"""Display an image, using PIL's ImageTk function.
Parameters
----------
arr : ndarray
Image to display. Images of dtype float are assumed to be in
[0, 1]. Images of dtype uint8 are in [0, 255].
title : Caption of the display window. Default is u"图像".
"""
if np.issubdtype(arr.dtype, float):
arr = (arr * 255).astype(np.uint8)
try:
image=Image.fromarray(arr)
root=tk.Tk()
root.title(title)
root.geometry('%dx%d' % (image.size[0],image.size[1]))
tkpi = ImageTk.PhotoImage(image)
label_image = tk.Label(root, image=tkpi).pack()
root.mainloop()
except Exception,e:
print e
使用注意事项:
1.与pyopencv不同, 所有的opencv方法都有一个cv前缀, 就用cv.cvCanny之类的了, 改变一下习惯也无所谓
2.scikits.image的opencv模块中只有opencv的图像处理函数导入了,其它的如机器学习,摄像机等内容没有包含
3.pyopencv中的waitkey()函数变成了,io.show()函数, 大概作用就是在非交互模式时,停止运行程序,等待imshow窗口被关闭, 否则, imshow窗口会一闪而过
4.opencv中的函数调用都是function( sourceImage, dstImage, ...) → None的形式, scikits.image.opencv 中都变成了function(sourceImage,...) → dstImage ,这样显然方便不少, 也显得自然, 但是需要改变习惯.
还有其它的问题, 大家在安装或使用的过程中遇到的, 希望回帖一起交流.
转载自:http://www.zeuux.com/group/scipython/bbs/content/5373/