关于OpenCV版本问题带来的两个小错误

本文针对使用OpenCV4.0时遇到的cv2.morphologyEx和cv2.findContours函数错误进行了分析与修正,包括调整内核类型及处理函数返回值变化等问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

写写代码,跑跑程序,出现两个小错误,解决之。

(1)cv2.morphologyEx

mask=cv2.morphologyEx(mask,cv2.MORPH_CLOSE,kernalC1)
TypeError: Expected cv::UMat for argument 'kernel'

(2)cv2.findContours

_,countours0,hierarchy=cv2.findContours(mask,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
ValueError: not enough values to unpack (expected 3, got 2)

两个小错误,查了下OpenCV版本为4.0.0

import cv2
print(cv2.__version__)
4.0.0

查看OpenCV4.0.0documents

https://docs.opencv.org/4.0.0-rc/d4/d73/tutorial_py_contours_begin.html

代码为:

import numpy as np
import cv2 as cv
im = cv.imread('test.jpg')
imgray = cv.cvtColor(im, cv.COLOR_BGR2GRAY)
ret, thresh = cv.threshold(imgray, 127, 255, 0)
contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)

修改网页上方版本为3.2,自动跳转到3.2的documents

https://docs.opencv.org/3.2.0/d4/d73/tutorial_py_contours_begin.html

代码为

import numpy as np
import cv2
im = cv2.imread('test.jpg')
imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(imgray,127,255,0)
im2, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

 

同样查找cv2.morphologyEx

https://docs.opencv.org/4.0.0-rc/d9/d61/tutorial_py_morphological_ops.html

代码为

import cv2 as cv
import numpy as np
img = cv.imread('j.png',0)
kernel = np.ones((5,5),np.uint8)
erosion = cv.erode(img,kernel,iterations = 1)
closing = cv.morphologyEx(img, cv.MORPH_CLOSE, kernel)

kernel类型为应该np.unit8。其他版本同上。

 

应该是版本问题,内置函数参数和返回值有修改,修改kernalC1类型,cv2.findContours和返回值,如下

(1)kernalC1类型

kernalCl = np.ones((11,11),np.uint)

改为

kernalCl = np.ones((11,11),np.uint8)

(2)cv2.findContours返回值

_,countours0,hierarchy=cv2.findContours(mask,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)

改为

countours0,hierarchy=cv2.findContours(mask,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)

 

这段代码存在一些潜在的问题,可能会导致运行时出现问题。以下是具体的分析: ### 报错原因: 1. **`ellipse()` 函数调用问题** `ellipse(canvas, currentCenter, Size(150, 100), (angleShift + getTickCount() % 360) * 2, Scalar(), -1, LINE_AA)` 这一行存在问题。 - 参数顺序有误:`Scalar()` 应该表示颜色值(如 BGR 值),但是在这里它为空,未传递有效值。 - `-1` 表示填充椭圆,但由于没有提供颜色参数,因此会导致绘制失败。 2. **`checkBoundaryCollision` 函数问题** - 此函数中有 `position.width` 的引用,而 `Point` 类型并没有 `width` 属性,只有 `x` 和 `y` 成员变量。这会造成编译错误。 3. **缺少必要的运动逻辑** - 程序虽然有一个无限循环结构 (`while(true)`) 来更新图像,但实际上并未对中心点位置进行任何计算或更改,这意味着图形始终处于初始状态 `(300, 300)` 并不会发生移动或旋转动画效果。 --- ### 解决方案 #### 对于 `ellipse()` 函数问题: 需要明确设定颜色和线条粗细。例如: ```cpp ellipse(canvas, currentCenter, Size(150, 100), (angleShift + getTickCount() % 360) * 2, blue, -1, LINE_AA); ``` 这里我们将颜色更改为蓝色 (`blue`),并且保持填充分别为 `-1`. #### 修改 `checkBoundaryCollision` 函数: 修正其内部条件检查部分以避免访问非法属性名的情况,可以改写如下所示形式之一即可正常运作了: ```cpp bool checkBoundaryCollision(Point &position, const Size &windowSize) { Rect rect(position.x - 150, position.y - 100, 300, 200); // 模拟物体范围 if(rect.x <=0 ||rect.y<=0|| rect.x+rect.width>=windowSize.width|| rect.y+rect.height>=windowSize.height) return true; else return false; } ``` #### 添加简单运动模拟机制: 我们可以在主循环中加入基本的速度矢量组件来逐步改变目标物象所在地点坐标数值大小变化情况从而实现动态位移现象演示目的。 最终完整的修复版本应该是这样的样子: ```cpp #include <opencv2/opencv.hpp> #include <cstdlib> #include <ctime> using namespace cv; // 全局变量声明开始... Point center(300, 300); Scalar blue(255, 0, 0), red(0, 0, 255); Mat canvas = Mat::zeros(600, 600, CV_8UC3); float speedX = rand() % 3 - 1; float speedY=rand()%3-1 ; void drawEllipsesAndCircle(const Point& currentCenter){ for(int i=0;i<3;i++){ int angleShift=i*120; ellipse(canvas,currentCenter,Size(150,100), ((angleShift+(getTickCount())%360))*2 ,blue,-1,LINE_AA);} circle(canvas,center,10,red,FILLED);} bool checkBoundaryCollision(Point& pos,const Size winSz){ Rect obj(pos.x-150,pos.y-100,300,200); if(obj.x<0||obj.y<0||obj.br().x>winSz.width||obj.br().y >winSz.height){return true;}else{return false;}} int main(){ srand((unsigned )time(NULL)); namedWindow("Animation"); while(char waitKey(3)!= 'q'){ canvas.setTo(Scalar()); // 更新位置并处理边界反射 center.x +=speedX ; center.y+=speedY ; if(checkBoundaryCollision(center,{canvas.cols,canvas.rows})){ speedX=-speedX ; speedY=-speedY;} drawEllipsesAndCircle(center); imshow("Animation", canvas);} destroyAllWindows(); return EXIT_SUCCESS;} ``` ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值