-
速度比老版Two_Pass快很多,后续看明白怎么改8邻域的再改,改完再看性能吧
-
void Two_PassNew( const Mat &bwImg, Mat &labImg ) { assert( bwImg.type()==CV_8UC1 ); labImg.create( bwImg.size(), CV_32SC1 ); //bwImg.convertTo( labImg, CV_32SC1 ); labImg = Scalar(0); labImg.setTo( Scalar(1), bwImg ); assert( labImg.isContinuous() ); const int Rows = bwImg.rows - 1, Cols = bwImg.cols - 1; int label = 1; vector<int> labelSet; labelSet.push_back(0); labelSet.push_back(1); //the first pass int *data_prev = (int*)labImg.data; //0-th row : int* data_prev = labImg.ptr<int>(i-1); int *data_cur = (int*)( labImg.data + labImg.step ); //1-st row : int* data_cur = labImg.ptr<int>(i); for( int i = 1; i < Rows; i++ ) { data_cur++; data_prev++; for( int j=1; j<Cols; j++, data_cur++, data_prev++ ) { if( *data_cur!=1 ) continue; int left = *(data_cur-1); int up = *data_prev; int neighborLabels[2]; int cnt = 0; if( left>1 ) neighborLabels[cnt++] = left; if( up > 1) neighborLabels[cnt++] = up; if( !cnt ) { labelSet.push_back( ++label ); labelSet[label] = label; *data_cur = label; continue; } int smallestLabel = neighborLabels[0]; if( cnt==2 && neighborLabels[1]<smallestLabel ) smallestLabel = neighborLabels[1]; *data_cur = smallestLabel; // 保存最小等价表 for( int k=0; k<cnt; k++ ) { int tempLabel = neighborLabels[k]; int& oldSmallestLabel = labelSet[tempLabel]; //这里的&不是取地址符号,而是引用符号 if( oldSmallestLabel > smallestLabel ) { labelSet[oldSmallestLabel] = smallestLabel; oldSmallestLabel = smallestLabel; } else if( oldSmallestLabel<smallestLabel ) labelSet[smallestLabel] = oldSmallestLabel; } } data_cur++; data_prev++; } //更新等价队列表,将最小标号给重复区域 for( size_t i = 2; i < labelSet.size(); i++ ) { int curLabel = labelSet[i]; int prelabel = labelSet[curLabel]; while( prelabel != curLabel ) { curLabel = prelabel; prelabel = labelSet[prelabel]; } labelSet[i] = curLabel; } //second pass data_cur = (int*)labImg.data; for( int i = 0; i < Rows; i++ ) { for( int j = 0; j < bwImg.cols-1; j++, data_cur++) *data_cur = labelSet[ *data_cur ]; data_cur++; } } 八连通改完了 速度依然杠杠的 void Two_PassNewEight( const Mat &bwImg, Mat &labImg ) { assert( bwImg.type()==CV_8UC1 ); labImg.create( bwImg.size(), CV_32SC1 ); //bwImg.convertTo( labImg, CV_32SC1 ); labImg = Scalar(0); labImg.setTo( Scalar(1), bwImg ); assert( labImg.isContinuous() ); const int Rows = bwImg.rows - 1, Cols = bwImg.cols - 1; int label = 1; vector<int> labelSet; labelSet.push_back(0); labelSet.push_back(1); //the first pass int *data_prev = (int*)labImg.data; //0-th row : int* data_prev = labImg.ptr<int>(i-1); int *data_cur = (int*)( labImg.data + labImg.step ); //1-st row : int* data_cur = labImg.ptr<int>(i); for( int i = 1; i < Rows; i ++ ) { data_cur ++; data_prev ++; for( int j = 1; j < Cols; j ++, data_cur ++, data_prev ++ ) { if( *data_cur!=1 ) continue; int left = *(data_cur-1);//左 int up = *data_prev;//上 int leftup = *(data_prev - 1);//左 int rightup = *(data_prev + 1);//上 int neighborLabels[4]; int cnt = 0; if( left>1 ) neighborLabels[cnt ++] = left; if( up > 1) neighborLabels[cnt ++] = up; if( leftup > 1) neighborLabels[cnt ++] = leftup; if( rightup > 1) neighborLabels[cnt ++] = rightup; if( !cnt ) { labelSet.push_back( ++label ); labelSet[label] = label; *data_cur = label; continue; } int smallestLabel = neighborLabels[0]; if( cnt == 4 && neighborLabels[1]<smallestLabel ) smallestLabel = neighborLabels[1]; *data_cur = smallestLabel; // 保存最小等价表 for( int k=0; k< cnt; k++ ) { int tempLabel = neighborLabels[k]; int& oldSmallestLabel = labelSet[tempLabel]; //这里的&不是取地址符号,而是引用符号 if( oldSmallestLabel > smallestLabel ) { labelSet[oldSmallestLabel] = smallestLabel; oldSmallestLabel = smallestLabel; } else if( oldSmallestLabel<smallestLabel ) labelSet[smallestLabel] = oldSmallestLabel; } } data_cur++; data_prev++; } //更新等价队列表,将最小标号给重复区域 for( size_t i = 2; i < labelSet.size(); i++ ) { int curLabel = labelSet[i]; int prelabel = labelSet[curLabel]; while( prelabel != curLabel ) { curLabel = prelabel; prelabel = labelSet[prelabel]; } labelSet[i] = curLabel; } //second pass data_cur = (int*)labImg.data; for( int i = 0; i < Rows; i++ ) { for( int j = 0; j < bwImg.cols-1; j++, data_cur++) *data_cur = labelSet[ *data_cur ]; data_cur++; } for(int i = 0; i < Rows; i ++) { labImg.at<int>(i, 0) = 0; labImg.at<int>(i, Cols - 1) = 0; } for(int i = 0; i < Cols; i ++) { labImg.at<int>(0, i) = 0; labImg.at<int>(Rows - 1, i) = 0; } }
-
标记连通四邻域的
最新推荐文章于 2022-05-20 15:24:27 发布