代码
绘制
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog openFile = new OpenFileDialog();
//GetType().Assembly.Location:获取当前进程的完整路径,包含文件名。
openFile.InitialDirectory = Path.Combine(Path.GetDirectoryName(GetType().Assembly.Location), "Images");
openFile.Filter = "All|*.*";
if (openFile.ShowDialog() == DialogResult.OK)
{
Img = Cv2.ImRead(openFile.FileName);
}
//首先裁剪图片右下角那块 输出为img2
//x=0在图片最左边 y=0在最上面 取的是矩形的左上顶点
int kuan = Img.Width / 2;
int gao=Img.Height /2 ;
//gao= 720;
MessageBox.Show(Img.Height.ToString());
Rect rect = new Rect();
rect.X = kuan-180;
rect.Width = kuan+50;
rect.Y =gao-180;
rect.Height = gao+180;
Mat img2= new Mat(Img,rect);
Cv2.ImShow("裁剪", img2);
//处理
myFind_chessboard(img2);
//chart上画图
drawLine();
}
棋盘格处理
核心就是调用Cv2.FindChessboardCorners(Img, a, out corners);直接将内角点找出来就行了,直接输出的是一排(x,y),将其转化为二维矩阵更好用一些。然后将其减来减去,就得到了畸变值。
Mat Img;
List<double> ww = new List<double>();
List<double> hh = new List<double>();
public static int xP = 0;
public static int yP = 0;
public static int hxP = xP / 2;//直接这样除是不行的 输出为0
public static int hyP = yP / 2;
void myFind_chessboard(Mat Img)
{
xP = int.Parse(textBox1.Text);//x和y方向的总点数
yP = int.Parse(textBox2.Text);
hxP = xP / 2;//需要在这里除 9/2=4
hyP = yP / 2;
//在Img中找内角点
Point2f[] corners;
Size a = new OpenCvSharp.Size(hxP, hyP);//第一个宽 第二个高
bool isFound = Cv2.FindChessboardCorners(Img, a, out corners);
MessageBox.Show("是否找出:" + isFound);
//复制一张img 为img3 在img3上将内角点画出来
Mat img2 = new Mat();
Img.CopyTo(img2);
//我觉得corners应该是一排的(x,y)
Cv2.DrawChessboardCorners(img2, a, corners, isFound);
Cv2.ImShow("img2", img2);
if (isFound)
{
//Corners2:将找到的corners按照一排多少个,矩阵这样的格式进行排列
Point2f[,] Corners2 = new Point2f[hxP, hyP];
Corners2 = OneD_2<Point2f>(corners, hyP);
for(int i = 0;i < hxP -1; i++)//列
{
for(int j = 0;j< hyP -1; j++)//行
{
double detaX = 0;
double detaY = 0;
Point centerY = new Point();
Point centerX = new Point();
detaX = Corners2[j, i + 1].X - Corners2[j, i].X;
detaY = Corners2[j + 1, i].Y - Corners2[j, i].Y;
centerX = center((Point)Corners2[j, i], (Point)Corners2[j, i + 1]);
centerY = center((Point)Corners2[j, i], (Point)Corners2[j + 1, i]);
//Cv2.PutText(Img, detaX.ToString("0.000"), (OpenCvSharp.Point)Corners2[j, i], HersheyFonts.HersheySimplex, 0.5, Scalar.Red, 2, LineTypes.Link4);
//应该是中间向边上畸变值不断减少
Cv2.PutText(Img, detaX.ToString("0.000"), centerX, HersheyFonts.HersheySimplex, 0.5, Scalar.Red, 2, LineTypes.Link4);
Cv2.PutText(Img, detaY.ToString("n4"), centerY, HersheyFonts.HersheySimplex, 0.5, Scalar.Red, 2, LineTypes.Link4);
if (i == 1)//第一列 也就是y轴上的那么几个
hh.Add(detaY * 0.00175 / 3.0);
if (j == 1)//第一行 也就是x轴上的那么几个
ww.Add(detaX * 0.00175 / 3.0);
Cv2.Circle(Img, (OpenCvSharp.Point)Corners2[j,i], 5, Scalar.Red, -1, LineTypes.Link8);
}
}
Cv2.ImShow("img", Img);
Cv2.WaitKey(0);
}
}
/// <summary>
/// 取中心点
/// </summary>
/// <param name="p1"></param>
/// <param name="p2"></param>
/// <returns></returns>
public Point center(Point p1, Point p2)
{
return new Point((p1.X + p2.X) / 2, (p1.Y + p2.Y) / 2);
}
/// <summary>
/// 一维数组转2维数组(矩阵)
/// </summary>
/// <param name="obj"></param>
/// <param name="len">矩阵行数</param>
/// <returns></returns>
public static T[,] OneD_2<T>(T[] obj, int len)
{
if (obj.Length % len != 0)
return null;//这样就是无法做一个矩阵
int width = obj.Length / len;
T[,] obj2 = new T[len, width];
for (int i = 0; i < obj.Length; i++)
{
obj2[i / width, i % width] = obj[i];
}
return obj2;
}
画图
核心就是 chart1.Series[0].Points.AddXY(i + 1, ww[i]);添加点,其他信息都直接设置好了
private void drawLine()
{
chart1.Visible = true;//在没有显示值之前先隐藏
int min = Math.Min(hh.Count, ww.Count);
//输入数据
for (int i = 0; i < min; i++)
{
chart1.Series[0].Points.AddXY(i + 1, ww[i]);
chart1.Series[1].Points.AddXY(i + 1, hh[i]);
}
ww.Clear();
hh.Clear();
}
实验现象