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

OpenCV应用单应性变换时cv::perspectiveTransform断言失败问题求助

问题解决方案

报错根因

你遇到的(-215:Assertion failed) scn + 1 == m.cols in function 'cv::perspectiveTransform'报错和des1、des2的长度没有直接关系:

该断言是OpenCV对perspectiveTransform输入参数的维度校验:单应性矩阵需要是3x3的结构,输入的2D坐标点通道数为2,2+1=3刚好匹配单应性矩阵的列数。触发报错的核心原因是你调用cv2.findHomography()计算单应性矩阵时,当匹配点质量差、RANSAC筛选后无法生成有效单应性矩阵,函数会返回None,你直接把空值传入perspectiveTransform就导致参数校验失败。

修复步骤

你需要补充两处判断逻辑:

  • 增加视频帧读取有效性判断,cap.read()返回的ret为False时直接终止循环,避免空帧参与计算
  • 调用cv2.findHomography()后先判断返回的单应性矩阵M是否为None,只有有效时才执行后续的透视变换操作

修复后完整代码

#!/usr/bin/env python
import cv2
import numpy as np
import sys

cap = cv2.VideoCapture('2.mp4')
MIN_MATCH_COUNT = 5
img1 = cv2.imread('b.png', 0) # 查询图
sift = cv2.xfeatures2d.SIFT_create()
# 提前计算查询图的关键点和描述子
kp1, des1 = sift.detectAndCompute(img1, None)
FLANN_INDEX_KDTREE = 0
index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
search_params = dict(checks=50)
flann = cv2.FlannBasedMatcher(index_params, search_params)

while cap.isOpened():
    ret, frame = cap.read()
    # 新增:视频读取结束直接退出循环
    if not ret:
        break
    kp2, des2 = sift.detectAndCompute(frame, None)
    if des1 is not None and len(des1) > 2 and des2 is not None and len(des2) > 2:
        matches = flann.knnMatch(des1, des2, k=2)
        good = []
        for m, n in matches:
            if m.distance < 0.7 * n.distance:
                good.append(m)

        if len(good) > MIN_MATCH_COUNT:
            src_pts = np.float32([kp1[m.queryIdx].pt for m in good]).reshape(-1, 1, 2)
            dst_pts = np.float32([kp2[m.trainIdx].pt for m in good]).reshape(-1, 1, 2)
            M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)
            # 新增:判断单应性矩阵是否有效
            if M is not None:
                matchesMask = mask.ravel().tolist()
                h, w = img1.shape
                pts = np.float32([[0, 0], [0, h - 1], [w - 1, h - 1], [w - 1, 0]]).reshape(-1, 1, 2)
                dst = cv2.perspectiveTransform(pts, M)
                print(dst)
            else:
                print("无法计算有效单应性矩阵")
        else:
            print("匹配点数量不足", (len(good), MIN_MATCH_COUNT))
    cv2.imshow("Image", frame)
    if cv2.waitKey(25) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

你原代码里未使用的img2和utils相关导入可以直接删除,减少冗余。

内容的提问来源于stack exchange,提问作者zexapod

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 02:24:03