使用OpenCV旋转图像时出现AttributeError: shape错误求助
问题根源与解决方法
你遇到的AttributeError: shape错误核心原因很简单:PIL的Image对象没有shape属性。shape是numpy数组(也就是OpenCV处理图像时用的格式)的专属属性,而你用Image.open()读取并处理后得到的是PIL的Image实例,自然调用不了shape。
下面给两种直接可行的解决思路:
思路1:将PIL图像转为numpy数组(兼容现有流程)
如果你想保留之前用PIL做resize、crop的逻辑,只需要在旋转前把PIL对象转成numpy数组,处理完再转回PIL对象即可:
import numpy as np import cv2 from PIL import Image class PlaneProcessor: def __init__(self, img_path): # 原PIL处理流程不变 self.plane_img = Image.open(img_path).resize((500,500)).crop((100,100,400,400)) def adjust_plane(self, some_condition): # 把PIL图像转成numpy数组(OpenCV可识别的格式) plane_cv = np.array(self.plane_img) # 注意:PIL是RGB通道,OpenCV默认BGR,若用OpenCV旋转函数需要通道转换 plane_cv = cv2.cvtColor(plane_cv, cv2.COLOR_RGB2BGR) if some_condition: # 现在可以正常获取shape了 h, w = plane_cv.shape[:2] # 执行旋转操作(以旋转90度为例) center = (w//2, h//2) rot_matrix = cv2.getRotationMatrix2D(center, 90, 1.0) rotated_plane = cv2.warpAffine(plane_cv, rot_matrix, (w, h)) # 转回PIL对象,保持原流程的对象类型 rotated_plane_rgb = cv2.cvtColor(rotated_plane, cv2.COLOR_BGR2RGB) self.plane_img = Image.fromarray(rotated_plane_rgb)
思路2:全程用OpenCV处理(避免类型转换)
如果后续主要用OpenCV操作,不如直接全程用OpenCV的API处理图像,从读取到缩放裁剪都用numpy数组,彻底避开类型问题:
import cv2 class PlaneProcessor: def __init__(self, img_path): # OpenCV读图像,直接得到numpy数组 plane_cv = cv2.imread(img_path) # 缩放 plane_cv = cv2.resize(plane_cv, (500,500)) # 裁剪:OpenCV的切片格式是 [y_start:y_end, x_start:x_end] plane_cv = plane_cv[100:400, 100:400] self.plane_img = plane_cv # 存储的是numpy数组 def adjust_plane(self, some_condition): plane = self.plane_img if some_condition: # 直接获取shape,无任何问题 h, w = plane.shape[:2] # 执行旋转操作 center = (w//2, h//2) rot_matrix = cv2.getRotationMatrix2D(center, 90, 1.0) self.plane_img = cv2.warpAffine(plane, rot_matrix, (w, h))
关键注意点
- PIL和OpenCV的通道顺序不同:PIL是RGB,OpenCV默认是BGR,跨库转换时必须用
cv2.cvtColor()做通道转换,否则图像颜色会失真。 - 面向对象编程里,要明确
self.plane_img存储的对象类型,是PIL Image还是numpy数组,后续操作要匹配对应的API。
内容的提问来源于stack exchange,提问作者taffyhound
相关产品推荐
相关产品推荐

