Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python-ValueError:操作数无法与形状一起广播_Python_Arrays_Matrix_Numpy_Face Recognition - Fatal编程技术网

Python-ValueError:操作数无法与形状一起广播

Python-ValueError:操作数无法与形状一起广播,python,arrays,matrix,numpy,face-recognition,Python,Arrays,Matrix,Numpy,Face Recognition,我正在尝试使用python通过主成分分析(PCA)实现人脸识别。其中一个步骤是通过减去平均面部向量m:n=T-m来规范化输入(测试)图像T 这是我的密码: #Step1: put database images into a 2D array filenames = glob.glob('C:\\Users\\Karim\\Downloads\\att_faces\\New folder/*.pgm') filenames.sort() img = [Image.open(fn).convert

我正在尝试使用python通过主成分分析(PCA)实现人脸识别。其中一个步骤是通过减去平均面部向量
m
n=T-m
来规范化输入(测试)图像
T

这是我的密码:

#Step1: put database images into a 2D array
filenames = glob.glob('C:\\Users\\Karim\\Downloads\\att_faces\\New folder/*.pgm')
filenames.sort()
img = [Image.open(fn).convert('L').resize((90, 90)) for fn in filenames]
images = np.asarray([np.array(im).flatten() for im in img])

#Step 2: find the mean image and the mean-shifted input images
m = images.mean(axis=0)
shifted_images = images - m

#Step 7: input image
input_image = Image.open('C:\\Users\\Karim\\Downloads\\att_faces\\1.pgm').convert('L').resize((90, 90))
T = np.asarray(input_image)
n = T - mean_image
但是我得到了一个错误
回溯(最近一次呼叫最后一次):
文件“C:/Users/Karim/Desktop/bacher 2/New folder/new3.py”,第46行,在
n=T-m

ValueError:操作数无法与形状(90,90)(8100)一起广播。

为展平阵列计算了平均值\u image

images = np.asarray([np.array(im).flatten() for im in img])
mean_image = images.mean(axis=0)

input_image
为90x90。因此出现了错误。您应该也展平输入图像,或者不展平原始图像(我不太明白您为什么这样做),或者仅为此操作将
mean\u image
调整为90x90。

正如@Lev所说,您已经展平了阵列。实际上,你不需要这样做来执行平均值。假设你有一个由2个3x4个图像组成的数组,那么你会有这样的东西:

In [291]: b = np.random.rand(2,3,4)

In [292]: b.shape
Out[292]: (2, 3, 4)

In [293]: b
Out[293]: 
array([[[ 0.18827554,  0.11340471,  0.45185287,  0.47889188],
        [ 0.35961448,  0.38316556,  0.73464482,  0.37597429],
        [ 0.81647845,  0.28128797,  0.33138755,  0.55403119]],

       [[ 0.92025024,  0.55916671,  0.23892798,  0.59253267],
        [ 0.15664109,  0.12457157,  0.28139198,  0.31634361],
        [ 0.33420446,  0.27599807,  0.40336601,  0.67738928]]])
在第一个轴上执行平均值,保留阵列的形状:

In [300]: b.mean(0)
Out[300]: 
array([[ 0.55426289,  0.33628571,  0.34539042,  0.53571227],
       [ 0.25812778,  0.25386857,  0.5080184 ,  0.34615895],
       [ 0.57534146,  0.27864302,  0.36737678,  0.61571023]])

In [301]: b - b.mean(0)
Out[301]: 
array([[[-0.36598735, -0.222881  ,  0.10646245, -0.0568204 ],
        [ 0.10148669,  0.129297  ,  0.22662642,  0.02981534],
        [ 0.24113699,  0.00264495, -0.03598923, -0.06167904]],

       [[ 0.36598735,  0.222881  , -0.10646245,  0.0568204 ],
        [-0.10148669, -0.129297  , -0.22662642, -0.02981534],
        [-0.24113699, -0.00264495,  0.03598923,  0.06167904]]])
对于许多用途,这也比将图像保留为数组列表要快,因为numpy操作是在一个数组上完成的,而不是通过数组列表完成的。大多数方法,如
mean
cov
等,都接受
axis
参数,并且您可以列出所有要执行该参数的维度,而无需展平

要将此应用于脚本,我将执行以下操作,保持原始维度:

images = np.asarray([Image.open(fn).convert('L').resize((90, 90)) for fn in filenames])
# so images.shape = (len(filenames), 90, 90)

m = images.mean(0)
# numpy broadcasting will automatically subract the (90, 90) mean image from each of the `images`
# m.shape = (90, 90)
# shifted_images.shape = images.shape = (len(filenames), 90, 90)
shifted_images = images - m 

#Step 7: input image
input_image = Image.open(...).convert('L').resize((90, 90))
T = np.asarray(input_image)
n = T - m
最后,如果速度是一个问题,那么使用np.dstack加入您的图像会更快:

In [354]: timeit b = np.asarray([np.empty((50,100)) for i in xrange(1000)])
1 loops, best of 3: 824 ms per loop

In [355]: timeit b = np.dstack([np.empty((50,100)) for i in xrange(1000)]).transpose(2,0,1)
10 loops, best of 3: 118 ms per loop

但加载图像可能需要大部分时间,如果是这种情况,您可以忽略这一点。

图像必须展平为2D数组,而不是3D数组,才能计算平均值、协方差、特征值和特征向量。另一方面,如果将输入图像展平,它将是1D数组,并且我也无法计算平均值、协方差、特征值和特征向量。@user222953我认为任何接受
参数的函数都不需要它,正如@askewchan所指出的。无论如何,现在你正在从一个90x90数组中减去一个8100 1D数组,这个数组必须以这样或那样的方式修复。我正在尝试你建议的方法,但我发现了一个错误
回溯(最近一次调用):文件“C:/Users/Karim/Desktop/bamber 2/New folder/new4.py”,第12行,在images=np.asarray([Image.open(fn.convert('L'))文件“C:\Python27\lib\site packages\numpy\core\numeric.py”,第320行,asarray返回数组(a,dtype,copy=False,order=order)SystemError:error return without exception set
确定我不理解该错误,但尝试将
np.asarray
更改为
np.array
,尝试一下你所拥有的,但不要使用
.flatte
imgs=[Image.open(fn).convert('L')。resize((90,90))来调整文件名中fn的大小]
images=np.asarray([np.array(img)用于imgs中的img])
np.array
无法修复任何问题,并且清除
.flatte
会在计算方差时产生另一个错误。无论如何,谢谢你的帮助