基于形状匹配原始版放出来(给有用的人参考2)

我们仍然讲学习。

昨天已经把80万像素1024*768的图像变成256*192图像了,并且使用iir高斯平滑保留了特征。

下面做的就是用roi把特征图扣出来,也就是所谓的模板,你在原图中的roi假定是200*200,那么在256*192中,就变成50*50了.要注意,我们昨天调用了一个函数非极大值抑制,实质是canny结果:

   public byte[] 非极大抑制黑中白202210261519(byte[] gaosbuffer, int chang, int gao)//这个buffer已经gaos过了
        {//这个版本非常精彩,自己又一次突破自己202210172008
            int hh = gao;
            int ww = chang;
            double[] 梯度幅值;
            梯度幅值 = new double[ww * hh];
            double[] gy = new double[ww * hh];
            double[] gx = new double[ww * hh];
            double[] 梯度角 = new double[ww * hh];
            byte[] 输出图像 = new byte[ww * hh];
            double maxM = 0;
            for (int i = 1; i < (hh - 1); i++)
            {
                for (int j = 1; j < (ww - 1); j++)
                {
                    int fangbian1 = i * ww + j;

                    // 3,此处改为 sobelx,sobely20220327
                    double Grady = gaosbuffer[fangbian1 - 1 - ww] + 2 * gaosbuffer[fangbian1 - ww] + gaosbuffer[fangbian1 - ww + 1]
                        - gaosbuffer[fangbian1 + ww - 1] - 2 * gaosbuffer[fangbian1 + ww] - gaosbuffer[fangbian1 + ww + 1];

                    double Gradx = gaosbuffer[fangbian1 - ww + 1] + 2 * gaosbuffer[fangbian1 + 1] + gaosbuffer[fangbian1 + ww + 1]
                         - gaosbuffer[fangbian1 - ww - 1] - 2 * gaosbuffer[fangbian1 - 1] - gaosbuffer[fangbian1 + ww - 1];

                    梯度幅值[fangbian1] = Math.Sqrt(Gradx * Gradx + Grady * Grady);
                    if (梯度幅值[fangbian1] > maxM) maxM = 梯度幅值[fangbian1];
                    // 4,这个函数博客里边有jiaoduAndxiangxian
                    梯度角[fangbian1] = jiaoduAndxiangxian(Gradx, Grady) * 180 / Math.PI;//角度,用弧度的话,速度效率高20221018

                    gx[fangbian1] = Gradx;
                    gy[fangbian1] = Grady;
                }
            }

            globmaxM = maxM;
            //5,非极大值抑制

            double g1 = 0, g2 = 0, g3 = 0, g4 = 0;
            double dTmp1 = 0.0, dTmp2 = 0.0;
            double dWeight = 0.0;
            double[] 非极大值抑制后图像 = new double[ww * hh];
            for (int i = 1; i < (ww - 1); i++)
            {
                for (int j = 1; j < (hh - 1); j++)
                {
                    int fangbian = j * ww + i;
                    if (梯度幅值[fangbian] == 0)
                    {
                        非极大值抑制后图像[fangbian] = 0;
                    }
                    else
                    {
                        //材///   
                        ///       g1  g2                  /   
                        ///           C                   /   
                        ///           g4  g3              /   
                        ///   
                        if (((梯度角[fangbian] >= 45) && (梯度角[fangbian] < 90)) ||
                            ((梯度角[fangbian] >= 225) && (梯度角[fangbian] < 270)))//
                        {
                            g1 = 梯度幅值[fangbian - ww - 1];
                            g2 = 梯度幅值[fangbian - ww];
                            g4 = 梯度幅值[fangbian + ww];
                            g3 = 梯度幅值[fangbian + ww + 1];
                            //    if (gy[fangbian] != 0)//为什么这个是多余的?

                            //     {
                            dWeight = Math.Abs(gx[fangbian] / (gy[fangbian])); //  p->Gradx,q->Grady
                            dTmp1 = g1 * dWeight + g2 * (1 - dWeight);
                            dTmp2 = g3 * dWeight + g4 * (1 - dWeight);
                            //       }
                            //      else { }
                        }
                        //材///   
                                      g1                      /   
                        // /       g4  C   g2              /   
                        // /       g3              /   
                        // / 
                        //   else
                        if (((梯度角[fangbian] >= 135) && (梯度角[fangbian] < 180)) ||//shuipingfangxiang
                                ((梯度角[fangbian] >= 315) && (梯度角[fangbian] < 360)))//20220817
                        {   //int nPointIdx = i+j*w;

                            g3 = 梯度幅值[fangbian + ww - 1];
                            g2 = 梯度幅值[fangbian + 1];
                            g1 = 梯度幅值[fangbian - ww + 1];
                            g4 = 梯度幅值[fangbian - 1];
                            //     if (gx[fangbian] != 0)//为什么这个是多余的?
                            //       {
                            dWeight = Math.Abs(gy[fangbian] / (gx[fangbian]));   //  p->Gradx,q->Grady
                            dTmp1 = g1 * dWeight + g2 * (1 - dWeight);
                            dTmp2 = g3 * dWeight + g4 * (1 - dWeight);
                            //    }
                            //  else
                            //    {
                            //先不处理20220817
                            //    }

                        }
                        //   材///   
                         /           g2  g1              /   
                         /           C                   /   
                         /       g3  g4                  /   
                         /   
                        //else 
                        if (((梯度角[fangbian] >= 90) && (梯度角[fangbian] < 135)) ||
                                 ((梯度角[fangbian] >= 270) && (梯度角[fangbian] < 315))) //20220817
                        {  //int nPointIdx = i+j*w;
                            g2 = 梯度幅值[fangbian - ww];
                            g1 = 梯度幅值[fangbian - ww + 1];
                            g4 = 梯度幅值[fangbian + ww];
                            g3 = 梯度幅值[fangbian + ww - 1];
                            //   if (gy[fangbian] != 0)//为什么这个是多余的?

                            //  {
                            dWeight = Math.Abs(gx[fangbian] / (gy[fangbian]));  //  p->Gradx,q->Grady
                            dTmp1 = g1 * dWeight + g2 * (1 - dWeight);
                            dTmp2 = g3 * dWeight + g4 * (1 - dWeight);
                            // }
                            //  else { }
                        }
                        //材///   
                              g3              /   
                              g4  C   g2              /   
                                      g1                      /   
                         
                        //else 

                        if (((梯度角[fangbian] >= 0) && (梯度角[fangbian] < 45)) ||
                      ((梯度角[fangbian] >= 180) && (梯度角[fangbian] < 225)))//这个是45度方向
                        {  //一共四个方向,已经判断了3个方向,这个可以不必判断了
                            g1 = 梯度幅值[fangbian + ww + 1];
                            g2 = 梯度幅值[fangbian + 1];
                            g3 = 梯度幅值[fangbian - ww - 1];
                            g4 = 梯度幅值[fangbian - 1];
                            // if (gx[fangbian] != 0)//为什么这个是多余的?

                            //  {
                            dWeight = Math.Abs(gy[fangbian] / (gx[fangbian]));    //  
                            dTmp1 = g1 * dWeight + g2 * (1 - dWeight);
                            dTmp2 = g3 * dWeight + g4 * (1 - dWeight);
                            // }
                            //   else { }
                        }

                    }
                    if ((梯度幅值[fangbian] > dTmp1) && (梯度幅值[fangbian] > dTmp2))
                    {
                        非极大值抑制后图像[fangbian] = 梯度幅值[fangbian];//非极大值抑制后图像

                    }
                    else
                    {
                        非极大值抑制后图像[fangbian] = 0;

                    }
                }
            }
            for (int i = 0; i < hh; i++)
            {
                for (int j = 0; j < ww; j++)
                {
                    int fangbian = i * ww + j;
                    //if ((非极大值抑制后图像[fangbian] > dThrHigh))//这个值太低,有干扰20221026,启用128
                    //    if ((非极大值抑制后图像[fangbian] > 180))//这个值太低,有干扰20221026,启用128,可能180效果更好,要匹配,有著特征就好
                    if ((非极大值抑制后图像[fangbian] > maxM * 0.618f))//黄金分割了一下
                    {//在精细中,可以尝试0.667,202211041121
                        输出图像[fangbian] = 255;
                        //if (checkBox幅值默认.Checked)
                        //{ TraceEdge(i, j, dThrLow, ref 梯度幅值, ref 输出图像, ww); }
                        //else
                        //{ TraceEdge(i, j, dThrLow, ref 非极大值抑制后图像, ref 输出图像, ww); }

                          TraceEdge(i, j, dThrLow, ref 梯度幅值, ref 输出图像,ww);  //梯度幅值版本20221017第一版本
                         TraceEdge(i, j, dThrLow, ref 非极大值抑制后图像, ref 输出图像, ww);  //第二版本20221018,这两个版本效果都可以
                    }
                }
            }
            //for (int w2b = 0; w2b < hh * ww; w2b++)
            //    输出图像[w2b] = (byte)(255 - 输出图像[w2b]);

            return 输出图像;
        }

