OpenCV运行手写识别代码报Expected Ptr<cv::UMat>错误求助
问题说明
基于OpenCV与Keras开发天城文手写识别程序时,更换多个OpenCV版本仍存在运行异常:程序调用摄像头完成颜色掩膜处理、提取轮廓后,执行选取面积最大轮廓的代码行时触发类型错误,直接终止运行。
完整报错信息如下:
line 95, in <module> main() File "c:\HindiHandWritingRecognizer\application.py", line 37, in main contou = max(cnts, key=cv2.contourArea(cnts)) TypeError: Expected Ptr<cv::UMat> for argument 'contour' [ WARN:0] terminating async callback
错误原因
max()函数的key参数写法错误:key参数需要传入可调用对象,原代码写为cv2.contourArea(cnts)是直接传入整个轮廓列表执行函数,而非对列表中单个轮廓元素计算面积,因此触发参数类型错误。cv2.findContours()返回值存在跨版本兼容问题:OpenCV 3.x版本该函数返回3个值(处理后图像, 轮廓列表, 层级表),OpenCV 4.x版本返回2个值(轮廓列表, 层级表),原代码固定取返回值索引[1]的写法,在不同版本下会拿到错误的对象(比如4.x版本下拿到的是层级表而非轮廓列表)。- 逻辑判断写法无效:原代码
if len(pts) != []中,len()返回值为整数,和空列表做比较永远返回True,会导致无手写轨迹时也触发识别逻辑,增加不必要的报错风险。 - 绘制逻辑顺序错误:原代码在
center变量初始化为None时就调用cv2.circle(img, center, ...),会触发空参数错误。
修复方法
- 修正
max()取最大轮廓的写法,将key参数改为传入函数对象本身:
把原代码第37行
修改为contou = max(cnts, key=cv2.contourArea(cnts))contou = max(cnts, key=cv2.contourArea) - 增加
findContours跨版本兼容逻辑,替换两处轮廓提取的固定索引取值:
原代码中
和cnts = cv2.findContours(thresh.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)[1]
分别修改为blackboard_cnts = cv2.findContours(thresh1.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)[1]cnts = cv2.findContours(thresh.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) cnts = cnts[0] if len(cnts) == 2 else cnts[1]blackboard_cnts = cv2.findContours(thresh1.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) blackboard_cnts = blackboard_cnts[0] if len(blackboard_cnts) == 2 else blackboard_cnts[1] - 修正无效的长度判断,把原代码
修改为if len(pts) != []:if len(pts) > 0: - 调整中心点绘制的代码顺序,将
cv2.circle(img, center, 5, (0, 0, 255), -1)移动到center变量赋值完成之后,也就是以下两行代码的后面:M = cv2.moments(contou) center = (int(M['m10'] / M['m00']), int(M['m01'] / M['m00']))
完成以上修改后程序即可正常运行。
内容的提问来源于stack exchange,提问作者Akshay Jugran
相关产品推荐
相关产品推荐

