Skip to content

Commit 0e91983

Browse files
Jaykobalalek
authored andcommitted
Merge pull request #1330 from Jaykob:parallelize_structured_edge_detection
* Replace OpenMP parallelization with OpenCV's general parallel_for_ to cover other backends than OpenMP. * Fixed shadowing of range variable in C++11 mode.
1 parent 1706988 commit 0e91983

File tree

1 file changed

+52
-40
lines changed

1 file changed

+52
-40
lines changed

modules/ximgproc/src/structured_edge_detection.cpp

Lines changed: 52 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -729,65 +729,73 @@ class StructuredEdgeDetectionImpl : public StructuredEdgeDetection
729729
offsetY[n] = x2*features.cols*nchannels + y2*nchannels + z;
730730
}
731731
// lookup tables for mapping linear index to offset pairs
732-
#ifdef _OPENMP
733-
#pragma omp parallel for
732+
733+
#ifdef CV_CXX11
734+
parallel_for_(cv::Range(0, height), [&](const cv::Range& range)
735+
#else
736+
const cv::Range range(0, height);
734737
#endif
735-
for (int i = 0; i < height; ++i)
736738
{
737-
float *regFeaturesPtr = regFeatures.ptr<float>(i*stride/shrink);
738-
float *ssFeaturesPtr = ssFeatures.ptr<float>(i*stride/shrink);
739-
740-
int *indexPtr = indexes.ptr<int>(i);
739+
for(int i = range.start; i < range.end; ++i) {
740+
float *regFeaturesPtr = regFeatures.ptr<float>(i*stride/shrink);
741+
float *ssFeaturesPtr = ssFeatures.ptr<float>(i*stride/shrink);
741742

742-
for (int j = 0, k = 0; j < width; ++k, j += !(k %= nTreesEval))
743-
// for j,k in [0;width)x[0;nTreesEval)
744-
{
745-
int baseNode = ( ((i + j)%(2*nTreesEval) + k)%nTrees )*nTreesNodes;
746-
int currentNode = baseNode;
747-
// select root node of the tree to evaluate
743+
int *indexPtr = indexes.ptr<int>(i);
748744

749-
int offset = (j*stride/shrink)*nchannels;
750-
while ( __rf.childs[currentNode] != 0 )
745+
for (int j = 0, k = 0; j < width; ++k, j += !(k %= nTreesEval))
746+
// for j,k in [0;width)x[0;nTreesEval)
751747
{
752-
int currentId = __rf.featureIds[currentNode];
753-
float currentFeature;
748+
int baseNode = ( ((i + j)%(2*nTreesEval) + k)%nTrees )*nTreesNodes;
749+
int currentNode = baseNode;
750+
// select root node of the tree to evaluate
754751

755-
if (currentId >= nFeatures)
752+
int offset = (j*stride/shrink)*nchannels;
753+
while ( __rf.childs[currentNode] != 0 )
756754
{
757-
int xIndex = offsetX[currentId - nFeatures];
758-
float A = ssFeaturesPtr[offset + xIndex];
759-
760-
int yIndex = offsetY[currentId - nFeatures];
761-
float B = ssFeaturesPtr[offset + yIndex];
762-
763-
currentFeature = A - B;
755+
int currentId = __rf.featureIds[currentNode];
756+
float currentFeature;
757+
758+
if (currentId >= nFeatures)
759+
{
760+
int xIndex = offsetX[currentId - nFeatures];
761+
float A = ssFeaturesPtr[offset + xIndex];
762+
763+
int yIndex = offsetY[currentId - nFeatures];
764+
float B = ssFeaturesPtr[offset + yIndex];
765+
766+
currentFeature = A - B;
767+
}
768+
else
769+
currentFeature = regFeaturesPtr[offset + offsetI[currentId]];
770+
771+
// compare feature to threshold and move left or right accordingly
772+
if (currentFeature < __rf.thresholds[currentNode])
773+
currentNode = baseNode + __rf.childs[currentNode] - 1;
774+
else
775+
currentNode = baseNode + __rf.childs[currentNode];
764776
}
765-
else
766-
currentFeature = regFeaturesPtr[offset + offsetI[currentId]];
767-
768-
// compare feature to threshold and move left or right accordingly
769-
if (currentFeature < __rf.thresholds[currentNode])
770-
currentNode = baseNode + __rf.childs[currentNode] - 1;
771-
else
772-
currentNode = baseNode + __rf.childs[currentNode];
773-
}
774777

775-
indexPtr[j*nTreesEval + k] = currentNode;
778+
indexPtr[j*nTreesEval + k] = currentNode;
779+
}
776780
}
777781
}
782+
#ifdef CV_CXX11
783+
);
784+
#endif
778785

779786
NChannelsMat dstM(dst.size(),
780787
CV_MAKETYPE(DataType<float>::type, outNum));
781788
dstM.setTo(0);
782789

783790
float step = 2.0f * CV_SQR(stride) / CV_SQR(ipSize) / nTreesEval;
784-
#ifdef _OPENMP
785-
#pragma omp parallel for
791+
#ifdef CV_CXX11
792+
parallel_for_(cv::Range(0, height), [&](const cv::Range& range)
786793
#endif
787-
for (int i = 0; i < height; ++i)
788794
{
789-
int *pIndex = indexes.ptr<int>(i);
790-
float *pDst = dstM.ptr<float>(i*stride);
795+
for(int i = range.start; i < range.end; ++i)
796+
{
797+
int *pIndex = indexes.ptr<int>(i);
798+
float *pDst = dstM.ptr<float>(i*stride);
791799

792800
for (int j = 0, k = 0; j < width; ++k, j += !(k %= nTreesEval))
793801
{// for j,k in [0;width)x[0;nTreesEval)
@@ -804,7 +812,11 @@ class StructuredEdgeDetectionImpl : public StructuredEdgeDetection
804812
for (int p = start; p < finish; ++p)
805813
pDst[offset + offsetE[__rf.edgeBins[p]]] += step;
806814
}
815+
}
807816
}
817+
#ifdef CV_CXX11
818+
);
819+
#endif
808820

809821
cv::reduce( dstM.reshape(1, int( dstM.total() ) ), dstM, 2, CV_REDUCE_SUM);
810822
imsmooth( dstM.reshape(1, dst.rows), 1 ).copyTo(dst);

0 commit comments

Comments
 (0)