opencv 学习(5)拐点的查找 您所在的位置:网站首页 凹拐点凸拐点 opencv 学习(5)拐点的查找

opencv 学习(5)拐点的查找

2023-09-04 08:17| 来源: 网络整理| 查看: 265

  引言

  图像处理过程中,拐点是重要的特征点之一。进行图像的分析时,拐点是一重要的研究方向。

拐点的形象解释:拐点,又称反曲点,在数学上指改变曲线向上或向下方向的点,直观地说拐点是使切线穿越曲线的点(即曲线的凹凸分界点)。若该曲线图形的函数在拐点有二阶导数,则二阶导数在拐点处异号(由正变负或由负变正)或不存在。

拐点的定义:若曲线图形在一点由凸转凹,或由凹转凸,则称此点为拐点。直观地说,拐点是使切线穿越曲线的点。若该曲线图形的函数在某点的二阶导数为零或不存在,且二阶导数在该点两侧符号相反,该点即为函数的拐点。这是寻找拐点时最实用的方法之一。

知道了拐点的定义,下面我们来讨论实际中如何获取拐点:

 从图中我们可以清晰的看出拐点的位置。然而在实际的操作当中,我们获取拐点并不是很容易。或者说,我们让计算机获取拐点是需要我们给计算机一个处理方式的。在此处,我所介绍的方法,仅仅只是一些简单的拐点。我的方式是取点求趋势得拐点。

具体做法:(默认可得轮廓点)

  得到轮廓点之后,我以区间的形式取点,即以一个固定长度取点求其平均值,用这个区间的平均值点来代表整个区间。用取得的平均值点来求当前线段或者弧段的趋势,当趋势改变剧烈时便是一条线段或弧段取完所有可用点的时候。这个时候我们使用线性方程来描述这个趋势即{y=kx+b|x,y->D},我们求其k,b,这样我们便得到了一个线性趋势方程。同理,我们可以得到所有的线性趋势方程。(在这里使用线性的原因仅仅因为趋势没有复杂的变化,并且线性的描述要简单一些)                                      现在我们找到两个趋势方程便可以找到拐点。

y=Kx+B,y=kx+b      取交点(x,y)=((b-B)/(K-k),Kx+B)或x,y)=((b-B)/(K-k),kx+b).取交点,在从轮廓中找到离交点最近的点。这样我们便完成了拐点的寻找。

效果

 

 

 

代码:

/******************************************************************** ** 文 件 名:拐点查找(主要内容) ** 创 建 人:yk ** 最后修改时间:2018年11月22日 *********************************************************************/ struct K_and_point { long double K = 0; long double X = 0; long double Y = 0; long double B = 0; }; bool Bigorsmall(double numberone,double numbertwo) { return numberone >= numbertwo ? true : false; } double point_x[100] = { 0 }, point_y[100] = {0}, dateSum_x=0, dateSum_y = 0; int datelen = 0, Recordlen = 0,Switch=0, trend_x=0,trend_y=0,Trend_Switch=0,linelenth=0; for (int i = 0; i < a.contours.size(); i++) { for (int j = 0; j < a.contours[i].size(); j++) { if (j == 0) { again: point_x[datelen] = a.contours[i][j].x; point_y[datelen] = a.contours[i][j].y; datelen++; } dateSum_x += (double)a.contours[i][j].x / (double)Collectionlength; dateSum_y += (double)a.contours[i][j].y / (double)Collectionlength; Recordlen++; if (Recordlen == Collectionlength) { Recordlen = 0; if (Bigorsmall(dateSum_x, point_x[datelen - 1])) { trend_x = 2; } else { trend_x = 1; } if (Bigorsmall(dateSum_y, point_y[datelen - 1])) { trend_y = 4; } else { trend_y = 3; } Trend_Switch = trend_x + trend_y; if((Switch==0)||(Switch==Trend_Switch)) { Switch = Trend_Switch; point_x[datelen] = dateSum_x; point_y[datelen] = dateSum_y; dateSum_x = 0; dateSum_y = 0; datelen++; } else { for (int i = 0; i < datelen; i++) { b[linelenth].X += (long double)point_x[i] / (long double)datelen; b[linelenth].Y += (long double)point_y[i] / (long double)datelen; } int re = 0; for (int i = 0; i < datelen - 1; i++) { b[linelenth].K += ((long double)point_y[i + 1] - (long double)point_y[i]) / ((long double)point_x[i + 1] - (long double)point_x[i]); re++; } b[linelenth].K = (long double)b[linelenth].K/(long double)re; b[linelenth].B = (long double)(b[linelenth].Y - b[linelenth].X*b[linelenth].K); //cout


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有