前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【点云学习】 源代码和关键功能介绍

【点云学习】 源代码和关键功能介绍

作者头像
EdenChen
发布2020-04-14 15:55:45
5520
发布2020-04-14 15:55:45
举报
文章被收录于专栏:ROBOTEDUROBOTEDU

导览

源代码和关键功能代码介绍

  1. 工程源代码下载
  2. 图像坐标系转换
  3. UI设计代码

01

工程和源代码下载

https://pan.baidu.com/s/1XaKFZLudnnISui7lV8540A

提取码:5ytm

现已经支持的点格式:.asc/.csv/.xyz

02

图像坐标系转化

窗口的交互设计都是基于C#中的PictureBox的坐标系

图像原点与图像框坐标原点

我们基于鼠标事件得到坐标都是基于图像框坐标系的,我们的点云坐标是与图像坐标对应的,因此需要将图像框的坐标转换到图片的坐标。

一般经过两次变化:平移+缩放

平移

缩放

代码语言:javascript
复制
        private Point TransImageToPicbox(Point e)
        {
            try
            {
                //取得当前图像在图片框中的位置和长宽
                rectangle_curr = (Rectangle)pictureBox1.GetType().GetProperty("ImageRectangle", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(pictureBox1, null);
                int currentWidth = rectangle_curr.Width;
                int currentHeight = rectangle_curr.Height;
                //计算缩放系数
                double rate_h = (double)currentHeight / (double)pictureBox1.Image.Height; double rate_w = (double)currentWidth / (double)pictureBox1.Image.Width;
                //计算XY偏移
                int black_left_width = (currentWidth == this.pictureBox1.Width) ? 0 : (this.pictureBox1.Width - currentWidth) / 2;
                int black_top_height = (currentHeight == this.pictureBox1.Height) ? 0 : (this.pictureBox1.Height - currentHeight) / 2;
                int zoom_x = e.X - black_left_width;
                int zoom_y = e.Y - black_top_height;
                double original_x = (double)zoom_x / rate_w;
                double original_y = (double)zoom_y / rate_h;
                //如果鼠标落在图片区域外则返回原点坐标
                if (e.X < black_left_width || e.X >= currentWidth + rectangle_curr.Location.X)
                {
                    return new Point(0, 0);
                }
                if (e.Y < black_top_height || e.Y >= currentHeight + rectangle_curr.Location.Y)
                {
                    return new Point(0, 0);
                }
                //返回实际图像坐标
                return new Point((int)original_x, (int)original_y);
            }
            catch (Exception)
            {
                return new Point(0, 0);
            }
        }

02

交互代码

通过鼠标拉线获取线上所有点云数据

1.设置鼠标事件 2.

代码语言:javascript
复制
        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
//鼠标按下时,记录开始点坐标
          StrPoint_pic = e.Location;
//转换坐标系到图像          
          StrPoint = TransImageToPicbox(e.Location);
          break;
        }                        

3.

代码语言:javascript
复制
        private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {
//鼠标松开记录结束点坐标        
        bitmap = (Bitmap)pictureBox1.Image;
        Graphics graphics = Graphics.FromImage(this.bitmap);
        EndPoint_pic = e.Location;
//转换坐标系到图像        
        EndPoint = TransImageToPicbox(new Point(EndPoint_pic.X, StrPoint_pic.Y));
        double[] data = new double[Get_Point_line(StrPoint, EndPoint).Count]; int count = 0;
        foreach (Point3 item in Get_Point_line(StrPoint, EndPoint))
        {
             data[count] = item.Z; count++;
        }
        FileOpt.data_buffer = data.ToList();
        chart.chart1.ChartAreas[0].AxisY.Maximum = data.Max() + 10; chart.chart1.ChartAreas[0].AxisY.Minimum = data.Min() - 10;
        chart.chart1.Series[0].IsValueShownAsLabel = false;
        chart.chart1.Series[0].Points.DataBindY(data);
//将两点的连线画在图像上        
        graphics.DrawLine(new Pen(Color.Red, 3), StrPoint, EndPoint);
        pictureBox1.Image = bitmap;
        break;
}                 

4.计算线的图像坐标系方程

5.

代码语言:javascript
复制
        private List<Point3> Get_Point_line(Point str,Point end)
        {
            //声明直线方程的k和b,声明一个存放线上点云数据的表
            float k;float b;List<Point3> point_list1 = new List<Point3>();
            try
            {
                
                Point3 point3 = new Point3();
                k = (float)(end.Y - str.Y) /(float)(end.X - str.X);
                b = str.Y - k * (float)str.X;
                //k存在,k>1或者0>k>-1
                if (k>1||((k<0)&&(k<-1)))
                {
                    for (int i = Math.Min(str.Y, end.Y); i < Math.Max(str.Y, end.Y); i++)
                    {
                        point3.Y = i; point3.X = (int)((i-b)/k); point3.Z = FileOpt.datamat_buffer[point3.X, point3.Y];
                        point_list1.Add(point3);
                    }
                    point_list = point_list1;
                }
                //k存在,k<1或者k<-1
                else

                {
                    for (int i = Math.Min(str.X, end.X); i < Math.Max(str.X, end.X); i++)
                    {
                        point3.X = i; point3.Y = (int)(k * (float)i + b); point3.Z = FileOpt.datamat_buffer[point3.X, point3.Y];
                        point_list1.Add(point3);
                    }
                    point_list = point_list1;
                }
                return point_list1;
            }
            catch (Exception)
            {
                //k不存在,此时线属于铅垂线
                Point3 point3 = new Point3();
                for (int i = Math.Min(str.Y, end.Y); i < Math.Max(str.Y, end.Y); i++)
                {
                    point3.X = str.X; point3.Y = i; point3.Z = FileOpt.datamat_buffer[point3.X, point3.Y];
                    point_list1.Add(point3);
                }
                point_list = point_list1;
                return point_list1;
                throw;
            }
        }

小结

1. 坐标系变化

2. 交互设计

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-04-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 ROBOTEDU 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档