[英]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.