方法取自Opencv2计算机视觉编程手册
图像分析的其中目标是识别并提取出这些物体。在物体检测中,我们首先要生成图像的二值图像,下一步则是提取连通区域。
二值图像的获取我们通过简单的阀值化操作和形态学开闭运算得到。
实验代码:
Matimage=imread("E:\\group.jpg",0);//提取二值图像
Mat thresholded;
Mat result;
threshold(image,thresholded,60,255,THRESH_BINARY);
bitwise_not(thresholded,result,Mat());
保存thresholded图像,命名为binary.png。
//形态学闭运算与开运算
Mat image=imread("E:\\binary.png");
Mat eroded;
Mat element(5,5,CV_8U,Scalar(1));
morphologyEx(image,eroded,MORPH_OPEN,element);
namedWindow(" Eroded Image");
imshow("Eroded Image",eroded);
Mat dilated;
dilate(image,dilated,Mat());
erode(dilated,dilated,Mat());
namedWindow("Dilated Image");
imshow("Dilated Image",dilated);
以上可以得到我们所需的二值图像
opencv中给我们提供了findContours这个函数用于提取连通区域轮廓。我们可以设置我们想要得到的轮廓大小,进行删减。
代码如下:
Mat image=imread("E:\\Dilated.png",0);
vector<std::vector<cv::Point> >contours;
findContours(image,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE);
Mat result(image.size(),CV_8U,Scalar(255));
drawContours(result,contours,-1,Scalar(0),2);
imshow("Contours",result);
int cmin=100;
int cmax=1000;
vector<std::vector<cv::Point> >::iterator itc = contours.begin();
while(itc!=contours.end())
{
if(itc->size()<cmin||itc->size()>cmax)
itc =contours.erase(itc);
else
itc++;
}
Mat image2=imread("E:\\group.jpg");
drawContours(image2,contours,-1,Scalar(255,255,255),2);
imshow("image",image2);
生成的图像如下:(图像上方还是有点瑕疵的,不过可以调整二值图像优化)