opencv入门学习,填充函数fillPoly遇到一个问题,跟着老师的代码,他跑起来是没有问题的,但是我这里始终不行,因为我装的是v4.0.0.老师装的是v4.4.0,可能存在一定差异
Mat canvas = Mat::zeros(Size(512, 512), CV_8UC3);
Point p1(100, 100);
Point p2(350, 100);
Point p3(450, 280);
Point p4(320, 450);
Point p5(80, 400);
std::vector<Point>pts;
pts.push_back(p1);
pts.push_back(p2);
pts.push_back(p3);
pts.push_back(p4);
pts.push_back(p5);
fillPoly(canvas, pts, Scalar(255, 0, 0), 8, 0);//这里导致崩溃
崩溃
fillPoly()有两个重载函数,按照老师这个写法调用的是这个:
CV_EXPORTS_W void fillPoly
(InputOutputArray img, InputArrayOfArrays pts,
const Scalar& color, int lineType = LINE_8,
int shift = 0,Point offset = Point() );
但是我同样的写法始终导致程序崩溃,debug最终确认是第二个参数InputArrayOfArrays 不对。
看了一下文档:
也就是InputArrayOfArrays类型应该是vector套vector类型或者MAT矩阵的vector,错误代码中的pts为Point的vector类型,所以不行。
对原来的pts再套一层vector修改后:
std::vector<std::vector<Point>>pppts;
pppts.push_back(pts);
fillPoly(canvas,pppts,Scalar(0, 0, 255), LINE_8, 0);
不过,虽然文档里面这么说的,但是看源码里的定义根本看不出InputArrayOfArrays与inputArray的区别,就像我开头提到的老师的函数调用是没有问题的,这个放到最后说。
另外,这里是对于普通的_InputArray类的构建方法:
其实也可以调用fillPoly()另一个重载函数:
CV_EXPORTS void fillPoly
(InputOutputArray img, const Point** pts,
const int* npts, int ncontours,
const Scalar& color, int lineType = LINE_8,
int shift = 0,Point offset = Point() );
Mat canvas = Mat::zeros(Size(512, 512), CV_8UC3);
std::vector<Point>pts;
pts.push_back(p1);
pts.push_back(p2);
pts.push_back(p3);
pts.push_back(p4);
pts.push_back(p5);
const Point *ppts[1] = {&pts[0]};
const int n = 5;
const int *npt = &n;
fillPoly(canvas, ppts, npt,1,Scalar(0,255,0),LINE_8,0);
应该注意这里第二个形参是Point**类型,也是一个矩阵,用pts作为形参是不行的
运行成功
一开始debug摸不着头脑,后来通过入参检测锁定出问题的参数:
fillPoly(cv::Mat(), cv::noArray(), Scalar(255, 0, 0), 8, 0);
cv::Mat(),cv::noArray()可作为矩阵空参。
第二天,因为又遇到一个问题,在一个论坛发现是因为v4.0.0的问题,于是安上了v4.4.0,问题果然解决了。因此又校验了一下这个问题,果然按老师的入参方式成功了。