• Learning opencv续不足(七)线图像的设计D


    因为线图像startline有了起点和终点,我们就可以用DDA法求出线上所有点,任意斜率直线通过四象限八区域查表法界定。我们只示范一个区域:函数为: public PointF DdaFindPtImprove(ref byte[] buffer8, PointF Start, PointF End, int thresDelta, int Dir,Size wh,ref int Pos)//thresDelta门槛值,Pos线图像中穿越点index

     {         float x, y;
                float dx, dy, k;
                PointF backPoint = new PointF();

                dx = (float)(End.X - Start.X);
                dy = (float)(End.Y - Start.Y);
                k = dy / dx;
                if (Math.Abs(dx) < 0.001)
                {
                    k = 65535;//随意给定一个最大值,还需论证。20150727,够用
                }
                x = Start.X;
                if (Start.Y < 0) Start.Y = 0;
                y = Start.Y;

                List<float> temparrclor = new List<float>(); // 线图像上每一个点灰度颜色   
                List<PointF> position = new List<PointF>();//线图像上每一个点坐标
                #region xiaoyu1
                if (Math.Abs(k) < 1)
                {
                    if (x > End.X)
                    {
                        for (; x >= End.X; x--)//x是整型,y是浮点型
                        {
                            float j = y;
                            int i = (int)(x);
                            float tempf = Math.Abs(j - (int)j);
                            PointF tempPt = new PointF(i, j);
                            float grey = 0;
                            if (k > -1 && k <= 0)
                            {
                                float avgGrey = (float)buffer8[(int)j * wh.Width + i];
                                float avgGrey1 = (float)buffer8[((int)j + 1) * wh.Width + i];
                                grey = avgGrey * (1 - tempf) + avgGrey1 * tempf;//灰度插值方法
                            }
                            else
                            {
                                float avgGrey = (float)buffer8[(int)j * wh.Width + i];
                                float avgGrey1 = (float)buffer8[((int)j - 1) * wh.Width + i];
                                grey = avgGrey * (1 - tempf) + avgGrey1 * tempf;
                            }
                            temparrclor.Add(grey);//插值灰度
                            position.Add(tempPt);

                            y = y - k;
                        }                                              
                        backPoint = FindCrosspointimprove(ref temparrclor, ref position, Dir, thresDelta,ref Pos);//找穿越点
                    }
                    else {.......}

              }

     #endregion xiaoyu1

    ........  return backPoint;}

      public PointF FindCrosspointimprove(ref List<float> lineTiDu, ref List<PointF> ijRecord, int Dir, int thresDelta,ref int POS)
            {//梯度和求穿越点,使用五个一组,与所讲略有差别
                List<float> deltatemp = new List<float>();
                List<float> fenzuaverage = new List<float>();
                for (int i = 0; i < lineTiDu.Count - 1; i++)
                {
                    float grey1 = lineTiDu[i + 1];               
                    float delta = (lineTiDu[i] - grey1);
                    if (Math.Abs(delta) < 5)
                        delta = 0;
                    deltatemp.Add(delta);
                }

                int fenzuC = deltatemp.Count / 5;
                for (int i = 0; i < fenzuC * 5; i = i + 5)
                {
                    float sum5 = deltatemp[i] + deltatemp[i + 1] + deltatemp[i + 2] + deltatemp[i + 3] + deltatemp[i + 4];
                    float aver = sum5 / 5;
                    if (Math.Abs(aver) < 5)
                        aver = 0;
                    fenzuaverage.Add(aver);
                }
                if (fenzuaverage.Count == 0) return new PointF();
                int crosspoint = 0;
                int crosspoint1 = 0;
                if (Dir == 0)
                {

                    for (int iii = fenzuaverage.Count - 1; iii >= 0; iii--)//排除起点和终点
                    {
                        if (fenzuaverage[iii] > 0)
                        {
                            crosspoint = 5 * (iii);
                            break;
                        }
                    }
                 float   maxVar = deltatemp[crosspoint];
                    for (int m = -5; m < 5; m++)
                    {
                        int tempint = crosspoint + m;
                        if (crosspoint == 0)
                            tempint = 0;
                        if (deltatemp[tempint] >= maxVar)//白到黑,加入方向判别
                        {
                            maxVar = deltatemp[tempint];
                            crosspoint1 = tempint;
                        }
                    }
                   
                }
                if (Dir == 1)
                {

                    for (int iii =0 ; iii <= fenzuaverage.Count - 1; iii++)//排除起点和终点
                    {
                        if (fenzuaverage[iii] < 0)
                        {
                            crosspoint = 5 * (iii);
                            break;
                        }
                    }
                   // minVar = deltatemp[crosspoint];
                    float minVar = deltatemp[crosspoint];
                    for (int m = -5; m < 5; m++)
                    {
                        int tempint = crosspoint + m;
                        if (crosspoint == 0)
                            tempint = 0;
                        if (deltatemp[tempint] <= minVar)//白到黑,加入方向判别
                        {
                            minVar = deltatemp[tempint];
                            crosspoint1 = tempint;
                        }
                    }

                }
                if (fenzuaverage[crosspoint / 5] * 5 >= thresDelta || fenzuaverage[crosspoint / 5] * 5 <= -thresDelta)
                {
                    POS = crosspoint1;//穿越点的index在线图像序列中
                    return ijRecord[crosspoint1];//穿越点的index对应坐标
                }//门槛判别
                else
                {
                    return new PointF();//没有穿越点,返回(0,0)
                }
            }

    一切准备就绪,在private void pictureBoxRoiImg_Paint(object sender, PaintEventArgs e)调用

     if (m_btempImage3 == true)//截取的ROI图像
                        {
                            PointF startxy = m_线图像.m_RoiBase.startLine.pt_start;
                            PointF endxy = m_线图像.m_RoiBase.startLine.pt_end;               
                       PointF     returnpoint = DdaFindPtImprove(ref tempImage3, startxy,
                                                endxy, 门槛值, glob_Dir, new Size(_RoiW, _RoiH), ref pos);
                            p = new Pen(Color.Red, 1);//画出穿越点叉叉
                            g.DrawLine(p, new PointF(returnpoint.X, returnpoint.Y - 3), new PointF(returnpoint.X, returnpoint.Y + 3));
                            g.DrawLine(p, new PointF(returnpoint.X - 3, returnpoint.Y), new PointF(returnpoint.X + 3, returnpoint.Y));              
                        }

    到此,线图像设计完成。下一节讲一组线图像组成找线工具。(待续..............)以下是运行后线图像工具效果:
    --------------------- 

  • 相关阅读:
    button 样式 GIS
    将一个json格式的字符串转换为一个实体对象
    统一将数据库中的数据类型转换为另外一种
    Redis学习16两种主从复制的模式
    阿里云服务器reboot后,用Xshell连接不上的解决办法
    Redis学习主从复制,搭建集群
    Redis学习15 发布订阅
    ASP.NET Eval多参数绑定
    面试时如何说辞职理由(转)
    (转)简单的js弹出窗口效果
  • 原文地址:https://www.cnblogs.com/ly570/p/11026686.html
Copyright © 2020-2023  润新知