图像轮廓搜索c实现

    图像轮廓搜索是图像处理中很基本很常用的算法,基于边缘跟踪的轮廓搜索是轮廓提取算法中较为高效的一种搜索算法。具体如下:

    (1) 从左到右,从上往下依次搜索非零点

    (2) 搜索到非零点并标记当前非零点,对当前非零点的八邻域按照逆时针进行搜索下一个非零点

    (3)若能够搜索到非零点,则重复步骤二,指导搜索完当前轮廓

    (4)当前轮廓搜索完毕,则返回(1)进行下一个轮廓进行搜索,如此重复直到所有的轮廓搜索完毕

void fetchContour(uchar *ptr, int step, int x, int y,point_t *points,int *count)
{
	int deltas[16];
	int s = 0, s_end = 0;
	int cur_x = x;
	int cur_y = y;
	int n = 0;

	uchar *i0 = ptr, *i1, *i3, *i4 = 0;
	const uchar nbd = 2;
	const uchar nbd_right = 3;

	POS_INDEX(deltas, step, 1);
	memcpy(deltas + 8, deltas, 8 * sizeof(deltas[0]));

	s_end = s = 4;

	//寻找该点周围非零点
	do
	{
		s = (s - 1) & 7;
		i1 = i0 + deltas[s];
		if (*i1 != 0)
			break;
	} while (s != s_end);

	//如果是孤立点,将其标记为3
	if (s == s_end)
	{
		*i0 = nbd_right;
	}
	else//非孤立点则对该点的边缘进行跟踪
	{
		i3 = i0;//i3为当前点的索引
		cur_x = x;
		cur_y = y;

		for (;;)
		{
			points[n].x = cur_x;
			points[n].y = cur_y;
			n++;
			s_end = s;
			//寻找i3周围不为零的点
			for (;;)
			{
				i4 = i3 + deltas[++s];
				if (*i4 != 0)
					break;
			}
			s &= 7;

			//获取当前非零点的位置
			cur_x = cur_x + codeDeltas[s][0];
			cur_y = cur_y + codeDeltas[s][1];

			//右边边界
			if ((unsigned)(s - 1) < (unsigned)s_end)
				*i3 = nbd_right;

			//其他边界
			else if (*i3 == 1)
				*i3 = nbd;

			//回到起始位置
			if (i4 == i0 && i3 == i1)
				break;

			//更新i3的位置
			i3 = i4;
			//s索引向当前搜索到点的位置,方便下一次搜索
			s = (s + 4) & 7;
		}

	}

	*count = n;

	return;
}
for (y = 1; y < height; y++)
{
	for (x = 1; x < width; x++)
	{
		//寻找每一行的非零元
		for (; x < width && (p = img -> pix[y * width + x]) == prev; x++);

		if (x >= width)
			break;

		if ((!(prev == 0 && p == 1)) || inner)
		{
			if (p == 2) inner = 1;
			else if (p == 3) inner = 0;

			prev = p;
			continue;
		}

		inner = 1;

		count = 0;
		fetchContour(&(img -> pix[y * width + x]), step, x, y,points,&count);			

		p = img -> pix[y * width + x];

		if (p == 2) inner = 1;
		else if (p == 3) inner = 0;
	}

	prev = 0;
	inner = 0;
}

如有不当之处,望指教,谢谢!

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值