你可以看到,我很多值限定死了,这是很有意义的,首先他是尝试过后定下来的,即经验值,另外,不变就很稳定。我们抠出的图像,即学习图像就来自  return 输出图像;

下面就是抠图代码,并且记录了学习到的边(注意和线条要区别,便可以组成线条,但不是线条),也就是我们提炼了canny图像,不要整体,只要特征,这样匹配中数据量就会很小:

   //  showbuffer2pict(globgaospydoutimgN, 128, 96, pictureBox加速gaos);
            //
            pictureBoxroi.Size = new Size(256, 192);
            if (globgaospydoutimgN == null) return;
            //   roi内所有llp
            float top = m_cutImageRoi.m_RoiBase1.rcWin.Top/4f;
            float left = m_cutImageRoi.m_RoiBase1.rcWin.Left/4f;
            //float right = m_cutImageRoi.m_RoiBase1.rcWin.Right;
            //float bottom = m_cutImageRoi.m_RoiBase1.rcWin.Bottom;

            int temproiw = (int)(m_cutImageRoi.m_RoiBase1.rcWin.Width/4f+3);
            int temproih = (int)(m_cutImageRoi.m_RoiBase1.rcWin.Height/4f+3);//si`she*wu*ru`dao*zhi`dejia-san-+3

            int mod = temproiw % 4;//解决四位对齐问题20150716
            temproiw = temproiw + (4 - mod) % 4;
            //  _RoiH = Convert.ToInt32(textBoxH.Text);
            int temproiX = (int)left;
            int temproiY = (int)top;

            byte[] roiImage = new byte[temproiw * temproih];
            //   unsafe
            {
                for (int i = 0; i < temproih; i++)
                    for (int j = 0; j < temproiw; j++)
                    {
                        roiImage[i * temproiw + j] = globgaospydoutimgN[((i + temproiY) * 128 + j + temproiX)];
                    }

            }

            List<List<Point>> llpgaos12896roi = new List<List<Point>>();
            //  llpgaos12896.Clear();
            int ww = temproiw; int hh = temproih;
            // ww = temproiw;  hh = temproih;
            for (int i = 0; i < hh; i++)//****染色算法必须202209091600染色算法也隐含了白底黑斑
            {//所以这里必须反色处理,负责没有结果//202209091606
                roiImage[i * ww + 0] = 0;
                roiImage[i * ww + ww - 1] = 0;
            }
            for (int j = 0; j < ww; j++)
            {
                roiImage[0 * ww + j] = 0;
                roiImage[(hh - 1) * ww + j] = 0;
            }
            染色算法黑中白(ref llpgaos12896roi, ref roiImage, ww, hh);//在边界崩溃了20220831
            if (llpgaos12896roi.Count == 0) return;
            showbuffer2pict(roiImage, ww, hh, pictureBoxroi);//roi内线条被染色为240

            /
            //质心还是要找,可能会用到,llp可以合并在一起用。202210261700
         
            hebingllp.Clear();
            for (int i = 0; i < llpgaos12896roi.Count; i++)
            {
                for (int j = 0; j < llpgaos12896roi[i].Count; j++)
                {
                    hebingllp.Add(llpgaos12896roi[i][j]);//找出x,y中最大,最小,差值加一来确认宽和高202210261709
                }
            }
            //0度匹配
            List<float> arr = new List<float>();

            for (int i = 0; i < hebingllp.Count; i++)
            {
                arr.Add(hebingllp[i].X);
            }
            // 以上四个x,找出最大和最小,画出两条线;
            float min = arr[0]; float max = arr[0];
            for (int i = 0; i < arr.Count; i++)
            {
                if (min > arr[i])
                {
                    min = arr[i];
                }
                if (max < arr[i])
                {
                    max = arr[i];
                }
            }

            arr = new List<float>();
            // 同样四个y,找出最大和最小,画出两条线;
            for (int i = 0; i < hebingllp.Count; i++)
            {
                arr.Add(hebingllp[i].Y);
            }
            float min1 = arr[0]; float max1 = arr[0];
            for (int i = 0; i < arr.Count; i++)
            {
                if (min1 > arr[i])
                {
                    min1 = arr[i];
                }
                if (max1 < arr[i])
                {
                    max1 = arr[i];
                }
            }
              
            匹配www = (int)Math.Abs(max - min);//两个x值
            //匹配www = (int)Math.Abs(max - min)+1;//两个x值
            匹配www = (int)Math.Abs(max - min) + 2 + 1 + 1;//两个x值//202210270838
           匹配qidianX = (int)min - 2;
             
            匹配hhh = (int)Math.Abs(max1 - min1);//两个y值//左顶(min,min1)及右底(max,max1)
            //匹配hhh = (int)Math.Abs(max1 - min1)+1;
            匹配hhh = (int)Math.Abs(max1 - min1) + 2 + 1 + 1;
           匹配qidianY = (int)min1 - 2;//已经改进,可以接受0,0;不能接受-1000//202211040955

           min和min1有都等于0的情形,所以不能赋值为零,为-1来判断吧,0,0值有可能是ok状况,匹配qidianY的条件要放宽
           hebingllp1.Clear();
           for (int t = 0; t < hebingllp.Count; t++)
           {
               hebingllp1.Add(new Point(hebingllp[t].X - 匹配qidianX, hebingllp[t].Y - 匹配qidianY));//这样处理的好处是与匹配www* 匹配hhh一致。202210261924
           }
            //
         
            buttonmatchlearning.Enabled = false;

