截取任意四边形区域的图像。
mask就是结果。
需要定义四边形区域,分别是 tl, tr, bl, br
std::map<int, std::set<int>> generateBorders(const std::vector<cv::Point> & vecPts)
{
std::map<int, std::set<int>> borders;
cv::Point tl(vecPts[0]), tr(vecPts[1]), bl(vecPts[2]), br(vecPts[3]); // tl to tr
double K = double(tl.y-tr.y) / (tl.x - tr.x);
for (int i = tl.x; i < tr.x; ++i)
borders[i].insert(cvRound(-K*(tl.x - i) + tl.y)); // tr to br
if (tr.x != br.x)
{
K = double(tr.y - br.y) / (tr.x - br.x);
for (int i = tr.x; i < br.x; ++i)
borders[i].insert(cvRound(-K*(tr.x - i) + tr.y));
} // br to bl
K = double(br.y - bl.y) / (br.x - bl.x);
for (int i = bl.x; i < br.x; ++i)
borders[i].insert(cvRound(-K*(br.x - i) + br.y)); // bl to tl
if (bl.x != tl.x)
{
K = double(bl.y - tl.y) / (bl.x - tl.x);
for (int i = tl.x; i < bl.x; ++i)
borders[i].insert(cvRound(-K*(bl.x - i) + bl.y));
} for (auto it = borders.begin(); it!=borders.end(); ++it)
{
if ((*it).second.size() == 2)
continue; std::set<int> newone = { *(*it).second.begin(), *(--(*it).second.end())};
(*it).second.swap(newone);
} #ifdef DEBUG_CODE
cv::Mat disp = cv::imread("1111.PNG", CV_LOAD_IMAGE_COLOR); for (auto it = borders.begin(); it != borders.end(); ++it)
{
cv::circle(disp, cv::Point((*it).first, *(*it).second.begin()), 1, cv::Scalar(255, 255, 0), -1);
cv::circle(disp, cv::Point((*it).first, *(--(*it).second.end())), 1, cv::Scalar(0, 255, 255), -1); } cv::circle(disp, tl, 2, cv::Scalar(0, 0, 255), -1);
cv::circle(disp, tr, 2, cv::Scalar(0, 0, 255), -1);
cv::circle(disp, bl, 2, cv::Scalar(0, 0, 255), -1);
cv::circle(disp, br, 2, cv::Scalar(0, 0, 255), -1);
#endif // DEBUG_CODE return borders;
} cv::Mat generateMask(const cv::Mat & src,
const std::vector<cv::Point> & vecPts)
{
cv::Mat mask = cv::Mat::zeros(src.size(), CV_8UC1); cv::Point tl(vecPts[0]), tr(vecPts[1]), bl(vecPts[2]), br(vecPts[3]);
std::map<int, std::set<int>> borders = generateBorders(vecPts); int minX = std::min(tl.x, bl.x),
maxX = std::max(tr.x, br.x),
minY = std::min(tl.y, tr.y),
maxY = std::max(bl.y, br.y); uchar minZ = std::min(src.at<uchar>(tl), src.at<uchar>(tr));
minZ = std::min(minZ, src.at<uchar>(bl));
minZ = std::min(minZ, src.at<uchar>(br)); for (size_t j= minY; j<maxY; ++j)
{
const uchar* pS = src.ptr<uchar>(j);
uchar* pM = mask.ptr<uchar>(j); for (size_t i = minX; i < maxX; ++i)
{
// in the region.
if (*borders[i].begin() < j && j < *(++borders[i].begin()))
{
pM[i] = pS[i];
}
}
} return mask; }