C#+OpenCV实战(四)_特定钢板缺陷检测
/// <summary>
/// 板材瑕疵检测(凹凸坑、划痕、颜料瑕疵)
/// </summary>
/// <param name="mat">图片</param>
/// <param name="resultMat">结果图片</param>
/// <param name="minArcLength">最小有效斑弧长;默认为5</param>
/// <param name="thickness">标注线条的宽度;默认为1</param>
/// <returns>斑点信息</returns>
public static Point[][] BoardSpot(Mat mat, out Mat resultMat, double minArcLength = 3, int thickness = 2)
{
List<Point[]> points = new List<Point[]>();
resultMat = new Mat();
mat.CopyTo(resultMat);
// 滤波 - 高斯滤波
Mat mat1 = new Mat();
Cv2.BilateralFilter(mat, mat1, 0, 20, 5);
// 二值化
Cv2.CvtColor(mat1, mat1, ColorConversionCodes.BGR2GRAY);
Cv2.Threshold(mat1, mat1, 100, 255, ThresholdTypes.BinaryInv);
//Cv2.ImShow("11",mat1);
//发现轮廓
/*
* 找轮廓(输入图像,out 轮廓集合,out 级别,轮廓检索模式,近似法,偏移量)
* 输入图像:单通道图像矩阵,可以是灰度图,但更常用的是二值图像,一般是经过Canny、拉普拉斯等边缘检测算子处理过的二值图像;
* 轮廓集合:contours
* 历史轮廓:hierarchy:0:后一个轮廓,1:前一个轮廓,2:父轮廓,3:内嵌轮廓
* 轮廓检索模式:轮廓的检索模式
* 取值一:CV_RETR_EXTERNAL 只检测最外围轮廓,包含在外围轮廓内的内围轮廓被忽略
* 取值二:CV_RETR_LIST 检测所有的轮廓,包括内围、外围轮廓,但是检测到的轮廓不建立等级关系,彼此之间独立,没有等级关系,这就意味着这个检索模式下不存在父轮廓或内嵌轮廓,所以hierarchy向量内所有元素的第3、第4个分量都会被置为-1,具体下文会讲到
* 取值三:CV_RETR_CCOMP 检测所有的轮廓,但所有轮廓只建立两个等级关系,外围为顶层,若外围内的内围轮廓还包含了其他的轮廓信息,则内围内的所有轮廓均归属于顶层
* 取值四:CV_RETR_TREE 检测所有轮廓,所有轮廓建立一个等级树结构。外层轮廓包含内层轮廓,内层轮廓还可以继续包含内嵌轮廓。
* 近似方法:轮廓的近似方法
* 取值一:CV_CHAIN_APPROX_NONE 保存物体边界上所有连续的轮廓点到contours向量内
* 取值二:CV_CHAIN_APPROX_SIMPLE 仅保存轮廓的拐点信息,把所有轮廓拐点处的点保存入contours向量内,拐点与拐点之间直线段上的信息点不予保留
* 取值三和四:CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain 近似算法
* 偏移量:Point偏移量,所有的轮廓信息相对于原始图像对应点的偏移量,相当于在每一个检测出的轮廓点上加上该偏移量,且Point可以是负值。不填为默认不偏移Point()
*/
Cv2.FindContours(mat1, out Point[][] contours, out HierarchyIndex[] hierarchy,
RetrievalModes.External, ContourApproximationModes.ApproxNone);
//绘制指定轮廓
for (int i = 0; i < contours.Length; i++)
{
double size = Cv2.ArcLength(contours[i], true); // 弧长
if (size > minArcLength)
{
Cv2.DrawContours(resultMat, contours, i, Scalar.Red, thickness);
points.Add(contours[i]);
}
}
return points.ToArray();
}
本文来自博客园,作者:꧁执笔小白꧂,转载请注明原文链接:https://www.cnblogs.com/qq2806933146xiaobai/p/18295843