• 轮廓跟踪


    这个算法也是看到有的的,不算复杂,但算法让是个好算法。while(!FindPoint)是关键,它保证了在循环里面找到的点是边界点而不是内部点。

    上代码

    void CImageColorProcess::TraceContour(LPBYTE lpSrc, LPBYTE lpDst, LPBYTE lpDst_, int nSrcCount, int nW, int nH)
    {
    	this->OSTUThreshold(lpSrc, lpDst_, nSrcCount, nW, nH);//大律法二值化
    	bool bFindStartPoint;//是否找到起始点及回到起始点
    	bool bFindPoint;//是否找到一个边界点
    	int Direction[8][2] = { { -1, 1 }, { 0, 1 }, { 1, 1 }, { 1, 0 },
    	{ 1, -1 }, { 0, -1 }, { -1, -1 }, { -1, 0 } };//八个方向和起始扫描方向
    	int BeginDirect;
    	Point StartPoint, CurrentPoint;//起始点及当前边界点
    	for (int i = 0; i < nH; i++)// 目标图像设定初始值为背景255
    	{
    		for (int j = 0; j < nW; j++)
    		{
    			lpDst[i*nW + j] = 255;
    		}
    	}
    	bFindStartPoint = false;
    	for (int j = 0; j < nH&&!bFindStartPoint; j++)
    	{
    		for (int i = 0; i < nW&&!bFindStartPoint; i++)
    		{
    			if (lpDst_[(nH-1-j)*nW + i] == 0)// 指向源图像倒数第j行,第i个象素的指针	
    			{
    				bFindStartPoint = true;
    				StartPoint.m_row = j;
    				StartPoint.m_col = i;
    				lpDst[(nH - 1 - j)*nW + i] = 0;
    			}
    		}
    	}
    	//由于起始点是在左下方,故起始扫描沿左上方向
    	BeginDirect = 0;
    	bFindStartPoint = false;
    	//从初始点开始扫描
    	CurrentPoint.m_row = StartPoint.m_row;
    	CurrentPoint.m_col = StartPoint.m_col;
    	while (!bFindStartPoint)
    	{
    		bFindPoint = false;
    		while (!bFindPoint)
    		{
    			//沿扫描方向查看一个像素
    			if (lpDst_[(nH-1-(CurrentPoint.m_row + Direction[BeginDirect][1]))*nW + CurrentPoint.m_col
    				+ Direction[BeginDirect][0]] == 0)
    			{
    				bFindPoint = true;
    				CurrentPoint.m_row = CurrentPoint.m_row + Direction[BeginDirect][1];
    				CurrentPoint.m_col = CurrentPoint.m_col + Direction[BeginDirect][0];
    				if (CurrentPoint.m_row == StartPoint.m_row&&CurrentPoint.m_col == StartPoint.m_col)
    				{
    					bFindStartPoint = true;
    				}
    				lpDst[(nH-1-CurrentPoint.m_row)*nW + CurrentPoint.m_col] = 0;
    				//扫描的方向逆时针旋转两格
    				BeginDirect--;
    				if (BeginDirect == -1)
    					BeginDirect = 7;
    				BeginDirect--;
    				if (BeginDirect == -1)
    					BeginDirect = 7;
    			}
    			else
    			{
    				//扫描方向顺时针旋转一格
    				BeginDirect++;
    				if (BeginDirect == 8)
    					BeginDirect = 0;
    			}
    		}
    	}
    }

    经测试发现该算法对整个相连的轮廓检测较好,如果遇到了琐碎的小轮廓它可能找到的就是这个小轮廓,导致大轮廓检测失败。上一组测试图片:



    版权声明:

  • 相关阅读:
    树的重心备忘
    Hdu 2196
    HDU 1520
    TOJ1068 商务旅行
    携程HDU第一场1001
    USACO 4.3.2 The Primes
    Html常用标签的应用
    Html
    开班心得
    for循环练习及字符串处理
  • 原文地址:https://www.cnblogs.com/walccott/p/4957132.html
Copyright © 2020-2023  润新知