c语言实现轮廓标记

来源:互联网 发布:英语听力软件有哪些 编辑:程序博客网 时间:2024/05/16 05:54

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

(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;}

实验结果:

原图:


标记过程效果图:










原创粉丝点击