二值图像的贴标签算法
贴标签就是将二值图中属于同一个连通域的像素标记起来。之前编的程序需要多次遍历图像,所以速度比较慢,最近有朋友告诉我一种更简单的方法。这里对二值图中白色的连通域进行贴标签,具体步骤是:
1、按行遍历图像,当遇到一个白点时,说明遇到了一个标签区域;
2、将当前白点的坐标作为种子点入栈;
3、判断栈是否为空,若栈非空,则在栈顶元素所在位置贴上对应的标签号,同时将二值图上的该位置赋成别的颜色(表明当前元素已经贴过标签),弹出栈顶元素,并将其8邻域的白点入栈,重复3直到栈空,这时,当前连通域已经完成贴标签过程;
4、继续按行遍历图像,直到遇到下一个白点,然后重复步骤2-3,直到遍历完图像;
1 //////////////////////////////////////////////////// 2 // 功能:二值图贴标签(针对感兴趣区域) 3 // 参数: 4 // pBin - 二值图像 5 // pLabel - 标签矩阵(在外申请,和图像同样大小,并全部置0) 6 // lineByte - 图像的每行字节数 7 // roi - 感兴趣区域(左闭右开、上闭下开区间)
8 // 返回值: 9 // nLabel - 标签个数 10 /////////////////////////////////////////////////// 11 12 int Labeling(unsigned char *pBin, int *pLabel, int lineByte, CRect roi) 13 { 14 //感兴趣区域的4条边界 15 int xMin = roi.left; 16 int xMax = roi.right; 17 int yMin = roi.top; 18 int yMax = roi.bottom; 19 20 stack<CPoint> stk; 21 int i,j,x,y,k; 22 int nLabel = 0; //标签编号(从1号标签贴起,非标签区域贴0) 23 for (y=yMin; y<yMax; y++) 24 { 25 for (x=xMin; x<xMax; x++) 26 { 27 if (pBin[y*lineByte+x]==255) //以找到的第一个白点为种子点 28 { 29 nLabel++; 30 stk.push(CPoint(x,y)); //将种子点入栈 31 pLabel[y*lineByte+x] = nLabel; 32 pBin[y*lineByte+x] = nLabel*40; 33 34 //若栈非空,弹出一个元素,并将其8邻域内的白点入栈,栈空时当前连通域完成贴标签 35 while (!stk.empty()) 36 { 37 CPoint pt = stk.top(); 38 stk.pop(); 39 i = pt.y; 40 j = pt.x; 41 k = i*lineByte+j; 42 if (i>yMin && j>xMin && pBin[k-lineByte-1]==255) //左上 43 { 44 stk.push(CPoint(j-1,i-1)); 45 pLabel[k-lineByte-1] = nLabel; 46 pBin[k-lineByte-1] = nLabel*40; 47 } 48 if (i>yMin && pBin[k-lineByte]==255) //上 49 { 50 stk.push(CPoint(j,i-1)); 51 pLabel[k-lineByte] = nLabel; 52 pBin[k-lineByte] = nLabel*40; 53 } 54 if (i>yMin && j<xMax-1 && pBin[k-lineByte+1]==255) //右上 55 { 56 stk.push(CPoint(j+1,i-1)); 57 pLabel[k-lineByte+1] = nLabel; 58 pBin[k-lineByte+1] = nLabel*40; 59 } 60 if (j>xMin && pBin[k-1]==255) //左 61 { 62 stk.push(CPoint(j-1,i)); 63 pLabel[k-1] = nLabel; 64 pBin[k-1] = nLabel*40; 65 } 66 if (j<xMax-1 && pBin[k+1]==255) //右 67 { 68 stk.push(CPoint(j+1,i)); 69 pLabel[k+1] = nLabel; 70 pBin[k+1] = nLabel*40; 71 } 72 if (i<yMax-1 && j>xMin && pBin[k+lineByte-1]==255) //左下 73 { 74 stk.push(CPoint(j-1,i+1)); 75 pLabel[k+lineByte-1] = nLabel; 76 pBin[k+lineByte-1] = nLabel*40; 77 } 78 if (i<yMax-1 && pBin[k+lineByte]==255) //下 79 { 80 stk.push(CPoint(j,i+1)); 81 pLabel[k+lineByte] = nLabel; 82 pBin[k+lineByte] = nLabel*40; 83 } 84 if (i<yMax-1 && j<xMax-1 && pBin[k+lineByte+1]==255) //右下 85 { 86 stk.push(CPoint(j+1,i+1)); 87 pLabel[k+lineByte+1] = nLabel; 88 pBin[k+lineByte+1] = nLabel*40; 89 } 90 } 91 } 92 } 93 } 94 95 return nLabel; 96 }
posted on 2013-01-25 16:54 文森vincent 阅读(3015) 评论(0) 编辑 收藏 举报