c语言实现轮廓标记

本文实现的是一种比较基础的轮廓标记方法:

(1)首先寻找不为零的像素点,即像素值为value=255。

(2)对当前像素点分别向左、向右搜索当前行的其实坐标。

(3)对(2)中搜索到当前行的起始行坐标,分别搜索上一行、下一行value = 255的末坐标。

(4)依次循环(1)-(3)直到当前轮廓标记完毕。

(5)寻找下一个轮廓。

(6)依此类推,直到所有轮廓被标记完成。


int blob_scan(image_ctx_ptr img)
{
	int w = img->w;
	int h = img->h;

	int i = 0;
	int cur_label = 1;
	int p_size = BLOB_STACK_SIZE;
	static point_t blob_stack[BLOB_STACK_SIZE];
	point_t* points = blob_stack; 
	uchar* pix = (uchar*)img->pix;

	//img_show(img, "thre");

	for (int y = 0; y < h; y++)
	{
		for (int x = 0; x < w; x++)
		{
			uchar value = pix[y * w + x];
			if (value == 255)
			{
				int s, e;
				int p_idx = 0;
				int p_max = 1;
				points[0].x = x;
				points[0].y = y;

				while (p_idx != p_max)
				{
					//获取栈顶元素
					point_t* p = &points[p_idx++];

					if (p_idx == p_size)
						p_idx = 0;

					//当上边行为两段,当前行为一整行
					if (value != pix[p->y * w + p->x])
						continue;

					//当前行当前点的坐标左边连续点扫描
					for (s = p->x - 1; s > 0 && pix[p->y * w + s] == value; s--);
					//当前行当前点的坐标右边连续点扫描
					for (e = p->x + 1; e < w && pix[p->y * w + e] == value; e++);

					s = s < 0 ? 0 : s;
					e = e > w - 1 ? w - 1 : e;

					//标注当前点
					for (i = s + 1; i < e; i++)
					{
						pix[p -> y * w + i] = cur_label;
					}

					//当前行的上一行扫描
					for (i = s; i <= e; i++)
					{
						if ((p->y - 1) > 0 && pix[(p->y - 1) * w + i] == value)
						{
							if (i == e || pix[(p->y - 1) * w + i + 1] != value)
							{
								points[p_max].x = i;
								points[p_max].y = p->y - 1;

								if (++p_max == p_size)
									p_max = 0;
								if (p_max == p_idx)
									goto kk;
							}
						}
					}

					//当前行的下一行扫描
					for (i = s; i <= e; i++)
					{
						if ((p->y + 1) < w && pix[(p->y + 1) * w + i] == value)
						{
							if (i == e || pix[(p->y + 1) * w + i + 1] != value)
							{
								points[p_max].x = i;
								points[p_max].y = p->y + 1;

								if (++p_max == p_size)
									p_max = 0;
								if (p_max == p_idx)
									goto kk;
							}
						}
					}
				}

				cur_label++;
			
			}
		}
	}

kk:
	return cur_label;
}

实验结果:

原图:


标记过程效果图:










  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值