0%

使用 OpenCV 的 fillPoly() 函数画多边形

最近需要通过 OpenCV 来给输出的图像画多边形,看了一些帖子之后发现 fillPoly() 函数很好用,在这里记录一下。

cv::fillPoly() 有多个重载版本,这里记录以下两个:

第一个版本

1
2
3
CV_EXPORTS_W void fillPoly(InputOutputArray img, InputArrayOfArrays pts,
const Scalar& color, int lineType = LINE_8, int shift = 0,
Point offset = Point() );

这个 API 比较好理解,img 是需要画多边形的图像, pts 是多边形的各个顶点,colorlineType 分别是多边形的颜色和边框类型,shiftoffset 分别是对点坐标的偏移和多边形整体的偏移。需要注意的是由于这个 API 不限定用来画凸多边形,也可以用来画凹多边形或者自身交叉的多边形,所以 pts 的顺序需要保证是你想要的多边形的顶点顺序。下面用两个例子说明。

1
2
3
4
5
6
7
8
9
cv::Mat image(cv::Size(540, 540), CV_8UC1);
std::vector<cv::Point> fillContSingle;
//add all points of the contour to the vector
fillContSingle.push_back(cv::Point(200, 100));
fillContSingle.push_back(cv::Point(200, 200));
fillContSingle.push_back(cv::Point(100, 200));
fillContSingle.push_back(cv::Point(300, 100));

cv::fillPoly( image, std::vector<std::vector<cv::Point>>{fillContSingle}, cv::Scalar(128));

上面的代码段的效果如下:

可以发现按照这个顺序的多边形画出来是自身交叉的。如果把其中其中第二和第三个点换一下,效果如下:

第二个版本

1
2
3
4
CV_EXPORTS void fillPoly(Mat& img, const Point** pts,
const int* npts, int ncontours,
const Scalar& color, int lineType = LINE_8, int shift = 0,
Point offset = Point() );

这个重载版本其实看不太懂跟第一个区别在哪里,需要额外设置参数的参数有每个多边形的点的数量和多边形的数量。感觉上是能够更明确自己需要画的效果,不过我自己没有尝试过,所以这里只是简单记录一下。需要注意的是这里点的参数是二维的Point 指针所以不能直接传入 vector 需要坐一定转换,使用的例子如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
std::vector<cv::Point> fillContSingle;
//add all points of the contour to the vector
fillContSingle.push_back(cv::Point(100, 100));
fillContSingle.push_back(cv::Point(100, 200));
fillContSingle.push_back(cv::Point(-200, 200));
fillContSingle.push_back(cv::Point(200, 100));

std::vector<std::vector<cv::Point> > fillContAll;

fillContAll.push_back(fillContSingle);

// convert 2d vector to Point**
std::vector<Point> tmp = fillContAll.at(0);
const Point* elementPoints[1] = { &tmp[0] };
int numberOfPoints = (int)tmp.size();
fillPoly (image, elementPoints, &numberOfPoints, 1, Scalar (128), 8);

效果和上图一样。

参考:StackOverFlow