C#opencvsharp实现十字定位中心
包安装opencvsharp,mathnet,numpy可不用,有些可以自己手敲
三个函数:最终调用函数 cirCenter()
//cleanline清除重复线函数 //getPoint计算交点函数
这里使用了mask,也可以不用mask.我纯是第一次做这个,借鉴一个python的代码(找不到是哪位大佬的了,属实是找了好久才找到的)
他这里直线去重是非常不好用的,我觉得使用角度判断非常好用,一般直接就得出了四条线(我觉得应该是大佬的藏拙,
),但是我不懂,还是在做九点标定板上定位九个十字中心的时候发现的。我也不懂,但是就稀里糊涂的定位出来了

public void cirCenter()
{
OpenCvSharp.Mat oriPic = Cv2.ImRead("C:\\Users\\LEIPENG\\source\\repos\\OnTimeCapture\\OnTimeCapture\\bin\\Debug\\Camera\\A.jpg");
OpenCvSharp.Mat src1 = Cv2.ImRead("C:\\Users\\LEIPENG\\source\\repos\\OnTimeCapture\\OnTimeCapture\\bin\\Debug\\Camera\\A.jpg", 0);
//OpenCvSharp.Mat src1 = Cv2.ImRead("C:\\Users\\LEIPENG\\Desktop\\nineTen.png",0);
//Cv2.CvtColor(src, src, ColorConversionCodes.GRAY2BGR);
OpenCvSharp.Mat gray = new OpenCvSharp.Mat(), binary = new OpenCvSharp.Mat(), vline = new OpenCvSharp.Mat();
gray = src1;
//二值化
Cv2.Threshold(gray, binary, 150, 255, ThresholdTypes.BinaryInv); //形态学处理
OpenCvSharp.Mat kernel2 = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(10, 10), new OpenCvSharp.Point(-1, -1));
Cv2.MorphologyEx(binary, vline, MorphTypes.Open, kernel2, new OpenCvSharp.Point(-1, -1));
Cv2.MedianBlur(vline, vline, 5);
//Cv2.ImShow("提取边缘线前二值化图", vline);
OpenCvSharp.Mat mat = new OpenCvSharp.Mat();
vline.ConvertTo(vline, MatType.CV_8UC1);
Cv2.Canny(vline, vline, 0, 150);
//Cv2.ImShow("二值化去噪提取边缘线", vline);
var cir = Cv2.HoughCircles(vline, HoughModes.Gradient, 1, 20, 50, 30, 0, 0);
OpenCvSharp.Mat mask = OpenCvSharp.Mat.Zeros(vline.Size(), MatType.CV_8U); // 创建遮罩
//Cv2.BitwiseNot(mask, mask);
//OpenCvSharp.Point[][] contours=null;
float x1 = cir[1].Center.X - cir[1].Radius;
float x2 = cir[1].Center.X + cir[1].Radius;
float y1 = cir[1].Center.Y - cir[1].Radius;
float y2 = cir[1].Center.Y + cir[1].Radius;
OpenCvSharp.Point point1 = new OpenCvSharp.Point(x1, cir[1].Center.Y);//左上
OpenCvSharp.Point point2 = new OpenCvSharp.Point(cir[1].Center.X, y2);//右上
OpenCvSharp.Point point3 = new OpenCvSharp.Point(cir[1].Center.X, y1);//左下
OpenCvSharp.Point point4 = new OpenCvSharp.Point(x2, cir[1].Center.Y);//右下
OpenCvSharp.Point[] poi = { point1, point2, point4, point3 };
Cv2.ImShow("操作之前", vline);
Cv2.DrawContours(mask, new[] { poi }, -1, new Scalar(255), -1);
Cv2.ImShow("mask画矩形", mask);
OpenCvSharp.Mat invertedMask = new OpenCvSharp.Mat();
Cv2.BitwiseAnd(vline, vline, invertedMask, mask: mask);//实现遮罩///已经用不到
//invertedMask = vline;
Mat edges = new Mat();
//Cv2.Canny(invertedMask, edges, 45, 135);
edges = vline;
Cv2.ImShow("HoughLines操作之前", invertedMask);
var lines = Cv2.HoughLines(edges, 1, Cv2.PI / 180, 120);
List<LineSegmentPolar> list = cleanline(lines);
Point[] point = getPoint(list).ToArray();
foreach (var line in list)
{
var rho = line.Rho;
var theta = line.Theta;
var a = Math.Cos(theta);
var b = Math.Sin(theta);
var x0 = a * rho;
var y0 = b * rho;
var x11 = Convert.ToInt32(x0 + 2000 * (-b));
var y11 = Convert.ToInt32(y0 + 2000 * (a));
var x22 = Convert.ToInt32(x0 - 2000 * (-b));
var y22 = Convert.ToInt32(y0 - 2000 * (a));
Cv2.Line(oriPic, new Point(x11, y11), new Point(x22, y22), Scalar.Lime, 1);
Cv2.Line(invertedMask, new Point(x11, y11), new Point(x22, y22), Scalar.White, 1);
}
var sumx = 0;
var sumy = 0;
foreach (var item in point)
{
Cv2.Circle(src1, Convert.ToInt32(item.X), Convert.ToInt32(item.Y), 3, Scalar.Lime);
sumx += item.X;
sumy += item.Y;
}
var midx = sumx / point.Length;
var midy = sumy / point.Length;
Cv2.Circle(oriPic, Convert.ToInt32(midx), Convert.ToInt32(midy), 3, Scalar.Lime);
Cv2.Circle(invertedMask, Convert.ToInt32(midx), Convert.ToInt32(midy), 2, Scalar.White);
Cv2.ImShow("res", oriPic);
Cv2.ImShow("vline使用bitand +mask", invertedMask);
}
List<LineSegmentPolar> cleanline(LineSegmentPolar[] lines)
{
for (int i = 0; i < lines.Length; i++)
{
if (lines[i].Rho < 0)
{
lines[i].Rho = -lines[i].Rho;
lines[i].Theta = (float)(lines[i].Theta - Cv2.PI);
}
}
List<LineSegmentPolar> listcopy = new List<LineSegmentPolar>();
//listcopy = lines.ToList();
List<LineSegmentPolar> list = new List<LineSegmentPolar>();
list.Add(lines[0]);
for (int i = 1; i < lines.Length; i++)
{
listcopy.Add(lines[i]);
}
foreach (var line in listcopy)
{
string flag = "0";
foreach (var star in list)
{
if (Math.Abs(line.Rho - star.Rho) < 10 && Math.Abs(line.Theta - star.Theta) < 0.1)
{
flag = "1";
}
}
if (flag == "0")
{
list.Add(line);
}
}
return list;
}
List<OpenCvSharp.Point> getPoint(List<LineSegmentPolar> lines)
{
//OpenCvSharp.Point[] points=new Point[] { };
List<Point> points = new List<Point>();
if (lines.Count == 4)
{
List<LineSegmentPolar> horline = new List<LineSegmentPolar>();
List<LineSegmentPolar> verline = new List<LineSegmentPolar>();
foreach (var line in lines)
{
if ((line.Theta > (0 - 0.1)) && line.Theta < (0 + 0.1))
{
horline.Add(line);
}
else
{
verline.Add(line);
}
}
int i = 0;
foreach (var l1 in horline)
{
foreach (var l2 in verline)
{
double[,] a = new double[,] { { Math.Cos(l1.Theta), Math.Sin(l1.Theta) },
{ Math.Cos(l2.Theta), Math.Sin(l2.Theta) } };
double[] b = new double[] { l1.Rho, l2.Rho };
var d = Numpy.np.linalg.solve(a, b);
var d1 = Convert.ToDouble(d.data[0].ToString());
var d2 = Convert.ToDouble(d.data[1].ToString());
Point point = new Point(d1, d2);
points.Add(point);
i++;
}
}
}
return points;
}
更多推荐

所有评论(0)