matlab中bwlabel,连通区域标记: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;

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值