Removed parallel version for CV_16U label type

pull/7705/head
Michele Cancilla 9 years ago
parent 4b7fc59332
commit 89a0a46a69
  1. 4
      modules/imgproc/include/opencv2/imgproc.hpp
  2. 37
      modules/imgproc/src/connectedcomponents.cpp

@ -3677,7 +3677,7 @@ the source image. ccltype specifies the connected components labeling algorithm
Grana (BBDT) and Wu's (SAUF) algorithms are supported, see the cv::ConnectedComponentsAlgorithmsTypes Grana (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. for details. Note that SAUF algorithm forces a row major ordering of labels while BBDT does not.
This function uses parallel version of both Grana and Wu's algorithms if at least one allowed This function uses parallel version of both Grana and Wu's algorithms if at least one allowed
parallel framework is enabled. parallel framework is enabled and if the rows of the image are at least twice the number returned by getNumberOfCPUs.
@param image the 8-bit single-channel image to be labeled @param image the 8-bit single-channel image to be labeled
@param labels destination labeled image @param labels destination labeled image
@ -3709,7 +3709,7 @@ the source image. ccltype specifies the connected components labeling algorithm
Grana's (BBDT) and Wu's (SAUF) algorithms are supported, see the cv::ConnectedComponentsAlgorithmsTypes 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. for details. Note that SAUF algorithm forces a row major ordering of labels while BBDT does not.
This function uses parallel version of both Grana and Wu's algorithms (statistics included) if at least one allowed This function uses parallel version of both Grana and Wu's algorithms (statistics included) if at least one allowed
parallel framework is enabled. parallel framework is enabled and if the rows of the image are at least twice the number returned by getNumberOfCPUs.
@param image the 8-bit single-channel image to be labeled @param image the 8-bit single-channel image to be labeled
@param labels destination labeled image @param labels destination labeled image