要注意的是,我们找了特征的最小外接矩形,显然他比抠图的roi要小,这也是为匹配减少数据量,匹配中,就用这个矩形,遍历整个256*192图像。

其实,roi矩形也是可以的,矩形大,搜索次数减少,矩形小,搜索次数多,你要衡量一下,我这里没用roi矩形。

学习就算完了,下面讲匹配,待续。。。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/872522.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

怎样在 PostgreSQL 中优化对复合索引的选择性?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01;&#x1f4da;领书&#xff1a;PostgreSQL 入门到精通.pdf 文章目录 怎样在 PostgreSQL 中优化对复合索引的选择性一、理解复合索引的概念二、选择性的重要性三、优化复合索…

ollama编译安装@focal jammy Ubuntu @FreeBSD jail

Ollama是一个用于在本地运行大型语言模型&#xff08;LLM&#xff09;的开源框架。它支持多种操作系统&#xff0c;但是唯独不支持FreeBSD&#xff0c;于是尝试在FreeBSD的jail里安装Ubuntu&#xff0c;Ubuntu里再安装ollama。 先上结论&#xff0c;好像focal jail无法编译成功…

shell脚本-linux如何在脚本中远程到一台linux机器并执行命令

需求&#xff1a;我们需要从11.0.1.17远程到11.0.1.16上执行命令 实现&#xff1a; 1.让11.0.1.17 可以免密登录到11.0.1.16 [rootlocalhost ~]# ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): Created d…

