简体   繁体   English

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

[英]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 . 其中一个步骤是通过减去平均面向量mn = 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. 大多数方法,如meancov等接受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.

相关问题 Python ValueError:操作数无法与形状一起广播 - Python ValueError: operands could not be broadcast together with shapes Python ValueError:操作数不能与形状(5,4)(5,5)一起广播 - Python ValueError: operands could not be broadcast together with shapes (5,4) (5,5) python numpy ValueError:操作数无法与形状一起广播 - python numpy ValueError: operands could not be broadcast together with shapes ValueError: 操作数无法与形状 (100,) (99,) 一起广播 Python - ValueError: operands could not be broadcast together with shapes (100,) (99,) error in Python Python:ValueError:操作数不能与形状一起广播(101)(2) - Python: ValueError: operands could not be broadcast together with shapes (101) (2) MATLAB 到 PYTHON 转换 [ValueError: 操作数无法与形状 (120,) (6,) 一起广播] - MATLAB TO PYTHON conversion [ValueError: operands could not be broadcast together with shapes (120,) (6,) ] Pandas:ValueError - 操作数无法与形状一起广播 - Pandas: ValueError - operands could not be broadcast together with shapes ValueError: 操作数无法与形状 (7,) (6,) (7,) 一起广播 - ValueError: operands could not be broadcast together with shapes (7,) (6,) (7,) ValueError: 操作数无法与形状一起广播 (7410,) (3,) - ValueError: operands could not be broadcast together with shapes (7410,) (3,) ValueError:操作数不能与形状(5,)(30,)一起广播 - ValueError: operands could not be broadcast together with shapes (5,) (30,)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM