最近需要通过 OpenCV 来给输出的图像画多边形,看了一些帖子之后发现 fillPoly() 函数很好用,在这里记录一下。
cv::fillPoly()
有多个重载版本,这里记录以下两个:
第一个版本
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
是多边形的各个顶点,color
和 lineType
分别是多边形的颜色和边框类型,shift
和 offset
分别是对点坐标的偏移和多边形整体的偏移。需要注意的是由于这个 API 不限定用来画凸多边形,也可以用来画凹多边形或者自身交叉的多边形,所以 pts
的顺序需要保证是你想要的多边形的顶点顺序。下面用两个例子说明。
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));
上面的代码段的效果如下:
可以发现按照这个顺序的多边形画出来是自身交叉的。如果把其中其中第二和第三个点换一下,效果如下:
第二个版本
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
需要坐一定转换,使用的例子如下:
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);
效果和上图一样。