【问题记录】Docker配置mongodb副本集实现数据流实时获取

配置mongodb副本集实现数据流实时获取 前言操作步骤1. docker拉取mongodb镜像2. 连接mongo1镜像的mongosh3. 在mongosh中初始化副本集 注意点 前言 由于想用nodejs实现实时获取Mongodb数据流&#xff0c;但是报错显示需要有副本集的mongodb才能实现实时获取信息流&#xff0c;…

扫地机器人如何解决室内空气污染问题

扫地机器人解决室内空气污染问题主要通过以下几个方面来实现&#xff1a; 一、高效清洁减少地面污染源 ① 地面清扫能力&#xff1a;扫地机器人能够自动或手动控制进行地面清扫&#xff0c;有效清除地面上的各种污渍、灰尘和毛发等污染物。这些污染物是室内空气中的重要污染源…

27.js实现鼠标拖拽

e.offsetX是鼠标距离准确事件源的左上角距离 e.clientX是鼠标距离浏览器可视窗口左上角的距离 e.pageX是鼠标距离文档左上角的距离 /* 当鼠标点击div时开始挪动&#xff0c;当鼠标抬起&#xff0c;div静止——事件源是div 当鼠标点击后,鼠标在移动——事件源…

java 前端上传文件后端解析并转发到第三方存储,Hutool 工具

单个文件上传 PostMapping("/upload")public MyResponse<?> upload(MultipartFile file) {if (multipartFiles null || multipartFiles.length 0) {throw new MessageException("未选择文件");}InputStreamResource inputStreamResource new Inp…

通过命令行工作流提升工作效率的实战教程(持续更新)

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…

从三个方向来谈谈开源项目有哪些机遇与挑战

开源项目有哪些机遇与挑战&#xff1f; 随着全球经济和科技环境的快速变化&#xff0c;开源软件项目的蓬勃发展成为了开发者社区的热门话题。越来越多的开发者和企业选择参与开源项目&#xff0c;以推动技术创新和实现协作共赢。你如何看待当前开源项目的发展趋势&#xff1f;…

SpringCache介绍

SpringCache是Spring提供的缓存框架。提供了基于注解的缓存功能。 SpringCache提供了一层抽象&#xff0c;底层可以切换不同的缓存实现&#xff08;只需要导入不同的Jar包即可&#xff09;&#xff0c;如EHCache&#xff0c;Caffeine&#xff0c;Redis。 2个重要依赖已经导入&a…

Vue 3中常用的生命周期钩子和监听器的详细分析

目录 前言1. onMounted2. watch3. computed4. 其他 前言 分析常用的一些生命周期钩子和监听器可以帮助我们在组件中处理数据加载、状态变化和响应式更新 1. onMounted 生命周期钩子&#xff0c;在组件挂载后执行。它适合用于初始化数据加载或执行一次性的操作 <template…

简单一阶滤波器设计:matlab和C实现

一、简单一阶滤波器的模型 二、示例 得: y(n)-0.9y(n-1)=x(n)+0.05x(n-1),即:y(n)=0.9y(n-1)+x(n)+0.05x(n-1) 已知:,并且有: A. 假设输入序列有N=100个点 B. 系统初始状态为0,即y(-1)=0 C. 输入序列是因果序列,

分析AI是在帮助开发者还是取代他们

AI在软件开发中起到了辅助作用&#xff0c;帮助开发者提高生产效率和质量。它可以通过代码生成、错误检测和自动化测试等功能&#xff0c;加速开发流程&#xff0c;减少人为错误并改善软件质量。AI工具可以解放开发者的时间和精力&#xff0c;让他们可以更专注于解决复杂问题和…

【OpenRecall】超越 Windows Recall,OpenRecall 为你的隐私和自由而战

引言 随着 Windows 11 的 Recall 功能推出&#xff0c;我们看到了数字记忆回顾的全新可能性。然而&#xff0c;这项功能受限于特定的硬件——Copilot 认证的 Windows 硬件&#xff0c;并且仅在 Windows 平台上可用。对于追求隐私和硬件灵活性的用户来说&#xff0c;这无疑是个…

长按加速- 解决react - setInterval下无法更新问题

最开始直接setInterval里&#xff0c;useState硬写&#xff0c;发现更新不&#xff0c;固定值 换let&#xff0c;发现dom更新不了 正确做法是用ref 并且pc端可以长按的&#xff0c;只是要用onTouchStart&#xff0c;不要用onMouseDown onTouchStart{handleMouseDown} onTou…

在设计电气系统时,电气工程师需要考虑哪些关键因素?

在设计电气系统时&#xff0c;电气工程师需要考虑多个关键因素&#xff0c;以确保系统的安全性、可靠性、效率和经济性。我收集归类了一份plc学习包&#xff0c;对于新手而言简直不要太棒&#xff0c;里面包括了新手各个时期的学习方向编程教学、问题视频讲解、毕设800套和语言…

SEO优化文章写作技巧:如何快速写出高排名高质量内容

不知道有多少人跟我一样&#xff0c;并没有接受过专业的seo优化培训&#xff0c;所学seo优化技巧全部都是通过百度查阅文章所得。 在搜索的有关seo优化相关内容里面&#xff0c;基本上都说到&#xff0c;原创优质内容、优质外链、优质友情链接、优质的内链这几个方面&#xff…

如何查看极狐GitLab Helm Chart?

GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab &#xff1a;https://gitlab.cn/install?channelcontent&utm_sourcecsdn 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署…

word 设置多级混合标题自动更新

目录预览 一、问题描述二、原因分析三、解决方案四、参考链接 一、问题描述 有没有体会过多级标题&#xff0c;怎么设置都不听使唤的情况&#xff1f; 我想要的格式是&#xff1a; 二、原因分析 多级标题中发现&#xff0c;输入编号格式这里有个数字没有底纹,是了&#xff0…

系统架构设计师教程 第3章 信息系统基础知识-3.1 信息系统概述

系统架构设计师教程 第3章 信息系统基础知识-3.1 信息系统概述 3.1.1 信息系统的定义3.1.1.1 信息系统3.1.1.2 信息化3.1.2 信息系统的发展3.1.2.1 初始阶段3.1.2.2 传播阶段3.1.2.3 控制阶段3.1.2.4 集成阶段3.1.2.5 数据管理阶段3.1.2.6 成熟阶段3.1.3 信息系统的分类3.…