精华内容
下载资源
问答
  • 八邻域跟踪算法理解

    千次阅读 2019-07-30 17:30:34
    八邻域跟踪算法基本思想是,遍历图像找到第一个非零像素点,那么这个点一定是边界点。设这个点为起始点x,顺时针查找该点八邻域内遇到的第一个非零像素点x'(点x'也为边界点)。令x=x',再进行邻域内的顺时针查找,...

             八邻域跟踪算法基本思想是,遍历图像找到第一个非零像素点,那么这个点一定是边界点。设这个点为起始点x,顺时针查找该点八邻域内遇到的第一个非零像素点x'(点x'也为边界点)。令x=x',再进行邻域内的顺时针查找,查找的起点为刚刚x到x'过程中x'前一个零点。                                           

                               

         对图(a), 在X点时,按照0->1->2->3->4…….的顺序进行查找。6处为查找到的第一个非零像素点,则6处为边界点,X'查找的起始位置是(a)中的5,即X'对应的4,则X'的查找顺序是4->5->6->7->0->1->2->3。

          同理可知。当X'为2,3时,查找起始点为0;当X'为4,5时,查找起始点为2;当X'为6,7时,查找起始点为4;当X'为0,1时,查找起始点为6。

     可用map映射进行存储。Map[0]=6,map[1]=6;map[2]=0,map[3]=0;map[4]=2,map[5]=2,

    Map[6]=4,map[7]=4.

        上一步查找到值为d(图a中d为6),则设置初始j=map[d](map[6]=4,即j=4;),但要对0,1,2,3继续查找,所以这里取除以8的余数。d设置为(d+i)%8(i=0,1,2……8)

                 

    展开全文
  • opencv 八邻域轮廓跟踪算法

    万次阅读 多人点赞 2016-12-23 22:37:04
    opencv 八邻域轮廓跟踪算法 图像处理中,往往需要用到轮廓跟踪解决一些问题,诸如轮廓点的排序得到相邻点。当使用findContours()查找轮廓的时候,我们希望得到Freeman码,但是实验发现并不是一个参数CV_CHAIN_CODE...

    opencv 八邻域轮廓跟踪算法

    图像处理中,往往需要用到轮廓跟踪解决一些问题,诸如轮廓点的排序得到相邻点。当使用findContours()查找轮廓的时候,我们希望得到Freeman码,但是实验发现并不是一个参数CV_CHAIN_CODE那么回事,网上一大堆的蜻蜓点水,说这个参数可以实现Freeman码生成,我怎么就没搜到一个生成结果,哪怕告诉我怎么才能得带到Freeman码,多方查阅相关书籍,比如朱伟的《opencv图像处理编程实例》,在findContours函数中没有指出这个参数CV_CHAIN_CODE,在图像处理大神毛星云的《opencv3图像处理》也没有看见这个参数。然后发现在opencv中,老版本的cvFindcontours貌似可以实现,网上查找很多,也是没有完整的解释和相应的代码可以得到Freeman码,很伤心,不开心。没办法,自己想得到类似Freeman码只能自己创造。所以就看见了八邻域轮廓跟踪可以得到它下一个轮廓点在哪里。
    关于八邻域概念这里不再多说,网上这种就很多了。八邻域跟踪和八链码跟踪不一样,前者是不知道下一个点在哪里,要得到下一个点在它的那个位置,而八链码跟踪是知道了方向,可以得到它下一个点的位置(这只是我个人理解,可能也是错的,哈哈)。网上也有相应的八邻域代码,写的很好,我大部分代码就是复制过来的,再加工一下,就可以满足自己的需要了。文章链接文章链接,这篇文章的代码比较通俗易懂,但是是老版本的图像类型,需要改进加工。那我也上我的代码,不多说。
    	int direction[8][2] = {{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1},{0,1},{1,1}};
    	vector<FM> FM(contours[0].size());
    	vector<int>d(contours[0].size());
    	vector<int>k(contours[0].size());
    	int CornersN=300;
    	vector<Point2f>vecCorners(CornersN);
    	int startDirect=0 ;
    	int FindStartPoint = 0;
    	int FindPoint = 0;
    	//开始跟踪
    	int X = startX;
    	int Y = startY;
    	int NextPtValue;
    	int nextX,nextY;
    	int i=0;
    	while(!FindStartPoint)
    	{
    		FindPoint=0;
    		while(!FindPoint)
    		{
    			//沿预定方向扫描,寻找下一个点
    			nextX=X+direction[startDirect][1];
    			nextY = Y + direction[startDirect][0];
    			NextPtValue=drawing.at<uchar>(nextX,nextY);
    			
    			if (NextPtValue != 0 && nextX>=0 && nextY>=0)
    			{
    				FM[i].ai=startDirect;
    				FM[i].x=nextY;
    				FM[i].y=nextX;
    				i++;
    				FindPoint = 1;
    				X = nextX;
    				Y = nextY;
    				if (X == startX && Y == startY)
    				{
    					FindStartPoint = 1;
    				}
    				startDirect = startDirect-2;
    				if(startDirect<0)
    					startDirect = startDirect+8;
    			}
    			else
    			{
    				startDirect = startDirect+1;
    				if (startDirect>=8) 
    					startDirect = startDirect-8;
    			}
    		}
    	}


    代码是部分代码,插入你的代码就好了,可能有些变量没有定义,可以自己找到加定义。代码中FM是我自己定义的一个结构体,看代码应该就看懂FM里面有什么,包括x,y,ai分别表示点的x,y和它在它前一个点的方向。directiong[8][2]二维数组是八个方向,首先是水平向右为起始,以逆时针为前进方向,结合八邻域那个图就懂了。找到了下一个点重新赋值,同时顺时针后退两个方向,没找到逆时针前进一个方向。道理就是我画个图先:

    首先如果起始点是最左上角的点,它的方向startDirect开始指向0,没找到,然后1,依次到7,找到了它的下一个点,然后方向还是7,要顺时针退两个方向,就是减2,变成起始点为5了,因为5上面的4已经在上一个点查找过了,不需要再去查找了。说完了,可能还有一些没说到的,基本思路那篇文章都说了一些,应该都比较好懂的。
    文章有些不妥之处,望大家批评指正,谢谢大家!
    展开全文
  • 一种基于八邻域深度差的点云边缘提取算法.pdf,提出了一种基于八邻域深度差(8N DD)的点云边缘提取算法算法根据目标特征的点云,对每个特征点沿深度方向进行垂直投影并对投影点进行栅格划分,计算出每个栅格内投影...
  • 种子填充算法--四邻域,八邻域

    千次阅读 2018-08-07 19:49:49
    种子填充算法最好使用非递归的方式,若使用递归方式,非常消耗栈内存容易溢出。 1.递归算法 void Polygon::fill(int x,int y,COLORREF color) { COLORREF currentColor=getColor(x,y); //如果当前位置颜色不是...

    种子填充算法最好使用非递归的方式,若使用递归方式,非常消耗栈内存容易溢出。

    1.递归算法

    void Polygon::fill(int x,int y,COLORREF color)
    {
        COLORREF currentColor=getColor(x,y);
        //如果当前位置颜色不是边框颜色而且不是指定颜色则填充
        if(currentColor!=borderColor && currentColor!=color)
        {
            putPixel/glVertex2i/.....  //填充颜色函数
            fill(x-1,y);
            fill(x+1,y);
            fill(x,y-1);
            fill(x,y+1);
        }
    }

    2.非递归算法

    void Polygon::fill(int x,int y,COLORREF color)
    {
        std::stack<Point>s;
        s.push(Point(x,y));
         COLORREF currentColor;
        while(!s.empty)
        {    
            Point p=s.top();
            s.pop();
            currentColor=getColor(x,y);
            //如果当前位置颜色不是边框颜色而且不是指定颜色则填充
            if(currentColor!=borderColor && currentColor!=color)
            {
                putPixel/glVertex2i/.....  //填充颜色函数
                s.push(Point(x-1,y));
                s.push(Point(x+1,y));
                s.push(Point(x,y-1));
                s.push(Point(x,y+1));
            }
        }
    }

     

    展开全文
  •  八邻域处理过程 *****************************/  /************************************  处理第一行的情况  **********************************/  // 搜索第一行的情况  if( Y>0 ) ...

     

    /***********************************************************************************

    **********

    **********        如果此代码对您有帮助的话,请多来踩我的Blog

    **********

    ************************************************************************************/

     

    int  i, j, nHeight, nWidth;    // 图像的高度和宽度
    bool  pbFlag[nHeight][nWidth];  //  声明一个大小为nHeight*nWidth的矩形
    int  xStart, xEnd, yStart, yEnd;
    /
    typedef struct  __XYPOSITION              //  定义一个图像中坐标的数据类型
    {
          int            xPos;                            //  x方向的坐标
          int            yPos;                            //  y方向的坐标
    }XYPOSITION, *PXYPOSITION;

    XYPOSITION  *pPosBottom, *pPosTop;
    XYPOSITION  pXYPos[nWidth*nHeight];            //  声明一个堆栈

    //  初始化,根据二维数据的地图初始化
    for(i=0; i <nHeight; i++ )    //  列扫描
    {
          for(j=0; j <nWidth; j++ )    //  行扫描
         {
                 //  如果地图数据为障碍物1,则pbFlag[i][j]=false
                 //  否则pbFlag[i][j] = true
          }
    }

    //  第一次搜索
    for(i=0; i <nHeight; i++ )    //  列扫描
    {
           for(j=0; j <nWidth; j++ )    //  行扫描
          {
                 if( pbFlag[i][j] )
                 {
                         //  初始化图像区域的位置
                        xStart = j;
                        xEnd  = j;
                        yStart = i;
                        yEnd  = i;

                        pPosBottom = pXYPos;
                        pPosTop    = pXYPos+1;
                        //  记录白色点的坐标
                        (*pPosBottom).xPos = j;
                        (*pPosBottom).yPos = i;
                        (*pPosBottom).pbCurrentPos = pbFlag+i*nWidth+j;
                        pbFlag[i][j] = false;

                       while( pPosBottom != pPosTop ) 
                       {
                                //  提取出搜索列表中的象素点
                               X = (*pPosBottom).xPos;
                               Y = (*pPosBottom++).yPos;

                              /*****************************
                                      八邻域处理过程
                              *****************************/
                             /************************************
                                      处理第一行的情况
                             **********************************/
                            //  搜索第一行的情况
                           if( Y>0 )
                           {
                                    Y1 = (Y-1);
                                   //  处理左上角的点
                                  if( X>0 )
                                  {
                                          if( pbFlag[Y1][X-1] )
                                          {
                                                 X1 = (X-1);
                                                (*pPosTop).xPos = X1;
                                                (*pPosTop).yPos = Y1;
                                               // 记录区域的大小
                                               xStart = min(xStart, X1);
                                               yStart = min(yStart, Y1);
                                               // 标识为已经搜索过
                                               pbFlag[Y1][X1] = false;
                                         }
                                 }
                                 // 处理正上边的点
                                 if( pbFlag[Y1][X])
                                 {
                                        (*pPosTop).xPos = X;
                                        (*pPosTop).yPos = Y1;
                                        // 记录区域的大小
                                        yStart = min(yStart, Y1);
                                        // 标识为已经搜索过
                                        pbFlag[Y1][X] = false;
                                  }
                                  //  处理右上角的点
                                  X1 = (X+1);
                                  if( X1 <nWidth )
                                  {
                                          if( pbFlag[Y1][X1] )
                                          {
                                                 (*pPosTop).xPos = X1;
                                                 (*pPosTop).yPos = Y1;
                                                 // 记录区域的大小
                                                 xEnd  = max(xEnd,  X1);
                                                 yStart = min(yStart, Y1);
                                                 // 标识为已经搜索过
                                                 pbFlag[Y1][X1] = false;
                                           }
                                     }
                                }
                       /******************************************************************
                                     处理第二行的情况
                        *****************************************************************/
                              //  搜索第二行的情况
                              // 处理正左边的点
                              if( X>0 )
                              {
                                     if( pbFlag[Y][X-1] )
                                     {
                                            X1 = (X-1);
                                           (*pPosTop).xPos = X1;
                                           (*pPosTop).yPos = Y;
                                           // 记录区域的大小
                                           xStart = min(xStart, X1); 
                                          // 标识为已经搜索过
                                          pbFlag[Y][X1] = false;
                                    }
                             }
                             //  处理正右边的点
                             X1 = (X+1);
                             if( X1 <nWidth  )
                             {
                                     if( pbFlag[Y][X1])
                                     {
                                            (*pPosTop).xPos = X1;
                                            (*pPosTop).yPos = Y;
                                            // 记录区域的大小
                                            xEnd  = max(xEnd,  X1);
                                            // 标识为已经搜索过
                                            pbFlag[Y][X1] = false;
                                      }
                                }
                         /*******************************************************************
                                      处理第三行的情况
                         ******************************************************************/
                                //  搜索第三行的情况
                                if( (Y+1) <nHeight )
                                {
                                        Y1 = (Y+1);
                                        //  处理左下角的点
                                       if( X>0 )
                                       {
                                              if( pbFlag[Y1][X-1])
                                              {
                                                      X1 = (X-1);
                                                      (*pPosTop).xPos = X1;
                                                      (*pPosTop).yPos = Y1;
                                                      // 记录区域的大小
                                                      xStart = min(xStart, X1); 
                                                      yEnd  = max(yEnd,  Y1);
                                                      // 标识为已经搜索过
                                                      pbFlag[Y1][X1] = false;
                                               }
                                         }
                                         //  处理正下边的点
                                         if( pbFlag[Y1][X])
                                         {
                                                (*pPosTop).xPos = X;
                                                (*pPosTop).yPos = Y1;
                                                // 记录区域的大小
                                                yEnd  = max(yEnd,  Y1);
                                                // 标识为已经搜索过
                                                pbFlag[Y1][X] = false;
                                         }
                                         //  处理右下角的点
                                         X1 = (X+1);
                                         if( X1 <nWidth )
                                        {
                                               if( pbFlag[Y1][X+1])
                                               {
                                                      (*pPosTop).xPos = X1;
                                                      (*pPosTop).yPos = Y1;
                                                      // 记录区域的大小
                                                      xEnd  = max(xEnd,  X1);
                                                      yEnd  = max(yEnd,  Y1);
                                                      // 标识为已经搜索过
                                                      pbFlag[Y1][X1] = false;
                                                }
                                         }
                                   }
                           }        //  while

                 /*******************************************************************
                             输出搜索到的子区域块
                 ******************************************************************/
                         if( xStart != 0                //  去除左边
                              && xEnd != (nWidth-1)      //  去除右边
                              && yStart != 0            //  去除上边
                              && yEnd  != (nHeight-1)  //  去除下边
                          )
                          {
                                    pPosBottom = pXYPos;

                                    while( pPosBottom != pPosTop ) 
                                   {
                                             //  输出图形中被障碍物包围的所有点的坐标X,Y
                                             X = (*pPosBottom).xPos;
                                             Y = (*pPosBottom ++).yPos;
                                    }
                             }
                    }
             } //  for j
    } // for i

    展开全文
  • 图像处理(五):八邻域边缘跟踪与区域生长算法

    万次阅读 多人点赞 2017-11-17 11:12:39
    边缘跟踪又分为八邻域和四邻域两种,具体原理可以参考残影、的博客。 实现步骤: 1、灰度化并进行Canny边缘检测 2、按照预先设定的跟踪方向(顺时针)进行边缘跟踪 3、每次跟踪的终止条件为:8邻域都不存在轮廓 ...
  • 八邻域断点检测

    千次阅读 2016-12-27 20:51:10
    八邻域断点检测  本文的理论思想主要来源大家可以参照,迈克老狼2012:OpenCV学习(13) 细化算法(1) 。本文是我自己尝试着将八邻域的细化思想 运用到断点检测上,个人觉得其实仅仅是八邻域应用的一小方面大家...
  • 为避免早熟收敛和局部最优...在个测试函数上,将CNS-PSO与标准PSO进行了对比,在不同维度的大多数函数上,前者的性能均优于后者,说明具有无标度网络邻域结构的CNS-PSO算法具有较强的避免早熟和逃逸局部最优的能力。
  • 四向边沿跟踪算子.c

    2019-12-31 00:32:01
    参考了网上的各种摄像头识别图像算法(虫随法,摩尔邻域跟踪算法,八邻域链码边界跟踪算法,生长算法,canny边缘检测算子),探索出了一种高效的识别算法,经测试,该算法要比八邻域抑或是八邻域算法要简单的多,...
  • 算法采用0°、22.5°、 45°、67.5°、 90°、112.5°、135°和157.5°个方向的卷积模板进行边缘检测,模板权值根据中心像素点到邻域像素的距离及方向夹角的大小进行设定,充分考虑到了邻域内像素对中心点方向梯度...
  • 参考了网上的各种摄像头识别图像算法(虫随法,摩尔邻域跟踪算法,八邻域链码边界跟踪算法,生长算法,canny边缘检测算子),探索出了一种高效的识别算法,经测试,该算法要比生长算法抑或是八邻域算法要简单的多,...
  • 区域标记算法

    千次阅读 2006-04-15 14:34:00
    区域标记算法 cndg 2006-4-15这里介绍区域标记算法,所谓区域标记就是把连续区域作同一个标记,常见的四邻域标记算法八邻域标记算法。现在就介绍它们的基本思想。1、 四邻域标记算法: 1) 判断此点四邻域中...
  • 二值图像连通域标记算法与代码

    万次阅读 热门讨论 2009-08-07 15:46:00
    10:19:42二值图像连通域标记算法与代码 这里列举二值图像连通域标记算法包括直接扫描标记算法和二值图像连通域标记快速算法一、直接扫描标记算法把连续区域作同一个标记,常见的四邻域标记算法八邻域标记算法。...
  • 基于八邻域的轮廓跟踪算法,用matlab实现
  • 实现原理:在处理八方向浮雕时,将某一个像素与其八邻域的任一像素进行相减,然后加上一个偏移值。该像素的八邻域又根据方位称为西北方(左上)、北方(上)、东北方(右上)、东方(右)、东南方(右下)、南方(下...
  • 二值图像连通域标记算法

    千次阅读 2015-05-31 22:21:35
    八邻域标记算法: 1) 判断此点八邻域中的最左,左上,最上,上右点的情况。如果都没有点,则表示一个新的区域的开始。 2) 如果此点八邻域中的最左有点,上右都有点,则标记此点为这两个中的最小的标记点,并修改大...
  • 二值图像连通域标记算法与代码 .

    千次阅读 2013-09-23 21:13:35
    二值图像连通域标记算法与代码 ...一、直接扫描标记算法把连续区域作同一个标记,常见的四邻域标记算法八邻域标记算法。 1、 四邻域标记算法: 1) 判断此点四邻域中的最左,最上有没有点,如果都没有点
  • 区域增长算法的原理非常简单,就是以一个种子点作为生长的起点,然后将种子周围的点(可以是四邻域也可以是八邻域)进行筛选(筛选条件可以是与种子点像素值是否接近,或者像素梯度是否小于阈值等等)。 如果满足...
  • 图像处理之泛洪填充算法(Flood Fill Algorithm)

    万次阅读 多人点赞 2013-05-10 01:23:34
    泛洪填充算法(Flood Fill Algorithm) 泛洪填充算法又称洪水填充算法是在很多图形绘制软件中常用的填充算法,最熟悉不过就是 ...像素填充法,八邻域像素填充法,基于扫描线的像素填充方法。根据实现又可以分为
  • 区域标记算法 这里介绍区域标记算法,所谓区域标记就是把连续区域作同一个标记,常见的四邻域标记算法八邻域标记算法。现在就介绍它们的基本思想。1、 四邻域标记算法:1) 判断此点四邻域中的最

空空如也

空空如也

1 2 3 4 5 6
收藏数 114
精华内容 45
关键字:

八邻域算法