您的位置:首页 > 编程语言 > Python开发

推荐使用scikits.image 进行图像处理, 比较好用.

2013-10-16 16:24 507 查看
看了<<用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/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Python 图像处理