需求:求下图中圆形的面积和周长;
原图如下:
处理后图像:
计算结果:
代码如下:
public Mat GetObjectByImg(Mat src,out double retArea, out double length)
{
retArea = 0;
length = 0;
//二值化
Mat binaryMat = new Mat();
Cv2.Threshold(src, binaryMat, 0, 255, ThresholdTypes.Binary | ThresholdTypes.Otsu);
Cv2.ImShow("binaryImg", binaryMat);
//形态学操作
Mat kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(9, 9), new Point(-1, -1));
Mat dst = new Mat();
//闭操作
Cv2.MorphologyEx(binaryMat, dst, MorphTypes.Close, kernel, new Point(-1, -1));
Cv2.ImShow("closeImg", dst);
//开操作
kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(9, 9), new Point(-1, -1));
Cv2.MorphologyEx(dst, dst, MorphTypes.Open, kernel, new Point(-1, -1));
Cv2.ImShow("openImg", dst);
//轮廓查找
Point[][] contours;
HierarchyIndex[] hierarchies;
Cv2.FindContours(dst, out contours, out hierarchies, RetrievalModes.Tree, ContourApproximationModes.ApproxSimple, new Point());
Mat retImg = Mat.Zeros(src.Size(), MatType.CV_8UC1);
int x = 0, y = 0;
Mat circleImage = new Mat();
for (int i = 0; i < contours.Length; i++)
{
//面积过滤
double area = Cv2.ContourArea(contours[i]);
if (area < 100)
{
continue;
}
//横纵比例 当横纵比例为1:1时
Rect rect = Cv2.BoundingRect(contours[i]);
double ratio = Convert.ToDouble(rect.Width) / Convert.ToDouble(rect.Height);
if (ratio > 0.9 && ratio < 1.1)
{
Cv2.DrawContours(retImg, contours, i, new Scalar(255, 255, 0), 1, LineTypes.Link8);
retArea = area;
length = Cv2.ArcLength(contours[i], true);
x = rect.X + rect.Width / 2;
y = rect.Y + rect.Height / 2;
Cv2.Circle(retImg, x, y, 2, new Scalar(128, 128, 128), 2, LineTypes.Link8, 0);
}
}
Cv2.ImShow("retImg", retImg);
circleImage = src.Clone();
Cv2.CvtColor(circleImage, circleImage, ColorConversionCodes.GRAY2BGR);
Cv2.Circle(circleImage, x, y, 2, new Scalar(0, 0, 255), 2, LineTypes.Link8, 0);
Cv2.ImShow("circleImage", circleImage);
return circleImage;
}
该案例基本操作步骤如上,针对于类似案例以及适当调节以上使用的算法参数;