@ -288,7 +288,7 @@ namespace cv{
int r = range.start; int r = range.start;
chunksSizeAndLabels_[r] = range.end; chunksSizeAndLabels_[r] = range.end;
LabelT label = LabelT(r *imgLabels_.cols / 4 + 1); LabelT label = LabelT((r * imgLabels_.cols + 1) / 2 + 1);
const LabelT firstLabel = label; const LabelT firstLabel = label;
const int w = img_.cols; const int w = img_.cols;
@ -390,7 +390,7 @@ namespace cv{
int r = range.start; int r = range.start;
chunksSizeAndLabels_[r] = range.end; chunksSizeAndLabels_[r] = range.end;
LabelT label = LabelT(r *imgLabels_.cols / 4 + 1); LabelT label = LabelT((r * imgLabels_.cols + 1) / 2 + 1);
const LabelT firstLabel = label; const LabelT firstLabel = label;
const int w = img_.cols; const int w = img_.cols;
@ -606,6 +606,7 @@ namespace cv{
P[0] = 0; P[0] = 0;
cv::Range range(0, h); cv::Range range(0, h);
LabelT nLabels = 1;
if (connectivity == 8){ if (connectivity == 8){
//First scan, each thread works with chunk of img.rows/nThreads rows //First scan, each thread works with chunk of img.rows/nThreads rows
@ -623,10 +624,9 @@ namespace cv{
//merge labels of different chunks //merge labels of different chunks
mergeLabels4Connectivity(imgLabels, P, chunksSizeAndLabels); mergeLabels4Connectivity(imgLabels, P, chunksSizeAndLabels);
} }
LabelT nLabels = 1;
for (int i = 0; i < h; i = chunksSizeAndLabels[i]){ for (int i = 0; i < h; i = chunksSizeAndLabels[i]){
flattenL(P, i * w / 4 + 1, chunksSizeAndLabels[i + 1], nLabels); flattenL(P, (i * w + 1) / 2 + 1, chunksSizeAndLabels[i + 1], nLabels);
} }
//Array for statistics dataof threads //Array for statistics dataof threads
@ -650,7 +650,6 @@ namespace cv{
//Kesheng Wu, et al //Kesheng Wu, et al
template<typename LabelT, typename PixelT, typename StatsOp = NoOp > template<typename LabelT, typename PixelT, typename StatsOp = NoOp >
struct LabelingWu{ struct LabelingWu{
LabelT operator()(const cv::Mat& img, cv::Mat& imgLabels, int connectivity, StatsOp& sop){ LabelT operator()(const cv::Mat& img, cv::Mat& imgLabels, int connectivity, StatsOp& sop){
CV_Assert(imgLabels.rows == img.rows); CV_Assert(imgLabels.rows == img.rows);
CV_Assert(imgLabels.cols == img.cols); CV_Assert(imgLabels.cols == img.cols);
@ -842,7 +841,7 @@ namespace cv{
chunksSizeAndLabels_[r] = range.end + (range.end % 2); chunksSizeAndLabels_[r] = range.end + (range.end % 2);
LabelT label = LabelT(r *imgLabels_.cols / 4 + 1); LabelT label = LabelT((r + 1) * (imgLabels_.cols + 1) / 4);
const LabelT firstLabel = label; const LabelT firstLabel = label;
const int h = img_.rows, w = img_.cols; const int h = img_.rows, w = img_.cols;
@ -2562,7 +2561,7 @@ namespace cv{
LabelT nLabels = 1; LabelT nLabels = 1;
for (int i = 0; i < h; i = chunksSizeAndLabels[i]){ for (int i = 0; i < h; i = chunksSizeAndLabels[i]){
flattenL(P, i *w / 4 + 1, chunksSizeAndLabels[i + 1], nLabels); flattenL(P, (i + 1) * (w + 1) / 4, chunksSizeAndLabels[i + 1], nLabels);
} }
//Array for statistics data //Array for statistics data
@ -3932,30 +3931,28 @@ namespace cv{
int lDepth = L.depth(); int lDepth = L.depth();
int iDepth = I.depth(); int iDepth = I.depth();
const char *currentParallelFramework = cv::currentParallelFramework(); const char *currentParallelFramework = cv::currentParallelFramework();
const int numberOfCPUs = cv::getNumberOfCPUs();
CV_Assert(iDepth == CV_8U || iDepth == CV_8S); CV_Assert(iDepth == CV_8U || iDepth == CV_8S);
//Run parallel labeling only if the rows of the image are at least twice the number returned by getNumberOfCPUs
const bool is_parallel = currentParallelFramework != NULL && numberOfCPUs > 1 && L.rows / numberOfCPUs >= 2;
if (ccltype == CCL_WU || connectivity == 4){ if (ccltype == CCL_WU || connectivity == 4){
// Wu algorithm is used // Wu algorithm is used
using connectedcomponents::LabelingWu; using connectedcomponents::LabelingWu;
using connectedcomponents::LabelingWuParallel; using connectedcomponents::LabelingWuParallel;
//warn if L's depth is not sufficient? //warn if L's depth is not sufficient?
if (lDepth == CV_8U){ if (lDepth == CV_8U){
if (currentParallelFramework == NULL) //Not supported yet
return (int)LabelingWu<uchar, uchar, StatsOp>()(I, L, connectivity, sop);
else
return (int)LabelingWuParallel<uchar, uchar, StatsOp>()(I, L, connectivity, sop);
} }
else if (lDepth == CV_16U){ else if (lDepth == CV_16U){
if (currentParallelFramework == NULL)
return (int)LabelingWu<ushort, uchar, StatsOp>()(I, L, connectivity, sop); return (int)LabelingWu<ushort, uchar, StatsOp>()(I, L, connectivity, sop);
else
return (int)LabelingWuParallel<ushort, uchar, StatsOp>()(I, L, connectivity, sop);
} }
else if (lDepth == CV_32S){ else if (lDepth == CV_32S){
//note that signed types don't really make sense here and not being able to use unsigned matters for scientific projects //note that signed types don't really make sense here and not being able to use unsigned matters for scientific projects
//OpenCV: how should we proceed? .at<T> typechecks in debug mode //OpenCV: how should we proceed? .at<T> typechecks in debug mode
if (currentParallelFramework == NULL) if (!is_parallel)
return (int)LabelingWu<int, uchar, StatsOp>()(I, L, connectivity, sop); return (int)LabelingWu<int, uchar, StatsOp>()(I, L, connectivity, sop);
else else
return (int)LabelingWuParallel<int, uchar, StatsOp>()(I, L, connectivity, sop); return (int)LabelingWuParallel<int, uchar, StatsOp>()(I, L, connectivity, sop);
@ -3967,21 +3964,15 @@ namespace cv{
using connectedcomponents::LabelingGranaParallel; using connectedcomponents::LabelingGranaParallel;
//warn if L's depth is not sufficient? //warn if L's depth is not sufficient?
if (lDepth == CV_8U){ if (lDepth == CV_8U){
if (currentParallelFramework == NULL) //Not supported yet
return (int)LabelingGrana<uchar, uchar, StatsOp>()(I, L, connectivity, sop);
else
return (int)LabelingGranaParallel<uchar, uchar, StatsOp>()(I, L, connectivity, sop);
} }
else if (lDepth == CV_16U){ else if (lDepth == CV_16U){
if (currentParallelFramework == NULL)
return (int)LabelingGrana<ushort, uchar, StatsOp>()(I, L, connectivity, sop); return (int)LabelingGrana<ushort, uchar, StatsOp>()(I, L, connectivity, sop);
else
return (int)LabelingGranaParallel<ushort, uchar, StatsOp>()(I, L, connectivity, sop);
} }
else if (lDepth == CV_32S){ else if (lDepth == CV_32S){
//note that signed types don't really make sense here and not being able to use unsigned matters for scientific projects //note that signed types don't really make sense here and not being able to use unsigned matters for scientific projects
//OpenCV: how should we proceed? .at<T> typechecks in debug mode //OpenCV: how should we proceed? .at<T> typechecks in debug mode
if (currentParallelFramework == NULL) if (!is_parallel)
return (int)LabelingGrana<int, uchar, StatsOp>()(I, L, connectivity, sop); return (int)LabelingGrana<int, uchar, StatsOp>()(I, L, connectivity, sop);
else else
return (int)LabelingGranaParallel<int, uchar, StatsOp>()(I, L, connectivity, sop); return (int)LabelingGranaParallel<int, uchar, StatsOp>()(I, L, connectivity, sop);

Loading…
Cancel
Save