还未有时间做注解,代码里面基本有简单的注解。
使用Python、C++写OpenCV不难,使用C#则很多语法找不到,本文里面很多函数的使用,都是查看C++源代码,花费很多时间才写出来的
public static OpenCvSharp.Mat Detection(Mat src0, string[] Para, out int Count
, out string OutInfo, OpenCvSharp.Point[][] RectCnts, Mat SrcOriginalDraw
, out Mat SrcOriginal, bool BoxCorn) //传入目标参数
{
OutInfo = "";
Mat src = src0;
Mat src2 = src0;
SrcOriginal = src0;
Mat dst = new Mat();
Cv2.GaussianBlur(src, dst, new OpenCvSharp.Size(5, 5), 0);//高斯模糊
//Cv2.MedianBlur(src,dst,5);
//处理反光
//Mat illum = new Mat();
//Mat illumMask = new Mat(Environment.CurrentDirectory+ "\\BlackMask2.jpg", ImreadModes.Color);
//illumMask = Mat.Zeros(illumMask.Size(),OpenCvSharp.MatType.CV_8UC1);
//Cv2.IlluminationChange(dst,illumMask,illum,0.2f,0.4f);
//转位HSV格式
var HSV = new Mat();
Cv2.CvtColor(dst, HSV, ColorConversionCodes.BGR2HSV);
//颜色过滤
var Mask = new Mat();
Cv2.InRange(HSV, new Scalar(int.Parse(Para[0]), int.Parse(Para[1]), int.Parse(Para[2]))
, new Scalar(int.Parse(Para[3]), int.Parse(Para[4]), int.Parse(Para[5])), Mask);
//做按位与运算
Mat Things = new Mat();
Cv2.BitwiseAnd(src, src, Things, Mask);
//二值化
Mat ErodeHSV = new Mat();
Cv2.Erode(Things, ErodeHSV, null, null, int.Parse(Para[6]));
//灰度图
Mat ThingsGray = new Mat();
OpenCvSharp.HierarchyIndex[] cnts = null;
OpenCvSharp.Point[][] cntsArray = null;
Cv2.CvtColor(ErodeHSV, ThingsGray, ColorConversionCodes.RGB2GRAY);
//查找边界
Cv2.FindContours(ThingsGray, out cntsArray, out cnts, RetrievalModes.External
, ContourApproximationModes.ApproxSimple);
int MaxBox = -1;
double MaxBoxArea = 0;
for (int i = 0; i < RectCnts.Length; i++)
{
if (Cv2.ContourArea(RectCnts[i]) > MaxBoxArea)
{
MaxBoxArea = Cv2.ContourArea(RectCnts[i]);
MaxBox = i;
}
}
OpenCvSharp.RotatedRect[] Box = new RotatedRect[cntsArray.Length];
//OpenCvSharp.CircleSegment[] Cir = new OpenCvSharp.CircleSegment[cntsArray.Length];
//Cv2.DrawContours(src2, cntsArray, -1, new Scalar(0, 255, 0), 9);
//double SumArea = 0;
Count = 0;
//Point2f center2f;
//float radius;
//OpenCvSharp.Point center;
//int MaxIndex = 0, SecondIndex = 0;
string Feature = "";
OpenCvSharp.Point BoxCenter;
for (int i = 0; i < cntsArray.Length; i++)
{
//在这里画方框 最小方框
Box[i] = Cv2.MinAreaRect(cntsArray[i]);
//Cv2.MinEnclosingCircle(cntsArray[i], out center2f, out radius);
//center.X = int.Parse(Math.Round(center2f.X, 0).ToString());
//center.Y = int.Parse(Math.Round(center2f.Y, 0).ToString());
//OpenCvSharp.Point2f[] Vertex = new OpenCvSharp.Point2f[4];
var Vertex = Box[i].Points();
if (BoxCorn == false)//为true的时候,四个点必须在盒子里
{
if (Box[i].Size.Height * Box[i].Size.Width > double.Parse(Para[7]) //Cv2.ContourArea(cntsArray[i]) > double.Parse(Threshold.Text) 改为用圆面积判断阈值 3.14 * radius * radius
&& Box[i].Size.Height * Box[i].Size.Width < double.Parse(Para[8])
&& (Box[i].Size.Height >= Box[i].Size.Width ? Box[i].Size.Height : Box[i].Size.Width) > double.Parse(Para[9]) //长边范围
&& (Box[i].Size.Height >= Box[i].Size.Width ? Box[i].Size.Height : Box[i].Size.Width) < double.Parse(Para[10])
&& (Box[i].Size.Height >= Box[i].Size.Width ? Box[i].Size.Width : Box[i].Size.Height) > double.Parse(Para[11]) //短边范围
&& (Box[i].Size.Height >= Box[i].Size.Width ? Box[i].Size.Width : Box[i].Size.Height) < double.Parse(Para[12])
&& Cv2.PointPolygonTest(RectCnts[MaxBox], Box[i].Center, false) == 1 //是否在多边形范围内
)
{
Count = Count + 1;
//Cv2.Circle(src2,center, int.Parse(Math.Round(radius,0).ToString()), new Scalar(0, 255, 0), 9);
Feature = "Feature" + Count.ToString() + ":"
+ (Box[i].Size.Height * Box[i].Size.Width).ToString("0") + ";"
+ Box[i].Size.Height.ToString("0") + ";"
+ Box[i].Size.Width.ToString("0");
OutInfo = OutInfo + Feature + "\n";
OpenCvSharp.Point2f[] Vector3 = new OpenCvSharp.Point2f[4];
Vector3 = Box[i].Points();
OpenCvSharp.Point[][] Vector31 = new OpenCvSharp.Point[1][];
Vector31[0] = new OpenCvSharp.Point[4];
for (int j = 0; j < Vector3.Length; j++)
{
Vector31[0][j].X = int.Parse(Math.Round(Vector3[j].X, 0).ToString());
Vector31[0][j].Y = int.Parse(Math.Round(Vector3[j].Y, 0).ToString());
}
Cv2.DrawContours(src2, Vector31, -1, new Scalar(0, 255, 0), 9);
Cv2.FillPoly(src2, Vector31, new Scalar(0, 255, 0));//填充矩形
//Cv2.DrawContours(SrcOriginalDraw, Vector31, -1, new Scalar(0, 255, 255), 9);
//打特征值
OpenCvSharp.HersheyFonts font = new HersheyFonts();
BoxCenter.X = int.Parse(Math.Round(Box[i].Center.X, 0).ToString());
BoxCenter.Y = int.Parse(Math.Round(Box[i].Center.Y, 0).ToString());
Cv2.PutText(SrcOriginalDraw, Feature, BoxCenter, font, 1, new Scalar(0, 0, 255), 2);
}
}
else
{
if (Box[i].Size.Height * Box[i].Size.Width > double.Parse(Para[7]) //Cv2.ContourArea(cntsArray[i]) > double.Parse(Threshold.Text) 改为用圆面积判断阈值 3.14 * radius * radius
&& Box[i].Size.Height * Box[i].Size.Width < double.Parse(Para[8])
&& (Box[i].Size.Height >= Box[i].Size.Width ? Box[i].Size.Height : Box[i].Size.Width) > double.Parse(Para[9]) //长边范围
&& (Box[i].Size.Height >= Box[i].Size.Width ? Box[i].Size.Height : Box[i].Size.Width) < double.Parse(Para[10])
&& (Box[i].Size.Height >= Box[i].Size.Width ? Box[i].Size.Width : Box[i].Size.Height) > double.Parse(Para[11]) //短边范围
&& (Box[i].Size.Height >= Box[i].Size.Width ? Box[i].Size.Width : Box[i].Size.Height) < double.Parse(Para[12])
&& Cv2.PointPolygonTest(RectCnts[MaxBox], Box[i].Center, false) == 1 //判断是否在多边形内
&& Cv2.PointPolygonTest(RectCnts[MaxBox], Vertex[0], false) == 1 //四个顶点
&& Cv2.PointPolygonTest(RectCnts[MaxBox], Vertex[1], false) == 1
&& Cv2.PointPolygonTest(RectCnts[MaxBox], Vertex[2], false) == 1
&& Cv2.PointPolygonTest(RectCnts[MaxBox], Vertex[3], false) == 1
)
{
Count = Count + 1;
//Cv2.Circle(src2,center, int.Parse(Math.Round(radius,0).ToString()), new Scalar(0, 255, 0), 9);
Feature = "Feature" + Count.ToString() + ":"
+ (Box[i].Size.Height * Box[i].Size.Width).ToString("0") + ";"
+ Box[i].Size.Height.ToString("0") + ";"
+ Box[i].Size.Width.ToString("0");
OutInfo = OutInfo + Feature + "\n";
OpenCvSharp.Point2f[] Vector3 = new OpenCvSharp.Point2f[4];
Vector3 = Box[i].Points();
OpenCvSharp.Point[][] Vector31 = new OpenCvSharp.Point[1][];
Vector31[0] = new OpenCvSharp.Point[4];
for (int j = 0; j < Vector3.Length; j++)
{
Vector31[0][j].X = int.Parse(Math.Round(Vector3[j].X, 0).ToString());
Vector31[0][j].Y = int.Parse(Math.Round(Vector3[j].Y, 0).ToString());
}
Cv2.DrawContours(src2, Vector31, -1, new Scalar(0, 255, 0), 9);
Cv2.FillPoly(src2, Vector31, new Scalar(0, 255, 0));//填充矩形
//Cv2.DrawContours(SrcOriginalDraw, Vector31, -1, new Scalar(0, 255, 255), 9);
//打特征值
OpenCvSharp.HersheyFonts font = new HersheyFonts();
BoxCenter.X = int.Parse(Math.Round(Box[i].Center.X, 0).ToString());
BoxCenter.Y = int.Parse(Math.Round(Box[i].Center.Y, 0).ToString());
//在图片上写字,打标记
Cv2.PutText(SrcOriginalDraw, Feature, BoxCenter, font, 1, new Scalar(0, 0, 255), 2);
}
}
}
SrcOriginal = SrcOriginalDraw;
return src2;
}