Python和科学计算认证群组  - 讨论区

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

2010年12月19日 星期日 13:32

看了<<用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 ,这样显然方便不少, 也显得自然, 但是需要改变习惯.

还有其它的问题, 大家在安装或使用的过程中遇到的, 希望回帖一起交流.

2010年12月19日 星期日 19:21

好像scikits.image中的opencv用的是OpenCV的C API,pyopencv用的是OpenCV的C++ API。

scipy自带的ndimage也有一些图像处理功能,OpenCV库也有好几种接口。

Python的选择真是很丰富,就差这样的总结性的文章,让用户快速入门。

如下红色区域有误,请重新填写。

    你的回复:

    请 登录 后回复。还没有在Zeuux哲思注册吗?现在 注册 !

    Zeuux © 2024

    京ICP备05028076号