最近在项目中需要提取多边形区域,并传入到算子中计算,故记录一下对多边形mask区域的提取方法。
#include
using namespace cv;
int main()
{
Mat src = imread(R"(E:\picture\picture_for_test\8.jpg)", 1); // replace image path
vector> mask_area;
vector mask_points;
mask_points.push_back(Point(100, 200));
mask_points.push_back(Point(500, 300));
mask_points.push_back(Point(520, 460));
mask_points.push_back(Point(300, 420));
mask_points.push_back(Point(200, 330));
mask_points.push_back(Point(100, 250));
mask_area.push_back(mask_points);
polylines(src, mask_area, 1, Scalar(0, 0, 0));
imshow("resource", src);
cv::Mat mask, dst;
src.copyTo(mask);
mask.setTo(cv::Scalar::all(0));
fillPoly(mask, mask_area, Scalar(255, 255, 255));
imshow("mask", mask);
src.copyTo(dst, mask);
imshow("dst", dst);
waitKey();
return 0;
}
关键函数为:fillPoly,该函数提供两种调用接口,分别如下:
void fillPoly(Mat& img, const Point** pts,
const int* npts, int ncontours,
const Scalar& color, int lineType=8, int shift=0,
Point offset=Point() );
void fillPoly(InputOutputArray img, InputArrayOfArrays pts,
const Scalar& color, int lineType=8, int shift=0,
Point offset=Point() );
这里使用到第二种调用接口,其具体实现代码如下:
void cv::fillPoly(InputOutputArray img, InputArrayOfArrays pts,
const Scalar& color, int lineType, int shift, Point offset)
{
CV_INSTRUMENT_REGION();
int i, ncontours = (int)pts.total();
if( ncontours == 0 )
return;
AutoBuffer _ptsptr(ncontours);
AutoBuffer _npts(ncontours);
Point** ptsptr = _ptsptr.data();
int* npts = _npts.data();
for( i = 0; i < ncontours; i++ )
{
Mat p = pts.getMat(i);
CV_Assert(p.checkVector(2, CV_32S) >= 0);
ptsptr[i] = p.ptr();
npts[i] = p.rows*p.cols*p.channels()/2;
}
fillPoly(img, (const Point**)ptsptr, npts, (int)ncontours, color, lineType, shift, offset);
}
可见,最终还是调用第一个接口实现。