将CV2 Numpy数组转换为RGB图像时出现“Not Enough Image Data”错误

3
在下面的代码中,我试图使用CV2输出一个单独的人脸(从一张较大的图像中裁剪出来):
def machine_pst():
    mlimg = request.files.get("mlimg")
    fname = mlimg.filename
    filepath = "/home/assets/faces/"
    mlimg.save(filepath + fname, overwrite = True)
    full_path = filepath + fname
    cascPath = "/home/assets/haarcascade_frontalface_default.xml"
    detector = cv2.CascadeClassifier(cascPath)
    faceSamples=[]
    pilImage=Image.open(full_path).convert('L')
    imageNp=np.array(pilImage,'uint8')
    faces=detector.detectMultiScale(imageNp)
    for (x,y,w,h) in faces:
        faceSamples.append(imageNp[y:y+h,x:x+w])
    img = Image.fromarray(faceSamples[0], 'RGB')

   cv2.imwrite("/home/assets/faces/read.png", img)
   source = "/static/faces/read.png"
   return template("home/machineout", source = source)

使用source作为参数传递到img src="{{source}}

如果我返回一个包含3张脸的图像中的脸部数量,我会获得“3”,所以这似乎很好用,如果我返回faceSamples的任何索引(例如faceSamples [0]),我也会得到数据返回,但是当我尝试将该人脸样本转换为图像时,出现了问题...

img = Image.fromarray(faceSamples[0], 'RGB')

我收到了一个ValueError,说“图像数据不足”

我知道(从之前的答案中得知),detectMultiScale返回的是矩形而不是图像,但是通过我的额外的Numpy代码,这仍然是个问题吗? 我是否仍然没有完全理解faceSamples数组返回的内容? 最后一段代码不能直接将其转换回RGB图像吗?


我在想 "/home/.../assets/faces/" 是否是正确的路径。你确定不是 .. 吗? - Quang Hoang
啊,抱歉 Quang。让我把那些去掉,这样就不会有混淆了……我只是举例子用了那些点。路径都正常工作。 - Victor Rodriguez
2
img = Image.fromarray() 会尝试创建一个 PIL 图像,然后将其传递给 cv2.imwrite(),但是 OpenCV 不支持 PIL 图像 - 它期望的是 Numpy 数组。你已经在 faceSamples[0] 中拥有了你想要的 - 一个 OpenCV 可以使用的 Numpy 数组/图像。 - Mark Setchell
你太棒了,马克!我正在查看我的图像中的一个面孔!感谢你的所有帮助,如果你想把这个作为答案,我会接受它。 - Victor Rodriguez
1个回答

3
您的问题在这里:
pilImage=Image.open(full_path).convert('L')
imageNp=np.array(pilImage,'uint8')

也就是说,您将imageNp转换为单通道灰度图像。那么继续操作就没有什么意义了。
img = Image.fromarray(faceSamples[0], 'RGB')

faceSamples[0]同样也是一张灰度图像。

另外,与@MarkSetchell的评论类似,您可以使用cv2.imread和其他函数替代PIL。它们更兼容其他openCV函数。


谢谢Quang!关于灰度图像的信息很有用。 - Victor Rodriguez

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接