You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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'

问题原因

  1. 类型不匹配:self.pred_face和self.input_img是PyTorch张量,而OpenCV函数仅接受numpy数组或UMat格式输入。
  2. 函数误用:cv2.transform用于变换点集(如关键点),变换整幅图像应使用cv2.warpAffine(仿射变换)或cv2.warpPerspective(透视变换)。
  3. 维度与设备不匹配: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 10:17:09