连通区域标记(c++版的bwlabel实现(基于opencv))
【连通区域标记(c++版的bwlabel实现(基于opencv))】类似于matlab中的bwlabel标记连通区域的c++版本实现,基于opencv,如下:
bwlabel.cpp
#include "cv.h" #include "highgui.h" #define NO_OBJECT 0 #define MIN(x, y) (((x) < (y)) ? (x) : (y)) #define ELEM(img, r, c) (CV_IMAGE_ELEM(img, unsigned char, r, c)) #define ONETWO(L, r, c, col) (L[(r) * (col) + c]) int find( int set[], int x ) { int r = x;
while ( set[r] != r ) r = set[r];
return r;
} /* labeling scheme +-+-+-+ |D|C|E| +-+-+-+ |B|A| | +-+-+-+ | | | | +-+-+-+ A is the center pixel of a neighborhood. In the 3 versions of connectedness: 4: A connects to B and C 6: A connects to B, C, and D 8: A connects to B, C, D, and E */ / //by yysdsyl // //input:img -- gray image // n -- n connectedness // labels -- label of each pixel, labels[row * col] //output: number of connected regions // // //email:yysdsyl@qq.com int bwlabel(IplImage* img, int n, int* labels) { if(n != 4 && n != 8) n = 4;
int nr = img->height;
int nc = img->width;
int total = nr * nc;
// results memset(labels, 0, total * sizeof(int));
int nobj = 0;
// number of objects found in image // other variables int* lset = new int[total];
// label table memset(lset, 0, total * sizeof(int));
int ntable = 0;
for( int r = 0;
r < nr;
r++ ) { for( int c = 0;
c < nc;
c++ ) { if ( ELEM(img, r, c) ) // if A is an object { // get the neighboring pixels B, C, D, and E int B, C, D, E;
if ( c == 0 ) B = 0;
else B = find( lset, ONETWO(labels, r, c - 1, nc) );
if ( r == 0 ) C = 0;
else C = find( lset, ONETWO(labels, r - 1, c, nc) );
if ( r == 0 || c == 0 ) D = 0;
else D = find( lset, ONETWO(labels, r - 1, c - 1, nc) );
if ( r == 0 || c == nc - 1 ) E = 0;
else E = find( lset, ONETWO(labels, r - 1, c + 1, nc) );
if ( n == 4 ) { // apply 4 connectedness if ( B && C ) { // B and C are labeled if ( B == C ) ONETWO(labels, r, c, nc) = B;
else { lset[C] = B;
ONETWO(labels, r, c, nc) = B;
} } else if ( B ) // B is object but C is not ONETWO(labels, r, c, nc) = B;
else if ( C ) // C is object but B is not ONETWO(labels, r, c, nc) = C;
else { // B, C, D not object - new object // label and put into table ntable++;
ONETWO(labels, r, c, nc) = lset[ ntable ] = ntable;
} } else if ( n == 6 ) { // apply 6 connected ness if ( D ) // D object, copy label and move on ONETWO(labels, r, c, nc) = D;
else if ( B && C ) { // B and C are labeled if ( B == C ) ONETWO(labels, r, c, nc) = B;
else { int tlabel = MIN(B,C);
lset[B] = tlabel;
lset[C] = tlabel;
ONETWO(labels, r, c, nc) = tlabel;
} } else if ( B ) // B is object but C is not ONETWO(labels, r, c, nc) = B;
else if ( C ) // C is object but B is not ONETWO(labels, r, c, nc) = C;
else { // B, C, D not object - new object // label and put into table ntable++;
ONETWO(labels, r, c, nc) = lset[ ntable ] = ntable;
} } else if ( n == 8 ) { // apply 8 connectedness if ( B || C || D || E ) { int tlabel = B;
if ( B ) tlabel = B;
else if ( C ) tlabel = C;
else if ( D ) tlabel = D;
else if ( E ) tlabel = E;
ONETWO(labels, r, c, nc) = tlabel;
if ( B && B != tlabel ) lset[B] = tlabel;
if ( C && C != tlabel ) lset[C] = tlabel;
if ( D && D != tlabel ) lset[D] = tlabel;
if ( E && E != tlabel ) lset[E] = tlabel;
} else { // label and put into table ntable++;
ONETWO(labels, r, c, nc) = lset[ ntable ] = ntable;
} } } else { ONETWO(labels, r, c, nc) = NO_OBJECT;
// A is not an object so leave it } } } // consolidate component table for( int i = 0;
i <= ntable;
i++ ) lset[i] = find( lset, i );
// run image through the look-up table for( int r = 0;
r < nr;
r++ ) for( int c = 0;
c < nc;
c++ ) ONETWO(labels, r, c, nc) = lset[ ONETWO(labels, r, c, nc) ];
// count up the objects in the image for( int i = 0;
i <= ntable;
i++ ) lset[i] = 0;
for( int r = 0;
r < nr;
r++ ) for( int c = 0;
c < nc;
c++ ) lset[ ONETWO(labels, r, c, nc) ]++;
// number the objects from 1 through n objects nobj = 0;
lset[0] = 0;
for( int i = 1;
i <= ntable;
i++ ) if ( lset[i] > 0 ) lset[i] = ++nobj;
// run through the look-up table again for( int r = 0;
r < nr;
r++ ) for( int c = 0;
c < nc;
c++ ) ONETWO(labels, r, c, nc) = lset[ ONETWO(labels, r, c, nc) ];
// delete[] lset;
return nobj;
}
代码下载: bwlabel.cpp
推荐阅读
- 「原宿」01门店区域卫生标准|「原宿」01门店区域卫生标准 -
- 铭
- Qt实战|Qt+OpenCV联合开发(十四)--图像感兴趣区域(ROI)的提取
- 看看CabloyJS是如何实现编辑页面脏标记的
- java内存区域与内存溢出异常
- 深入理解Java虚拟机之Java内存区域与内存溢出异常
- 把可滚动区域中-某个子元素平滑滚动到可视区域正中间位置
- 如何使用 Amazon S3 多区域访问点提高多区域应用程序的性能速度和可用性
- 求桥,边双连通缩点
- android集成百度地图定位、poi检索、marker标记功能,以及marker点击事件