使用Python+;PIL-速度问题

使用Python+;PIL-速度问题,python,normalization,python-imaging-library,Python,Normalization,Python Imaging Library,我在业余时间正在研究一个小问题,包括分析一些通过显微镜获得的图像。这是一个到处都有东西的晶片,最终我想制作一个程序来检测某些材料何时出现 无论如何,第一步是规范化整个图像的强度,因为镜头不会发出均匀的闪电。目前,我使用的是一个没有任何东西的图像,只有基底,作为背景或参考图像。我找到RGB的三个(强度)值中的最大值 from PIL import Image from PIL import ImageDraw rmax = 0;gmax = 0;bmax = 0;rmin = 300;gmin

我在业余时间正在研究一个小问题,包括分析一些通过显微镜获得的图像。这是一个到处都有东西的晶片,最终我想制作一个程序来检测某些材料何时出现

无论如何,第一步是规范化整个图像的强度,因为镜头不会发出均匀的闪电。目前,我使用的是一个没有任何东西的图像,只有基底,作为背景或参考图像。我找到RGB的三个(强度)值中的最大值

from PIL import Image
from PIL import ImageDraw

rmax = 0;gmax = 0;bmax = 0;rmin = 300;gmin = 300;bmin = 300

im_old = Image.open("test_image.png")
im_back = Image.open("background.png")

maxx = im_old.size[0] #Import the size of the image
maxy = im_old.size[1]
im_new = Image.new("RGB", (maxx,maxy))


pixback = im_back.load()
for x in range(maxx):
    for y in range(maxy):
        if pixback[x,y][0] > rmax:
            rmax = pixback[x,y][0]
        if pixback[x,y][1] > gmax:
            gmax = pixback[x,y][1]
        if pixback[x,y][2] > bmax:
            bmax = pixback[x,y][2]


pixnew = im_new.load()
pixold = im_old.load()
for x in range(maxx):
    for y in range(maxy):
        r = float(pixold[x,y][0]) / ( float(pixback[x,y][0])*rmax )
        g = float(pixold[x,y][1]) / ( float(pixback[x,y][1])*gmax )
        b = float(pixold[x,y][2]) / ( float(pixback[x,y][2])*bmax )
        pixnew[x,y] = (r,g,b)
代码的第一部分逐像素确定背景图像的红色、绿色和蓝色通道的最大强度,但只需执行一次

第二部分获取“真实”图像(图像上有内容),并根据背景逐像素标准化红色、绿色和蓝色通道。这需要一些时间,对于1280x960图像需要5-10秒,如果需要对多个图像执行此操作,则速度太慢

我能做些什么来提高速度?我曾想过将所有图像移动到numpy阵列,但我似乎找不到一种快速的方法来处理RGB图像。 我宁愿不离开Python,因为我的C++是相当低的,并且得到一个工作的FORTRAN代码可能要比我在速度方面节省的时间长:P

< P>见

你可以说

databack = scipy.misc.fromimage(pixback)
rmax = numpy.max(databack[:,:,0])
gmax = numpy.max(databack[:,:,1])
bmax = numpy.max(databack[:,:,2])
这应该比在图像的所有(r,g,b)三元组上循环快得多。 那你就可以了

dataold = scip.misc.fromimage(pixold)
r = dataold[:,:,0] / (pixback[:,:,0] * rmax )
g = dataold[:,:,1] / (pixback[:,:,1] * gmax )
b = dataold[:,:,2] / (pixback[:,:,2] * bmax )

datanew = numpy.array((r,g,b))
imnew = scipy.misc.toimage(datanew)

该代码未经测试,但应在稍作修改的情况下工作。

这可能不属于这里。@S.Lott,我认为这是一个灰色区域。问题归根结底是关于一种特定的技术。@MarkRansom:“特定的技术”是如何使它变成灰色的?这是密码。要回顾一下。@S.Lott,也许你是对的,它毕竟不是灰色的。我刚刚重读了FAQ,我看不出这个问题有任何问题。@Bjarke:你想过OpenCV吗?它是一个功能强大的图像处理库,带有Python绑定。它的读写速度很快,例如,它有一个自适应阈值算法。虽然与我的(w)hack相比,它确实非常快,但scipy函数似乎有些问题。例如,使用类似以下代码的图像应显示图像的红色通道,但情况似乎并非如此:
scipy.misc.toimage(databack[:,:,0])。show()
Unutbu给出了另一种解决方案,它不使用scipy在两个方向上转换图像和numpy数据。也许您应该尝试类似arr=np.array(np.asarray(img.astype('float'))new_img=Image.fromarray(normalize(arr.astype('uint8'),'RGBA')的方法,当我在灰度图像上执行此操作时(将转换和保存更改为'L'),与仅转换为灰度图像相比,我看不出任何区别(除了它的文件大小大约是灰度图像的3倍)。它的颜色也比较大,但我能从视觉上分辨出区别。文件大小的增加来自哪里?我是否应该能够注意到灰度归一化中的差异,如果是的话,我还需要在这里改变什么?我注意到维基上给出了相同的灰度公式示例。如果你有灰度图像,那么
arr
将具有形状
(H,W)
,而不是
(H,W,4)
。因此,您不需要规范化每个通道,
arr[…,i]
。相反,您应该规范化
arr
本身。因此,删除循环的
并将
arr[…,i]
更改为
arr
import numpy as np
from PIL import Image

def normalize(arr):
    """
    Linear normalization
    http://en.wikipedia.org/wiki/Normalization_%28image_processing%29
    """
    arr = arr.astype('float')
    # Do not touch the alpha channel
    for i in range(3):
        minval = arr[...,i].min()
        maxval = arr[...,i].max()
        if minval != maxval:
            arr[...,i] -= minval
            arr[...,i] *= (255.0/(maxval-minval))
    return arr

def demo_normalize():
    img = Image.open(FILENAME).convert('RGBA')
    arr = np.array(img)
    new_img = Image.fromarray(normalize(arr).astype('uint8'),'RGBA')
    new_img.save('/tmp/normalized.png')