使用cv2.transform应用变换矩阵遇参数错误,求助
问题解决:cv2.transform 传入PyTorch张量报错
问题背景
尝试替换原有代码逻辑:在特征提取前用OpenCV对图像应用变换矩阵,而非将变换矩阵传入net_recog,但运行触发类型不匹配错误。
错误信息
cv2.error: OpenCV(4.8.1) :-1: error: (-5:Bad argument) in function 'transform'
Overload resolution failed:
- src is not a numpy array, neither a scalar
- Expected Ptrcv::UMat for argument 'src'
问题原因
- 类型不匹配:
self.pred_face和self.input_img是PyTorch张量,而OpenCV函数仅接受numpy数组或UMat格式输入。 - 函数误用:
cv2.transform用于变换点集(如关键点),变换整幅图像应使用cv2.warpAffine(仿射变换)或cv2.warpPerspective(透视变换)。 - 维度与设备不匹配:PyTorch张量维度为
(batch, channel, height, width),而OpenCV图像格式为(height, width, channel);若张量在GPU上,需先移至CPU再转换。
解决方案代码示例
import numpy as np import cv2 import torch def compute_losses(self): assert self.net_recog.training == False trans_m = self.trans_m if not self.opt.use_predef_M: trans_m = estimate_norm_torch(self.pred_lm, self.input_img.shape[-2]) # 将张量转为numpy数组,调整维度并移至CPU pred_face_np = self.pred_face.cpu().numpy().transpose(0, 2, 3, 1) # 转成(B, H, W, C) trans_m_np = trans_m.cpu().numpy().astype(np.float32) # 批量处理每张图像的仿射变换 pred_feat1_np = [] for img, mat in zip(pred_face_np, trans_m_np): # 若变换矩阵是3x3透视矩阵,取前2行转为仿射矩阵;若用透视变换则用cv2.warpPerspective if mat.shape == (3, 3): mat = mat[:2, :] # 转换数值范围为0-255的uint8(适配OpenCV处理) img_uint8 = (img * 255).astype(np.uint8) # 应用仿射变换 warped_img = cv2.warpAffine(img_uint8, mat, (img.shape[1], img.shape[0])) # 转回0-1浮点型 pred_feat1_np.append(warped_img.astype(np.float32) / 255.0) # 转回PyTorch张量格式并放回原设备 pred_feat1_np = np.array(pred_feat1_np).transpose(0, 3, 1, 2) # 转成(B, C, H, W) pred_feat1 = torch.tensor(pred_feat1_np).to(self.pred_face.device) pred_feat = self.net_recog(pred_feat1) # 对input_img执行相同处理 input_img_np = self.input_img.cpu().numpy().transpose(0, 2, 3, 1) gt_feat1_np = [] for img, mat in zip(input_img_np, trans_m_np): if mat.shape == (3, 3): mat = mat[:2, :] img_uint8 = (img * 255).astype(np.uint8) warped_img = cv2.warpAffine(img_uint8, mat, (img.shape[1], img.shape[0])) gt_feat1_np.append(warped_img.astype(np.float32) / 255.0) gt_feat1_np = np.array(gt_feat1_np).transpose(0, 3, 1, 2) gt_feat1 = torch.tensor(gt_feat1_np).to(self.input_img.device) gt_feat = self.net_recog(gt_feat1) self.loss_feat = self.opt.w_feat * self.compute_feat_loss(pred_feat, gt_feat)
关键说明
- 若使用透视变换,将
cv2.warpAffine替换为cv2.warpPerspective,并传入完整的3x3变换矩阵。 - 若原张量数值范围不是0-1,需根据实际情况调整转换逻辑(如直接处理浮点型图像则跳过uint8转换)。
- 批量处理时需循环单张图像,OpenCV变换函数不直接支持批量输入。
内容的提问来源于stack exchange,提问作者yun_91D
相关产品推荐
相关产品推荐

