一步一步实现自己机器视觉Megauging中工具的制作和运作(简单示范,抓矩形工具功能实现,三)

我们需要双击工具组(toolgroup)项toolitemRect,产生一个form,当有图像传入,我们可以操作去找矩形,这个form如下,分两部分,通用部分针对性(截取感兴趣roi图像)部分(这里针对自然是gaugerect),其实我们大部分工具都是这样设计的。

通用部分,前面博客已经出现,代码可参考:

a,Learning opencv续不足(二)感兴趣区域图像截取

b,神奇的东东在一个界面快速组织起来工作(一)

public partial class ImageSourceForm : Form{...............................}

c,坐标系工具的设计

我们这一节关键是,demo抓矩形工具的实现(很显然,我们的工具都在roi截取的图像中出现,对比抓线工具)

通过对比,可以看到,感兴趣区域截取图像的那个框框和我们的抓取矩形工具的框框神似,不仅如此,我们前面两节中的工具盒框框和工具组项框框的设计也是如此。需要强调的是,这四个框框中,只有抓取矩形的框框有旋转功能,其他三个框框没有此功能,思考为什么?

所以他们都来自ROIsimple,因为旋转,我们有新增,故改变为ROIsimple2(思考,能否不改变,我们继续派生?重用重载,像上一节的IsPointInRect函数,和我以前的c++程序对比,这里的派生弱爆了,在c#下太重实现了!),看一看几处不同:

第一处不同:  public class ROIsimple2
    {
        public RoiBase m_RoiBase1;

第二处不同:

  public void DrawRectFrame(bool lbtn, PointF point)
        {
            if (lbtn)
            {
                switch (m_eHandle)
                {
                    case E_HANDLES.E_HANDLE_INSIDE:
                        m_RoiBase1.Drag(point);
                        break;

                    case E_HANDLES.E_HANDLE_SOUTH:
                        m_RoiBase1.DragTolerancey(point)
;//这个改变矩形的宽度
                        break;
                    case E_HANDLES.E_HANDLE_EAST:
                        m_RoiBase1.DragXYandRotate(point)
;//这个矩形可以旋转,改变长宽
                        break;
                    default:
                        break;

以上有两处不同,具体函数代码实现,他们也在前面的博客中出现了。具体代码请参考:

a,感兴趣线图像设计

b,感兴趣找线工具设计

抓矩形工具的形体已成,只差感知能力了,我们以前都是使用线图像感知穿越点,这里明显不同,使用梯度和,进行角点感知

代码如下:

   private void pictureBoxRoiImg_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            Pen p = new Pen(Color.Green, 1);//rectgauge形体添加完毕,202006010721,开始 添加感知能力,参考标定roi

            g.DrawLine(new Pen(Color.Blue), new Point(0, pictureBoxRoiImg.Height / 2), new Point(pictureBoxRoiImg.Width, pictureBoxRoiImg.Height / 2));
            g.DrawLine(new Pen(Color.Blue), new Point(pictureBoxRoiImg.Width / 2, 0), new Point(pictureBoxRoiImg.Width / 2, pictureBoxRoiImg.Height));//画中心十字
                     
            m_gaugeRect.m_RoiBase1.Draw(g, p);//画rectgauge形体

            if (tempImage3 != null)
            {
                int w = pictureBoxRoiImg.Image.Width;
                PointF[] tempcorner = new PointF[4];//20200601矩形只有四个角点
              //通过矩形的四个角找亚像素,那么是圆角矩形怎么ban?20200601             
                    mg_line templine1= m_gaugeRect.m_RoiBase1.startLine;
                    mg_line templine2 = m_gaugeRect.m_RoiBase1.lastline;
                     PointF[] first = new PointF[4];
                     first[0] = templine1.pt_start;
                     first[1] = templine1.pt_end;
                     first[2] = templine2.pt_start;
                     first[3] = templine2.pt_end;
                     int thres = Convert.ToInt32(textBoxthres.Text);
                for(int j=0;j<4;j++)
                    try
                    {
                        int 梯度和 = 0;//202006010804将使用16*16窗口
                        tempcorner[j] = glob_subcorner((int)(first[j].X - 8), (int)(first[j].Y - 8), 16, 16, w, tempImage3, ref 梯度和);

//新版本有关亚像素梯度和202005151029
                        if (梯度和 > thres)
                        {                           
                            p = new Pen(Color.Red, 1);                          
                            g.DrawLine(p, new PointF(tempcorner[j].X, tempcorner[j].Y - 3), new PointF(tempcorner[j].X, tempcorner[j].Y + 3));
                            g.DrawLine(p, new PointF(tempcorner[j].X - 3, tempcorner[j].Y), new PointF(tempcorner[j].X + 3, tempcorner[j].Y));
                            if (checkBox3.Checked == false)
                            {
                                float a = (float)(tempcorner[j].X);
                                float b = (float)(tempcorner[j].Y);//显示梯度和及亚像素角点坐标
                                g.DrawString(梯度和.ToString() + "\r\n" + (a).ToString() + "," +
                                    (b).ToString(), new Font("Arial", 9), Brushes.Red, tempcorner[j]);
                            }
                        }
                    }
                    catch (Exception ee) { }                              
            }
        }

这个函数   glob_subcorner是否在哪里见过(对比harris角点之亚像素角点最小二乘法实现一节tysubcorners1per8函数)?

    private PointF glob_subcorner(int left, int top, int w, int h, int picW, byte[] orgbyte, ref int tiduhe)//新版本有关亚像素梯度和202005151029
        {
            double D, A, B, E, F, G, H; A = B = D = E = F = G = H = 0;
            double _D, _A, _B; _A = _B = _D = 0;
            for (int i = 0; i < h; i++)
                for (int j = 0; j < w; j++)
                {                   
                    int xdaoshu = orgbyte[(top + i) * picW + left + j + 1] - orgbyte[(top + i) * picW + left + j];//无需考虑边界
                    int ydaoshu = orgbyte[(i + top) * picW + j + left + picW] - orgbyte[(top + i) * picW + left + j];
                    double TiDuvalue = Math.Sqrt(xdaoshu * xdaoshu + ydaoshu * ydaoshu);
                    tiduhe += Math.Abs(xdaoshu) + Math.Abs(ydaoshu);
                    float MVX = (float)(TiDuvalue * Math.Cos(jiaoduAndxiangxian(xdaoshu, ydaoshu)));//梯度向量X
                    float MVY = (float)(TiDuvalue * Math.Sin(jiaoduAndxiangxian(xdaoshu, ydaoshu)));//梯度向量Y
                    _A += (MVX) * (MVX);
                    _B += (MVX) * (MVY);
                    _D += (MVY) * (MVY);
                    E += (MVX) * (MVX) * (left + j);//x
                    F += (MVX) * (MVY) * (top + i);//y
                    G += (MVX) * (MVY) * (left + j);//x
                    H += (MVY) * (MVY) * (top + i);//y
                }
            double result = _A * _D - _B * _B;
            A = _D / (result * 1.0); B = -_B / (result * 1.0); D = _A / (result * 1.0);
            double x = A * (E + F) + B * (G + H);
            double y = B * (E + F) + D * (G + H);
            return new PointF((float)(x), (float)(y));
        }

gaugerectform搞定,未完,待续......

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值