- OpenCvSharp安装(一)
- OpenCvSharp读取、显示和写入图像(二)
- OpenCvSharp图像裁剪、调整大小、旋转、透视(三)
- OpenCvSharp基本绘画(直线、椭圆、矩形、圆、多边形、文本)(四)
- OpenCvSharp 检测(斑点检测、边缘检测、轮廓检测)(五)
- OpenCvSharp 轮廓绘制六步骤(六)
- OpenCvSharp 目标检测五个步骤(七)
- OpenCvSharp透视矫正六步骤(八)
五 、检测(斑点检测、边缘检测、轮廓检测)
进行图像处理时,可以使用不同的算法和函数来实现斑点检测、边缘检测和轮廓检测。
1、斑点检测(Blob)
1)、SimpleBlobDetector
斑点检测是指在图像中找到明亮或暗的小区域(通常表示为斑点),并标记它们的位置。
可以使用OpenCV中的函数SimpleBlobDetector来实现斑点检测。
该函数将图像转换为二进制图像,然后找到所有的轮廓,通过设置阈值来确定斑点的亮度范围。-
SimpleBlobDetector是OpenCV中用于检测二值图像中的斑点的类,以下是它的参数说明:
- thresholdStep:二值化阈值步长,用于在二值化过程中逐步增加或减小阈值,默认为10。
- minThreshold:最小的二值化阈值,默认为50。
- maxThreshold:最大的二值化阈值,默认为220。
- minRepeatability:最小的斑点重复次数,默认为2,表示只有当一个斑点至少在两个不同位置被检测到时才会被认为是有效的。
- blobColor:斑点的亮度值,取值为0或255,默认为0,表示只检测黑色斑点。
- filterByArea:是否根据斑点的面积进行过滤,默认为true,表示进行过滤。
- minArea:最小的斑点面积,默认为25,表示只检测面积大于25的斑点。
- maxArea:最大的斑点面积,默认为5000,表示只检测面积小于5000的斑点。
- filterByCircularity:是否根据斑点的圆形度进行过滤,默认为false,表示不进行过滤。
- minCircularity:最小的斑点圆形度,默认为0.8,表示只检测圆形度大于0.8的斑点。
- maxCircularity:最大的斑点圆形度,默认为1,表示只检测圆形度小于1的斑点。
- filterByInertia:是否根据斑点的惯性比进行过滤,默认为true,表示进行过滤。
- minInertiaRatio:最小的斑点惯性比,默认为0.1,表示只检测惯性比大于0.1的斑点。
- maxInertiaRatio:最大的斑点惯性比,默认为1,表示只检测惯性比小于1的斑点。
- filterByConvexity:是否根据斑点的凸度进行过滤,默认为true,表示进行过滤。
- minConvexity:最小的斑点凸度,默认为0.95,表示只检测凸度大于0.95的斑点。
- 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);
2)、connectedComponentsWithStats
- 使用cv2.connectedComponentsWithStats找到所有连通区域及其统计数据。
过滤出可能是斑点的连通区域。
using OpenCvSharp.Blob;
Cv2.Threshold(bin, binary, 90, 255, ThresholdTypes.Binary); //二值化
Mat result = new Mat(my_img3.Size(), MatType.CV_8UC3);
CvBlobs blobs = new CvBlobs();
blobs.Label(binary);//斑点检测
blobs.RenderBlobs(my_img3, result);//渲染斑点
int text = 1; //数字
foreach (var item in blobs)
{
if ((item.Value.Area > 20)) // 检查标签区域 20
{
// float xxx=item.Value.
CvBlob b = item.Value;
Cv2.Circle(result, b.Contour.StartingPoint, 8, Scalar.Red, 2, LineTypes.AntiAlias);
Cv2.PutText(result, text.ToString(), new OpenCvSharp.Point(b.Centroid.X, b.Centroid.Y), //修改标签编号设置
HersheyFonts.HersheyComplex, 1, Scalar.Yellow, 2, LineTypes.AntiAlias);
int ratio = 100 * b.Area / (b.Rect.Width * b.Rect.Height);
// if (b.Area / (b.Rect.Width * b.Rect.Height) > 0.4)
// {
LogHelper.WriteLog("ratio=" + ratio.ToString() + ",Area=" + b.Area.ToString() + "Width=" + b.Rect.Width.ToString() + "Height=" + b.Rect.Height.ToString());
if (ratio >= 40)
{ ZpArr[i] = 0; }
// }
text++;
}
}
2、边缘检测
- 边缘检测是一种图像处理技术,可以找到图像中的边缘或边界。
OpenCV 中提供的两种重要边缘检测算法: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的值可以获得不同方向的边缘信息。输出图像的像素值表示了对应位置的边缘强度。
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算子在水平方向上进行边缘检测,然后显示结果图像。
2)、cv2.Canny()
public static void Canny(InputArray image, OutputArray edges, double threshold1, double threshold2, int apertureSize = 3, bool L2gradient = false)
3、轮廓检测
- 轮廓检测是一种从图像中提取物体形状的技术。
OpenCV中的cvFindContours函数可以实现轮廓检测。
该函数将图像转换为二进制图像,然后找到所有的轮廓。
参考
李建军的博客:https://blog.csdn.net/hb_ljj/article/details/135038353