在您的图像中有 5 个轮廓:2 个外部轮廓、2 个内部轮廓和右上角的 1 个。
您可以丢弃内部和外部轮廓,看看它们是 CW 还是 CCW。您可以使用带有定向标志的contourArea 来执行此操作:
oriented – 定向区域标志。如果为真,则函数根据轮廓方向(顺时针或逆时针)返回带符号的面积值。使用此功能,您可以通过获取区域的符号来确定轮廓的方向。该参数默认为false,即返回绝对值。
所以,用 red 绘制外部轮廓,用 green 绘制内部轮廓,您会得到:
然后您可以在下面的代码中只存储外部轮廓(参见externalContours):
#include <opencv2\opencv.hpp>
#include <vector>
using namespace std;
using namespace cv;
int main()
{
// Load grayscale image
Mat1b B = imread("path_to_image", IMREAD_GRAYSCALE);
// Find contours
vector<vector<Point>> contours;
findContours(B.clone(), contours, RETR_TREE, CHAIN_APPROX_NONE);
// Create output image
Mat3b out;
cvtColor(B, out, COLOR_GRAY2BGR);
vector<vector<Point>> externalContours;
for (size_t i=0; i<contours.size(); ++i)
{
// Find orientation: CW or CCW
double area = contourArea(contours[i], true);
if (area >= 0)
{
// Internal contours
drawContours(out, contours, i, Scalar(0, 255, 0));
}
else
{
// External contours
drawContours(out, contours, i, Scalar(0, 0, 255));
// Save external contours
externalContours.push_back(contours[i]);
}
}
imshow("Out", out);
waitKey();
return 0;
}
请记住findContours 损坏了输入图像(您显示的第二张图像是垃圾)。只需将图像的克隆传递给findContours 即可避免原始图像损坏。