[英]Python - ValueError: operands could not be broadcast together with shapes
I am trying to implement face recognition by Principal Component Analysis (PCA) using python. 我正在尝试使用主要组件分析(PCA)使用python实现面部识别。 One of the steps is to normalize the input (test) image
T
by subtracting the average face vector m
: n = T - m
. 其中一个步骤是通过减去平均面向量
m
: n = T - m
来归一化输入(测试)图像T
Here is my code: 这是我的代码:
#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
But I am getting an error Traceback (most recent call last): File "C:/Users/Karim/Desktop/Bachelor 2/New folder/new3.py", line 46, in <module> n = T - m ValueError: operands could not be broadcast together with shapes (90,90) (8100)
但我得到一个错误
Traceback (most recent call last): File "C:/Users/Karim/Desktop/Bachelor 2/New folder/new3.py", line 46, in <module> n = T - m ValueError: operands could not be broadcast together with shapes (90,90) (8100)
mean_image
was computed for flattened arrays: 为flattened数组计算
mean_image
:
images = np.asarray([np.array(im).flatten() for im in img])
mean_image = images.mean(axis=0)
and input_image
is 90x90. 和
input_image
是90x90。 Hence the error. 因此错误。 You should either flatten the input image, too, or not flatten the original images (I don't quite understand why you do it), or resize
mean_image
to 90x90 just for this operation. 您也应该平整输入图像,或者不要压平原始图像(我不太明白为什么要这样做),或者仅为此操作将
mean_image
调整为90x90。
As @Lev says, you have flattened your arrays. 正如@Lev所说,你已经弄平了阵列。 You don't actually need to do this to perform the mean.
你实际上并不需要这样做来执行平均值。 Say you have an array of 2 3x4 images, then you'd have something like this:
假设您有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]]])
Perform the mean over the first axis, leaving the shape of the arrays: 在第一个轴上执行平均值,保留数组的形状:
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]]])
For many uses, this will also be faster than keeping your images as a list of arrays, since the numpy operations are done on one array instead of through a list of arrays. 对于许多用途,这也比将图像保持为数组列表更快,因为numpy操作是在一个数组上完成的,而不是通过数组列表完成的。 Most methods, like
mean
, cov
, etc accept the axis
argument, and you can list all the dimensions to perform it on without having to flatten. 大多数方法,如
mean
, cov
等接受axis
参数,您可以列出所有维度来执行它而不必展平。
To apply this to your script, I would do something like this, keeping the original dimensionalities: 要将此应用于您的脚本,我会做这样的事情,保持原始的维度:
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
As a final comment, if speed is an issue, it would be faster to use np.dstack to join your images: 作为最终评论,如果速度是一个问题,使用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
But it's likely that loading the images takes most of the time, and if that's the case you can ignore this. 但是,加载图像很可能需要花费大部分时间,如果是这种情况,你可以忽略它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.