簡體   English   中英

使用 Python+PIL 對圖像進行強度歸一化 - 速度問題

[英]Intensity normalization of image using Python+PIL - Speed issues

我在業余時間處理一個小問題,涉及分析通過顯微鏡獲得的一些圖像。 它是一塊晶圓,到處都是一些東西,最終我想制作一個程序來檢測某些材料何時出現。

無論如何,第一步是標准化整個圖像的強度,因為鏡頭不會發出均勻的閃電。 目前我使用的圖像,沒有任何東西,只有基材,作為背景或參考圖像。 我找到了 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 arrays,但我似乎無法找到對 RGB 圖像執行此操作的快速方法。 我寧願不離開 python,因為我的 C++ 是相當低級的,並且獲得一個有效的 FORTRAN 代碼可能需要比我在速度方面節省的時間更長:P

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')

http://docs.scipy.org/doc/scipy/reference/generated/scipy.misc.fromimage.html#scipy.misc.fromimage

你可以說

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)

代碼未經過測試,但應以某種方式稍作修改。

這部分來自FolksTalk 網頁

from PIL import Image
import numpy as np

# Read image file
in_file = "my_image.png"
# convert('RGB') for PNG file type
image = Image.open(in_file).convert('RGB')
pixels = np.asarray(image)

# Convert from integers to floats
pixels = pixels.astype('float32')

# Normalize to the range 0-1
pixels /= 255.0

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM