c# OpenCvSharp实现常见检测(斑点检测,轮廓检测,边缘检测)
作者:李建军
在C#中使用OpenCV进行图像处理时,可以使用不同的算法和函数来实现斑点检测、边缘检测和轮廓检测。
- 斑点检测
- 边缘检测
- 轮廓检测
一、斑点检测(Blob)
斑点检测是指在图像中找到明亮或暗的小区域(通常表示为斑点),并标记它们的位置。可以使用OpenCV中的函数SimpleBlobDetector来实现斑点检测。该函数将图像转换为二进制图像,然后找到所有的轮廓,通过设置阈值来确定斑点的亮度范围。
SimpleBlobDetector.Params
//函数原型 public Params() { Data = new WParams { thresholdStep = 10f, minThreshold = 50f, maxThreshold = 220f, minRepeatability = 2u, minDistBetweenBlobs = 10f, filterByColor = 1, blobColor = 0, filterByArea = 1, minArea = 25f, maxArea = 5000f, filterByCircularity = 0, minCircularity = 0.8f, maxCircularity = float.MaxValue, filterByInertia = 1, minInertiaRatio = 0.1f, maxInertiaRatio = float.MaxValue, filterByConvexity = 1, minConvexity = 0.95f, maxConvexity = float.MaxValue }; }
SimpleBlobDetector是OpenCV中用于检测二值图像中的斑点的类,以下是它的参数说明:
1. thresholdStep:二值化阈值步长,用于在二值化过程中逐步增加或减小阈值,默认为10。
2. minThreshold:最小的二值化阈值,默认为50。
3. maxThreshold:最大的二值化阈值,默认为220。
4. minRepeatability:最小的斑点重复次数,默认为2,表示只有当一个斑点至少在两个不同位置被检测到时才会被认为是有效的。
5. blobColor:斑点的亮度值,取值为0或255,默认为0,表示只检测黑色斑点。
6. filterByArea:是否根据斑点的面积进行过滤,默认为true,表示进行过滤。
7. minArea:最小的斑点面积,默认为25,表示只检测面积大于25的斑点。
8. maxArea:最大的斑点面积,默认为5000,表示只检测面积小于5000的斑点。
9. filterByCircularity:是否根据斑点的圆形度进行过滤,默认为false,表示不进行过滤。
10. minCircularity:最小的斑点圆形度,默认为0.8,表示只检测圆形度大于0.8的斑点。
11. maxCircularity:最大的斑点圆形度,默认为1,表示只检测圆形度小于1的斑点。
12. filterByInertia:是否根据斑点的惯性比进行过滤,默认为true,表示进行过滤。
13. minInertiaRatio:最小的斑点惯性比,默认为0.1,表示只检测惯性比大于0.1的斑点。
14. maxInertiaRatio:最大的斑点惯性比,默认为1,表示只检测惯性比小于1的斑点。
15. filterByConvexity:是否根据斑点的凸度进行过滤,默认为true,表示进行过滤。
16. minConvexity:最小的斑点凸度,默认为0.95,表示只检测凸度大于0.95的斑点。
17. maxConvexity:最大的斑点凸度,默认为1,表示只检测凸度小于1的斑点。
这些参数可以根据具体应用场景进行调整,以得到符合要求的斑点检测结果。
所使用图例
// 读取原始图像 Mat image = new Mat("1.jpg", ImreadModes.Color); // 创建SimpleBlobDetector参数 SimpleBlobDetector.Params parameters = new SimpleBlobDetector.Params(); // 设置参数 parameters.FilterByArea = true; parameters.MinArea = 100; parameters.MaxArea = 10000; // 创建SimpleBlobDetector SimpleBlobDetector detector = SimpleBlobDetector.Create(parameters); // 检测斑点 KeyPoint[] keypoints = detector.Detect(image); // 在图像上绘制斑点 Mat result = new Mat(); Cv2.DrawKeypoints(image, keypoints, result, Scalar.All(-1), DrawMatchesFlags.Default); // 显示结果 Cv2.ImShow("Result", result); Cv2.WaitKey(0);
二、边缘检测
边缘检测是一种图像处理技术,可以找到图像中的边缘或边界。penCV 中提供的两种重要边缘检测算法:Sobel边缘检测和 canny边缘检测。
1、cv2.Sobel()
//函数原型 public static void Sobel( InputArray src, OutputArray dst, int ddepth, int dx, int dy, int ksize = 3, double scale = 1, double delta = 0, BorderType borderType = BorderType.Default )
参数说明:
src:输入图像。
dst:输出图像,是一个与输入图像相同大小和类型的图像。
ddepth:输出图像的深度,通常使用-1表示与输入图像相同深度。
dx:表示在水平方向上进行边缘检测的阶数。
dy:表示在垂直方向上进行边缘检测的阶数。
ksize:表示卷积核的大小,默认为3。
scale:可选参数,用于缩放结果,默认为1。
delta:可选参数,用于调整结果的偏移,默认为0。
borderType:可选参数,用于指定边界的处理方式,默认为BorderType.Default。
使用cv2.Sobel函数可以进行边缘检测,通过调整dx和dy的值可以获得不同方向的边缘信息。输出图像的像素值表示了对应位置的边缘强度。
cv2.Sobel函数进行边缘检测的示例
using OpenCvSharp; Mat srcImage = new Mat("input.jpg", ImreadModes.Color); Mat grayImage = new Mat(); Cv2.CvtColor(srcImage, grayImage, ColorConversionCodes.BGR2GRAY); Mat edges = new Mat(); Cv2.Sobel(grayImage, edges, MatType.CV_8U, 1, 0, 3); Cv2.ImShow("Edges", edges); Cv2.WaitKey(0);
这个示例将输入图像转换为灰度图像,并使用Sobel算子在水平方向上进行边缘检测,然后显示结果图像。
总之,cv2.Sobel函数是OpenCVSharp库中的一个函数,用于在图像上应用Sobel算子进行边缘检测。通过调整参数可以获得不同方向的边缘信息。
2、cv2.Canny()
public static void Canny(InputArray image, OutputArray edges, double threshold1, double threshold2, int apertureSize = 3, bool L2gradient = false)
参数说明:
image:要进行边缘检测的输入图像。
edges:输出的边缘图像。
threshold1:第一个阈值,用于边缘链接。
threshold2:第二个阈值,用于边缘链接。
apertureSize:Sobel算子的孔径大小,默认为3。
L2gradient:一个布尔值,指定求梯度大小的方法,默认为false。
Canny边缘检测算法的原理是:首先对图像进行高斯滤波,然后通过Sobel算子计算图像的梯度,再通过非极大值抑制来提取局部最大值作为边缘点,最后通过双阈值检测来连接边缘点。
cv2.Canny函数的示例代码:
using OpenCvSharp; class Program { static void Main(string[] args) { // 读取图像 Mat image = Cv2.ImRead("image.jpg", ImreadModes.Color); // 将图像转换为灰度图像 Mat grayImage = new Mat(); Cv2.CvtColor(image, grayImage, ColorConversionCodes.BGR2GRAY); // 使用Canny边缘检测算法检测边缘 Mat edges = new Mat(); Cv2.Canny(grayImage, edges, 100, 200); // 显示原始图像和边缘图像 Cv2.ImShow("Original Image", image); Cv2.ImShow("Edges", edges); Cv2.WaitKey(0); // 释放内存 Cv2.DestroyAllWindows(); image.Dispose(); grayImage.Dispose(); edges.Dispose(); } }
这个示例代码从文件中读取图像,然后将其转换为灰度图像。然后,它使用Canny边缘检测算法检测图像中的边缘,并将结果显示出来。最后,释放内存并关闭窗口。
注意:在运行此代码之前,确保已在项目中添加对OpenCVSharp库的引用,并将图像文件与示例代码放在同一目录下,并将图像文件名替换为实际的图像文件名
三、 轮廓检测
轮廓检测是一种从图像中提取物体形状的技术。OpenCV中的cvFindContours函数可以实现轮廓检测。该函数将图像转换为二进制图像,然后找到所有的轮廓。
轮廓检测步骤
- Cv2.CvtColor彩色图像转换为灰度图像
- cv2.threshold函数用于将图像进行二值化处理
- Cv2.FindContours在图像中查找轮廓
- Cv2.DrawContours在图像上绘制轮廓
示例代码
// 读取图像 Mat image = Cv2.ImRead("1.png", ImreadModes.Color); // 将图像转换为灰度图像 Mat grayImage = new Mat(); Cv2.CvtColor(image, grayImage, ColorConversionCodes.BGR2GRAY); // 进行BGR2GRAY转换 Mat ThresholdImage = new Mat(); Cv2.Threshold(grayImage, ThresholdImage, 150, 255, ThresholdTypes.Binary); // 对图像进行二值化处理 Cv2.ImShow("ThresholdImage", ThresholdImage); Cv2.WaitKey(0); OpenCvSharp.Point[][] contours; HierarchyIndex[] hierarchy; Cv2.FindContours(ThresholdImage, out contours, out hierarchy, RetrievalModes.List, ContourApproximationModes.ApproxSimple); Scalar color = new Scalar(0, 255, 0); // 轮廓颜色为绿色 int thickness = 2; // 轮廓线粗细为2 for (int i = 0; i < contours.Length; i++) { Cv2.DrawContours(ThresholdImage, contours, i, color, thickness); // 绘制轮廓 } Cv2.ImShow("Contours", ThresholdImage); // 显示图像 Cv2.WaitKey(0);
以上就是c# OpenCvSharp实现常见检测(斑点检测,轮廓检测,边缘检测)的详细内容,更多关于c# OpenCvSharp的资料请关注脚本之家其它相关文章!