我正在使用Python中的脚本,我想找到相同维度的多个图像的中位数。也就是说,我不想在位置[x,y]中拍摄所有(红色,绿色和蓝色)像素,并使用它们的中值构建一个新图像。
我当前的方法使用Python PIL(成像库),但速度很慢!我非常想使用OpenCV(cv2)接口,因为它将每个图像直接加载为numpy数组。但是,当堆叠尺寸为x(2560,1920,3)的x图像时,我一直错误地索引。有什么帮助吗?
我目前使用PIL的低效代码如下:
from PIL import Image, ImageChops,ImageDraw,ImageFilter,cv
import sys,glob,sys,math,shutil,time,os, errno,numpy,string
from os import *
inputs = ()
path = str(os.getcwd())
BGdummyy=0
os.chdir(path)
for files in glob.glob("*.png"):
inputs = inputs + (str(str(files)),)
BGdummy=0
for file in inputs:
BGdummy=BGdummy+1
im = cv.LoadImage(file)
cv.CvtColor( im, im, cv.CV_BGR2RGB )
img = Image.fromstring("RGB", cv.GetSize(im), im.tostring())
vars()["file"+str(BGdummy)] = img.load()
imgnew = Image.new("RGB", (2560,1920))
pixnew = imgnew.load()
for x in range(2560):
for y in range(1920):
R=[];G=[];B=[];
for z in range(len(inputs)):
R.append(vars()["file"+str(z+1)][x,y][0])
G.append(vars()["file"+str(z+1)][x,y][1])
B.append(vars()["file"+str(z+1)][x,y][2])
R = sorted(R)
G = sorted(G)
B = sorted(B)
mid = int(len(inputs)/2.)
Rnew = R[mid]
Gnew = G[mid]
Bnew = B[mid]
pixnew[x,y] = (Rnew,Gnew,Bnew)
BGdummyy = BGdummyy+1
imgnew.save("NewBG.png")
答案 0 :(得分:3)
我将演示如何使用5个小型数组(3,3,3)来完成它。
首先,我将创建5个数组,然后将它们保存在列表X中。在您的情况下,您将在此列表中保留30个图像。 (我在一行中这样做)
X = [a,b,c,d,e] = [np.random.randint(0,255,(3,3,3)) for i in xrange(5)]
接下来,将每个图像展平为一个长单行。所以早些时候您的形象就像
[R1G1B1 R2G2B2 R3G3B3,
R4G4B4 R5G5B5 R6G6B6,
R7G7B7 R8G8B8 R9G9B9]
这将变为[R1 G1 B1 R2 G2 B2 R3 G3 B3......... R9 G9 B9]
。然后堆叠所有这些展平的图像,形成一个大的2D阵列。在该数组中,您会看到,所有第一个红色像素都出现在第一列中,依此类推。然后你可以简单地为它申请np.median。
Y = np.vstack((x.ravel() for x in X))
我把每张图片都拿走并堆叠起来。在我的例子中,Y是一个大小为5x27的数组(行 - 图像数,列 - 图像中的像素数)
现在我找到这个Y的中位数并将其重新塑造成我们原始的图像形状:
Z = np.median(Y,axis = 0)
Z = np.uint8(Z.reshape(a.shape))
完成。
为了确保它正常工作,让我们检查任意像素的值,比如Z[0,1,2]
:
In [50]: G1 = [x[0,1,2] for x in X]
In [51]: G1
Out[51]: [225, 65, 26, 182, 51]
In [52]: Z[0,1,2]
Out[52]: 65.0
是的,数据是正确的。