mirror of
https://github.com/opencv/opencv.git
synced 2025-08-06 14:36:36 +08:00
Add Grana's connected components algorithm for 8-way connectivity. (#6823)
* Add Grana's connected components algorithm for 8-way connectivity. That algorithm is faster than Wu's one (currently implemented in opencv). For more details see https://github.com/prittt/YACCLAB. * New functions signature and distance transform compatibility * Add tests to imgproc/test/test_connectedcomponents.cpp * Change of test_connectedcomponents.cpp for c++98 support
This commit is contained in:
parent
4f0f5a24ef
commit
5ddd25313f
@ -413,6 +413,13 @@ enum ConnectedComponentsTypes {
|
||||
CC_STAT_MAX = 5
|
||||
};
|
||||
|
||||
//! connected components algorithm
|
||||
enum ConnectedComponentsAlgorithmsTypes {
|
||||
CCL_WU = 0, //!< SAUF algorithm for 8-way connectivity, SAUF algorithm for 4-way connectivity
|
||||
CCL_DEFAULT = -1, //!< BBDT algortihm for 8-way connectivity, SAUF algorithm for 4-way connectivity
|
||||
CCL_GRANA = 1 //!< BBDT algorithm for 8-way connectivity, SAUF algorithm for 4-way connectivity
|
||||
};
|
||||
|
||||
//! mode of the contour retrieval algorithm
|
||||
enum RetrievalModes {
|
||||
/** retrieves only the extreme outer contours. It sets `hierarchy[i][2]=hierarchy[i][3]=-1` for
|
||||
@ -3648,7 +3655,21 @@ CV_EXPORTS_W void matchTemplate( InputArray image, InputArray templ,
|
||||
image with 4 or 8 way connectivity - returns N, the total number of labels [0, N-1] where 0
|
||||
represents the background label. ltype specifies the output label image type, an important
|
||||
consideration based on the total number of labels or alternatively the total number of pixels in
|
||||
the source image.
|
||||
the source image. ccltype specifies the connected components labeling algorithm to use, currently
|
||||
Grana's (BBDT) and Wu's (SAUF) algorithms are supported, see the cv::ConnectedComponentsAlgorithmsTypes
|
||||
for details. Note that SAUF algorithm forces a row major ordering of labels while BBDT does not.
|
||||
|
||||
@param image the 8-bit single-channel image to be labeled
|
||||
@param labels destination labeled image
|
||||
@param connectivity 8 or 4 for 8-way or 4-way connectivity respectively
|
||||
@param ltype output image label type. Currently CV_32S and CV_16U are supported.
|
||||
@param ccltype connected components algorithm type (see the cv::ConnectedComponentsAlgorithmsTypes).
|
||||
*/
|
||||
CV_EXPORTS_AS(connectedComponentsWithAlgorithm) int connectedComponents(InputArray image, OutputArray labels,
|
||||
int connectivity, int ltype, int ccltype);
|
||||
|
||||
|
||||
/** @overload
|
||||
|
||||
@param image the 8-bit single-channel image to be labeled
|
||||
@param labels destination labeled image
|
||||
@ -3658,6 +3679,32 @@ the source image.
|
||||
CV_EXPORTS_W int connectedComponents(InputArray image, OutputArray labels,
|
||||
int connectivity = 8, int ltype = CV_32S);
|
||||
|
||||
|
||||
/** @brief computes the connected components labeled image of boolean image and also produces a statistics output for each label
|
||||
|
||||
image with 4 or 8 way connectivity - returns N, the total number of labels [0, N-1] where 0
|
||||
represents the background label. ltype specifies the output label image type, an important
|
||||
consideration based on the total number of labels or alternatively the total number of pixels in
|
||||
the source image. ccltype specifies the connected components labeling algorithm to use, currently
|
||||
Grana's (BBDT) and Wu's (SAUF) algorithms are supported, see the cv::ConnectedComponentsAlgorithmsTypes
|
||||
for details. Note that SAUF algorithm forces a row major ordering of labels while BBDT does not.
|
||||
|
||||
|
||||
@param image the 8-bit single-channel image to be labeled
|
||||
@param labels destination labeled image
|
||||
@param stats statistics output for each label, including the background label, see below for
|
||||
available statistics. Statistics are accessed via stats(label, COLUMN) where COLUMN is one of
|
||||
cv::ConnectedComponentsTypes. The data type is CV_32S.
|
||||
@param centroids centroid output for each label, including the background label. Centroids are
|
||||
accessed via centroids(label, 0) for x and centroids(label, 1) for y. The data type CV_64F.
|
||||
@param connectivity 8 or 4 for 8-way or 4-way connectivity respectively
|
||||
@param ltype output image label type. Currently CV_32S and CV_16U are supported.
|
||||
@param ccltype connected components algorithm type (see the cv::ConnectedComponentsAlgorithmsTypes).
|
||||
*/
|
||||
CV_EXPORTS_AS(connectedComponentsWithStatsWithAlgorithm) int connectedComponentsWithStats(InputArray image, OutputArray labels,
|
||||
OutputArray stats, OutputArray centroids,
|
||||
int connectivity, int ltype, int ccltype);
|
||||
|
||||
/** @overload
|
||||
@param image the 8-bit single-channel image to be labeled
|
||||
@param labels destination labeled image
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -827,7 +827,7 @@ void cv::distanceTransform( InputArray _src, OutputArray _dst, OutputArray _labe
|
||||
if( labelType == CV_DIST_LABEL_CCOMP )
|
||||
{
|
||||
Mat zpix = src == 0;
|
||||
connectedComponents(zpix, labels, 8, CV_32S);
|
||||
connectedComponents(zpix, labels, 8, CV_32S, CCL_WU);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -42,6 +42,7 @@
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
@ -58,8 +59,30 @@ protected:
|
||||
CV_ConnectedComponentsTest::CV_ConnectedComponentsTest() {}
|
||||
CV_ConnectedComponentsTest::~CV_ConnectedComponentsTest() {}
|
||||
|
||||
// This function force a row major order for the labels
|
||||
void normalizeLabels(Mat1i& imgLabels, int iNumLabels) {
|
||||
vector<int> vecNewLabels(iNumLabels + 1, 0);
|
||||
int iMaxNewLabel = 0;
|
||||
|
||||
for (int r = 0; r<imgLabels.rows; ++r) {
|
||||
for (int c = 0; c<imgLabels.cols; ++c) {
|
||||
int iCurLabel = imgLabels(r, c);
|
||||
if (iCurLabel>0) {
|
||||
if (vecNewLabels[iCurLabel] == 0) {
|
||||
vecNewLabels[iCurLabel] = ++iMaxNewLabel;
|
||||
}
|
||||
imgLabels(r, c) = vecNewLabels[iCurLabel];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CV_ConnectedComponentsTest::run( int /* start_from */)
|
||||
{
|
||||
|
||||
int ccltype[] = { cv::CCL_WU, cv::CCL_DEFAULT, cv::CCL_GRANA };
|
||||
|
||||
string exp_path = string(ts->get_data_path()) + "connectedcomponents/ccomp_exp.png";
|
||||
Mat exp = imread(exp_path, 0);
|
||||
Mat orig = imread(string(ts->get_data_path()) + "connectedcomponents/concentric_circles.png", 0);
|
||||
@ -71,9 +94,16 @@ void CV_ConnectedComponentsTest::run( int /* start_from */)
|
||||
}
|
||||
|
||||
Mat bw = orig > 128;
|
||||
Mat labelImage;
|
||||
int nLabels = connectedComponents(bw, labelImage, 8, CV_32S);
|
||||
|
||||
for (uint cclt = 0; cclt < sizeof(ccltype)/sizeof(int); ++cclt)
|
||||
{
|
||||
|
||||
Mat1i labelImage;
|
||||
int nLabels = connectedComponents(bw, labelImage, 8, CV_32S, ccltype[cclt]);
|
||||
|
||||
normalizeLabels(labelImage, nLabels);
|
||||
|
||||
// Validate test results
|
||||
for (int r = 0; r < labelImage.rows; ++r){
|
||||
for (int c = 0; c < labelImage.cols; ++c){
|
||||
int l = labelImage.at<int>(r, c);
|
||||
@ -101,6 +131,9 @@ void CV_ConnectedComponentsTest::run( int /* start_from */)
|
||||
ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ts->set_failed_test_info(cvtest::TS::OK);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user