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
相关产品推荐
相关产品推荐

