Python AttributeError:';numpy.ndarray和#x27;
嗨,我正在编写一个小脚本,可以使重复的图片裁剪更容易。 我编写了一个小脚本,使用鼠标事件从图像中获取x,y坐标,我正在尝试使用openCV教程中找到的代码,将人脸图像裁剪为人脸数据库的特定大小Python AttributeError:';numpy.ndarray和#x27;,python,opencv,Python,Opencv,嗨,我正在编写一个小脚本,可以使重复的图片裁剪更容易。 我编写了一个小脚本,使用鼠标事件从图像中获取x,y坐标,我正在尝试使用openCV教程中找到的代码,将人脸图像裁剪为人脸数据库的特定大小 import sys, math import Image import cv2 import numpy as np import Tkinter import tkFileDialog from Tkinter import Tk from tkFileDialog import askopenfil
import sys, math
import Image
import cv2
import numpy as np
import Tkinter
import tkFileDialog
from Tkinter import Tk
from tkFileDialog import askopenfilename
def Distance(p1,p2):
dx = p2[0] - p1[0]
dy = p2[1] - p1[1]
return math.sqrt(dx*dx+dy*dy)
def ScaleRotateTranslate(image, angle, center = None, new_center = None, scale = None, resample=Image.BICUBIC):
if (scale is None) and (center is None):
return image.rotate(angle=angle, resample=resample)
nx,ny = x,y = center
sx=sy=1.0
if new_center:
(nx,ny) = new_center
if scale:
(sx,sy) = (scale, scale)
cosine = math.cos(angle)
sine = math.sin(angle)
a = cosine/sx
b = sine/sx
c = x-nx*a-ny*b
d = -sine/sy
e = cosine/sy
f = y-nx*d-ny*e
return image.transform(image.size, Image.AFFINE, (a,b,c,d,e,f), resample=resample)
def CropFace(image, eye_left=(0,0), eye_right=(0,0), offset_pct=(0.2,0.2), dest_sz = (70,70)):
# calculate offsets in original image
offset_h = math.floor(float(offset_pct[0])*dest_sz[0])
offset_v = math.floor(float(offset_pct[1])*dest_sz[1])
# get the direction
eye_direction = (eye_right[0] - eye_left[0], eye_right[1] - eye_left[1])
# calc rotation angle in radians
rotation = -math.atan2(float(eye_direction[1]),float(eye_direction[0]))
# distance between them
dist = Distance(eye_left, eye_right)
# calculate the reference eye-width
reference = dest_sz[0] - 2.0*offset_h
# scale factor
scale = float(dist)/float(reference)
# rotate original around the left eye
image = ScaleRotateTranslate(image, center=eye_left, angle=rotation)
# crop the rotated image
crop_xy = (eye_left[0] - scale*offset_h, eye_left[1] - scale*offset_v)
crop_size = (dest_sz[0]*scale, dest_sz[1]*scale)
image = image.crop((int(crop_xy[0]), int(crop_xy[1]), int(crop_xy[0]+crop_size[0]), int(crop_xy[1]+crop_size[1])))
# resize it
image = image.resize(dest_sz, Image.ANTIALIAS)
return image
# mouse callback function
def getCoord(event,x,y,flags,param):
global click
global xs
global ys
global xs1
global ys1
if event == cv2.EVENT_LBUTTONDOWN:
print str(x) + " " + str(y)
with open("coords.txt", "a") as myfile:
if click == 0:
xs = x
ys = y
#myfile.write(str(x) + " " + str(y) + " ")
if click == 1:
xs1 = x
ys1 = y
#myfile.write(str(x) + " " + str(y) + "\n")
print "Press 'Esc' to go to next picture or to exit"
click += 1
if __name__ == "__main__":
global click
global xs
global ys
global xs1
global ys1
print "\n"
print "\n"
click = 0
fileList = []
root = Tkinter.Tk()
filez = tkFileDialog.askopenfilenames(parent=root,title='Choose a file/files')
fileList = root.tk.splitlist(filez)
print root.tk.splitlist(filez)
lenght = len(fileList)
print str(lenght)
for num in range(0,lenght):
if click == 0:
print "test"
image = cv2.imread(str(fileList[num]), cv2.IMREAD_COLOR)
cv2.namedWindow("Find and Cropp")
cv2.setMouseCallback("Find and Cropp", getCoord)
cv2.imshow("Find and Cropp", image)
if cv2.waitKey(0) & 0xFF == 27:
cv2.destroyWindow("Find and Cropp")
if click > 0:
elx = int(xs)
#print xs
ely = int(ys)
#print ys
erx = int(xs1)
#print xs1
ery = int(ys1)
#print ys1
if click == 2:
#CropFace(image, eye_left=(115,115), eye_right=(168,120), offset_pct=(0.1,0.1), dest_sz=(200,200)).save("01a.jpg")
CropFace(image, eye_left=(elx,ely), eye_right=(erx,ery), offset_pct=(0.2,0.2), dest_sz=(200,200)).save("data/" + str(num+1) + ".jpg")
CropFace(image, eye_left=(elx,ely), eye_right=(erx,ery), offset_pct=(0.3,0.3), dest_sz=(200,200)).save("data/" + str(num+1) + "a.jpg")
#CropFace(image, eye_left=(115,115), eye_right=(168,120), offset_pct=(0.2,0.2)).save("01d.jpg")
print "********************" + str(num+1) + ".jpg - saved"
click = 0
cv2.destroyWindow("Find and Cropp")
我得到的错误是
属性错误:“numpy.ndarray”对象没有atribute“transform”
错误从以下行开始:
CropFace(image, eye_left=(elx,ely), eye_right=(erx,ery), offset_pct=(0.2,0.2), dest_sz=(200,200)).save("data/" + str(num+1) + ".jpg")
并在第行完成:
return image.transform(image.size, Image.AFFINE, (a,b,c,d,e,f), resample=resample)
但是,当我运行代码只是为了裁剪人脸(坐标是先前使用第一个脚本获得并保存到文本文件中的)时,一切都正常运行。OpenCV和PIL处理图像之间存在差异。OpenCV将图像作为NumPy数组处理,但PIL将其存储为
PIL.Image
对象
NumPy数组对象没有变换函数,但PIL图像对象具有变换函数
如果不希望自己实现裁剪面函数,请首先将NumPy数组更改为PIL图像,然后将PIL图像更改为NumPy数组
改变
CropFace(image, eye_left=(elx,ely), eye_right=(erx,ery), offset_pct=(0.3,0.3), dest_sz=(200,200)).save("data/" + str(num+1) + "a.jpg")
进入
我没有立即发现问题所在,但这也有点困难,因为代码太多了。如果你能将代码的范围缩小到能显示其工作和不工作的最小示例,那么会更容易提供帮助,而且你自己可能会遇到问题。@Nicolas78:添加了一些注释……你是否逐行跟踪代码,查看每个变量的值并确保它们具有正确的值?!
CropFace(Image.fromarray(np.uint8(image)), eye_left=(elx,ely), eye_right=(erx,ery), offset_pct=(0.3,0.3), dest_sz=(200,200)).save("data/" + str(num+1) + "a.jpg")