mirror of
https://github.com/opencv/opencv.git
synced 2026-07-29 15:23:05 +04:00
Merge branch '4.x' into '5.x'
This commit is contained in:
@@ -39,6 +39,7 @@
|
||||
//
|
||||
//M*/
|
||||
#include "precomp.hpp"
|
||||
using namespace cv;
|
||||
|
||||
namespace cv
|
||||
{
|
||||
@@ -2143,35 +2144,6 @@ void cv::polylines(InputOutputArray img, InputArrayOfArrays pts,
|
||||
polylines(img, (const Point**)ptsptr, npts, (int)ncontours, isClosed, color, thickness, lineType, shift);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
using namespace cv;
|
||||
|
||||
static void addChildContour(InputArrayOfArrays contours,
|
||||
size_t ncontours,
|
||||
const Vec4i* hierarchy,
|
||||
int i, std::vector<CvSeq>& seq,
|
||||
std::vector<CvSeqBlock>& block)
|
||||
{
|
||||
for( ; i >= 0; i = hierarchy[i][0] )
|
||||
{
|
||||
Mat ci = contours.getMat(i);
|
||||
cvMakeSeqHeaderForArray(CV_SEQ_POLYGON, sizeof(CvSeq), sizeof(Point),
|
||||
!ci.empty() ? (void*)ci.ptr() : 0, (int)ci.total(),
|
||||
&seq[i], &block[i] );
|
||||
|
||||
int h_next = hierarchy[i][0], h_prev = hierarchy[i][1],
|
||||
v_next = hierarchy[i][2], v_prev = hierarchy[i][3];
|
||||
seq[i].h_next = (0 <= h_next && h_next < (int)ncontours) ? &seq[h_next] : 0;
|
||||
seq[i].h_prev = (0 <= h_prev && h_prev < (int)ncontours) ? &seq[h_prev] : 0;
|
||||
seq[i].v_next = (0 <= v_next && v_next < (int)ncontours) ? &seq[v_next] : 0;
|
||||
seq[i].v_prev = (0 <= v_prev && v_prev < (int)ncontours) ? &seq[v_prev] : 0;
|
||||
|
||||
if( v_next >= 0 )
|
||||
addChildContour(contours, ncontours, hierarchy, v_next, seq, block);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cvDrawContours( void* _img, CvSeq* contour,
|
||||
@@ -2185,83 +2157,99 @@ void cv::drawContours( InputOutputArray _image, InputArrayOfArrays _contours,
|
||||
int maxLevel, Point offset )
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
Mat image = _image.getMat(), hierarchy = _hierarchy.getMat();
|
||||
CvMat _cimage = cvMat(image);
|
||||
|
||||
size_t ncontours = _contours.total();
|
||||
size_t i = 0, first = 0, last = ncontours;
|
||||
std::vector<CvSeq> seq;
|
||||
std::vector<CvSeqBlock> block;
|
||||
|
||||
if( !last )
|
||||
CV_Assert( thickness <= MAX_THICKNESS );
|
||||
const size_t ncontours = _contours.total();
|
||||
if (!ncontours)
|
||||
return;
|
||||
CV_Assert(ncontours <= (size_t)std::numeric_limits<int>::max());
|
||||
if (lineType == cv::LINE_AA && _image.depth() != CV_8U)
|
||||
lineType = 8;
|
||||
Mat image = _image.getMat(), hierarchy = _hierarchy.getMat();
|
||||
|
||||
seq.resize(last);
|
||||
block.resize(last);
|
||||
|
||||
for( i = first; i < last; i++ )
|
||||
seq[i].first = 0;
|
||||
|
||||
if( contourIdx >= 0 )
|
||||
if (thickness >= 0) // contour lines
|
||||
{
|
||||
CV_Assert( 0 <= contourIdx && contourIdx < (int)last );
|
||||
first = contourIdx;
|
||||
last = contourIdx + 1;
|
||||
}
|
||||
|
||||
for( i = first; i < last; i++ )
|
||||
{
|
||||
Mat ci = _contours.getMat((int)i);
|
||||
if( ci.empty() )
|
||||
continue;
|
||||
int npoints = ci.checkVector(2, CV_32S);
|
||||
CV_Assert( npoints > 0 );
|
||||
cvMakeSeqHeaderForArray( CV_SEQ_POLYGON, sizeof(CvSeq), sizeof(Point),
|
||||
ci.ptr(), npoints, &seq[i], &block[i] );
|
||||
}
|
||||
|
||||
if( hierarchy.empty() || maxLevel == 0 )
|
||||
for( i = first; i < last; i++ )
|
||||
double color_buf[4] {};
|
||||
scalarToRawData(color, color_buf, _image.type(), 0 );
|
||||
int i = 0, end = (int)ncontours;
|
||||
if (contourIdx >= 0)
|
||||
{
|
||||
seq[i].h_next = i < last-1 ? &seq[i+1] : 0;
|
||||
seq[i].h_prev = i > first ? &seq[i-1] : 0;
|
||||
i = contourIdx;
|
||||
end = i + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t count = last - first;
|
||||
CV_Assert(hierarchy.total() == ncontours && hierarchy.type() == CV_32SC4 );
|
||||
const Vec4i* h = hierarchy.ptr<Vec4i>();
|
||||
|
||||
if( count == ncontours )
|
||||
for (; i < end; ++i)
|
||||
{
|
||||
for( i = first; i < last; i++ )
|
||||
Mat cnt = _contours.getMat(i);
|
||||
if (cnt.empty())
|
||||
continue;
|
||||
const int npoints = cnt.checkVector(2, CV_32S);
|
||||
CV_Assert(npoints > 0);
|
||||
for (int j = 0; j < npoints; ++j)
|
||||
{
|
||||
int h_next = h[i][0], h_prev = h[i][1],
|
||||
v_next = h[i][2], v_prev = h[i][3];
|
||||
seq[i].h_next = (size_t)h_next < count ? &seq[h_next] : 0;
|
||||
seq[i].h_prev = (size_t)h_prev < count ? &seq[h_prev] : 0;
|
||||
seq[i].v_next = (size_t)v_next < count ? &seq[v_next] : 0;
|
||||
seq[i].v_prev = (size_t)v_prev < count ? &seq[v_prev] : 0;
|
||||
const bool isLastIter = j == npoints - 1;
|
||||
const Point pt1 = cnt.at<Point>(j);
|
||||
const Point pt2 = cnt.at<Point>(isLastIter ? 0 : j + 1);
|
||||
cv::ThickLine(image, pt1 + offset, pt2 + offset, color_buf, thickness, lineType, 2, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else // filled polygons
|
||||
{
|
||||
int i = 0, end = (int)ncontours;
|
||||
if (contourIdx >= 0)
|
||||
{
|
||||
i = contourIdx;
|
||||
end = i + 1;
|
||||
}
|
||||
std::vector<int> indexesToFill;
|
||||
if (hierarchy.empty() || maxLevel == 0)
|
||||
{
|
||||
for (; i != end; ++i)
|
||||
indexesToFill.push_back(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
int child = h[first][2];
|
||||
if( child >= 0 )
|
||||
std::stack<int> indexes;
|
||||
for (; i != end; ++i)
|
||||
{
|
||||
addChildContour(_contours, ncontours, h, child, seq, block);
|
||||
seq[first].v_next = &seq[child];
|
||||
// either all from the top level or a single contour
|
||||
if (hierarchy.at<Vec4i>(i)[3] < 0 || contourIdx >= 0)
|
||||
indexes.push(i);
|
||||
}
|
||||
while (!indexes.empty())
|
||||
{
|
||||
// get current element
|
||||
const int cur = indexes.top();
|
||||
indexes.pop();
|
||||
|
||||
// check current element depth
|
||||
int curLevel = -1;
|
||||
int par = cur;
|
||||
while (par >= 0)
|
||||
{
|
||||
par = hierarchy.at<Vec4i>(par)[3]; // parent
|
||||
++curLevel;
|
||||
}
|
||||
if (curLevel <= maxLevel)
|
||||
{
|
||||
indexesToFill.push_back(cur);
|
||||
}
|
||||
|
||||
int next = hierarchy.at<Vec4i>(cur)[2]; // first child
|
||||
while (next > 0)
|
||||
{
|
||||
indexes.push(next);
|
||||
next = hierarchy.at<Vec4i>(next)[0]; // next sibling
|
||||
}
|
||||
}
|
||||
}
|
||||
std::vector<Mat> contoursToFill;
|
||||
for (const int & idx : indexesToFill)
|
||||
contoursToFill.push_back(_contours.getMat(idx));
|
||||
fillPoly(image, contoursToFill, color, lineType, 0, offset);
|
||||
}
|
||||
|
||||
cvDrawContours( &_cimage, &seq[first], cvScalar(color), cvScalar(color), contourIdx >= 0 ?
|
||||
-maxLevel : maxLevel, thickness, lineType, cvPoint(offset) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const int CodeDeltas[8][2] =
|
||||
{ {1, 0}, {1, -1}, {0, -1}, {-1, -1}, {-1, 0}, {-1, 1}, {0, 1}, {1, 1} };
|
||||
|
||||
|
||||
Reference in New Issue
Block a user