我們知道如果要求取輪廓可以使用findContours函數,
該函數會返回為vector<vector<Point> >的輪廓向量。
而在以前想對輪廓進行繪制我通常會使用遍歷這個vector然后依次將點繪制到img上
其實OpenCV里面已經有drawContours這個函數可以實現這個效果
具體來說,當我想將這個輪廓進行填充的時候我會有下面2步驟:
a)依次遍歷輪廓點,將點繪制到img上
void drawMaxAreaLine(cv::Mat &dst, const std::vector<cv::Point> maxAreaPoints) { int step = dst.step; auto data = dst.data; for (int i = 0; i < maxAreaPoints.size(); ++i) { *(data + maxAreaPoints[i].x + maxAreaPoints[i].y * step) = 255; } }
b)使用floodFill以及一個種子點進行填充
floodFill(savedGrayMat, Point(currentFrameEdge[0].x + 2, currentFrameEdge[0].y + 2), 255);
這里常會碰到種子點不好選取的問題,因為有時候所選擇的種子點不能保證對所有輪廓都適用。也就是查找一個在輪廓內的點是存在一定難度的。
ButInfact:
drawContours就可以辦到!
vector<vector<Point> > contours; contours.push_back(currentFrameEdge); Mat savedGrayMat = Mat::zeros(RectData[0].rows, RectData[0].cols, CV_8UC1); //drawMaxAreaLine(savedGrayMat, currentFrameEdge); //floodFill(savedGrayMat, Point(currentFrameEdge[0].x + 2, currentFrameEdge[0].y + 2), 255); drawContours(savedGrayMat, contours, 0, Scalar(255), CV_FILLED); imshow("savedGrayMat", savedGrayMat); waitKey();

上面中間的圖就是通過drawContours得到的
上面的左圖和中間圖進行與就可以得到右圖!
std::stringstream strStream; strStream << "L\\" << i << ".jpg"; string savedName = strStream.str(); bitwise_and(savedGrayMat, RectData[i], savedGrayMat); //這條語句進行與效果是將原始圖與上面得到的ROI圖進行&&使得只有中間圖的白色區域會留下左圖的信息
cv::imwrite(savedName, savedGrayMat);
