关于opencv的findContours函数的一个问题
实测opencv的findContours函数存在把距离为12个像素以下的两个区域当作一个区域提取轮廓;
如图,最近的轮廓不能进行区分;
测试代码为
cv::cvtColor(imgIn, imgIn, CV_BGR2GRAY);
cv::imshow("testImg", imgIn);
cv::Mat element = cv::getStructuringElement(CV_SHAPE_RECT, cv::Size(1,1));
cv::morphologyEx(imgIn, imgIn, CV_MOP_ERODE, element);
std::vector<std::vector<cv::Point>> contours;
std::vector<cv::Vec4i> hierarchy;
cv::findContours(imgIn, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
cv::drawContours(imgIn,contours,cv::Scalar(100),2);
for (auto x : contours) {
cv::circle(imgIn, getCentre(x), 4, cv::Scalar(0), -1);
}
观察到最左侧的正方形虽然没有被认为是独立的区域(没有对其计算质心),但是似乎具有独立的轮廓描述,推断是因为findcontours的查找机制,使得其轮廓在某一位置连通了,所以实际上仍然是连在一起的轮廓;
稍微缩小一下间隙,使间隙缩小到10,有
这个就很明显了;
采用cv::findContours函数对目标轮廓进行提取的各位使用时还要注意一下这个问题;
问题说明
拿图试了几次发现是因为在opencv里,读取二值图时(即便是用opencv自己生成的二值图像保存之后在读入的),取值为255的目标像素周围的点其实不是0,而是可能有部分点的像素值被读取为0-20,不知道是保存的原因还是读取的原因,所以使用findcontours时要注意进行一次额外的二值化,以避免由于存在部分低值像素导致相邻的结构被视为一个整体进行轮廓提取;
划重点
用findContours之前务必进行二值化;