Skip to content

Commit 35f4090

Browse files
committed
Update edge_drawing.cpp
1 parent f5aeecf commit 35f4090

File tree

1 file changed

+36
-164
lines changed

1 file changed

+36
-164
lines changed

modules/ximgproc/src/edge_drawing.cpp

Lines changed: 36 additions & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,7 @@ class EdgeDrawingImpl : public EdgeDrawing
154154
int gradThresh; // gradient threshold
155155
int anchorThresh; // anchor point threshold
156156

157-
158-
static void SplitSegment2Lines(double* x, double* y, int noPixels, int segmentNo, std::vector<EDLineSegment>& lines, int min_line_len = 6, double line_error = 1.0);
159157
std::vector<EDLineSegment> lines;
160-
std::vector<EDLineSegment> invalidLines;
161158
int linesNo;
162159
int min_line_len;
163160
double line_error;
@@ -216,12 +213,11 @@ class EdgeDrawingImpl : public EdgeDrawing
216213
void JoinArcs3();
217214

218215
// circle utility functions
219-
static Circle* addCircle(Circle* circles, int& noCircles, double xc, double yc, double r, double circleFitError, double* x, double* y, int noPixels);
220-
static Circle* addCircle(Circle* circles, int& noCircles, double xc, double yc, double r, double circleFitError, EllipseEquation* pEq, double ellipseFitError, double* x, double* y, int noPixels);
216+
static void addCircle(Circle* circles, int& noCircles, double xc, double yc, double r, double circleFitError, double* x, double* y, int noPixels);
217+
static void addCircle(Circle* circles, int& noCircles, double xc, double yc, double r, double circleFitError, EllipseEquation* pEq, double ellipseFitError, double* x, double* y, int noPixels);
221218
static void sortCircles(Circle* circles, int noCircles);
222219
static bool CircleFit(double* x, double* y, int N, double* pxc, double* pyc, double* pr, double* pe);
223220
static void ComputeCirclePoints(double xc, double yc, double r, double* px, double* py, int* noPoints);
224-
static void sortCircle(Circle* circles, int noCircles);
225221

226222
// ellipse utility functions
227223
static bool EllipseFit(double* x, double* y, int noPoints, EllipseEquation* pResult, int mode = FPF);
@@ -365,7 +361,6 @@ void EdgeDrawingImpl::detectEdges(InputArray src)
365361
anchorNos = 0;
366362
anchorPoints.clear();
367363
lines.clear();
368-
invalidLines.clear();
369364
segmentPoints.clear();
370365
segmentPoints.push_back(vector<Point>()); // create empty vector of points for segments
371366
srcImage = src.getMat();
@@ -1270,8 +1265,12 @@ int EdgeDrawingImpl::RetrieveChainNos(Chain* chains, int root, int chainNos[])
12701265

12711266
void EdgeDrawingImpl::detectLines(OutputArray _lines)
12721267
{
1268+
std::vector<Vec4f> linePoints;
12731269
if (segmentPoints.size() < 1)
1270+
{
1271+
Mat(linePoints).copyTo(_lines);
12741272
return;
1273+
}
12751274

12761275
min_line_len = params.MinLineLength;
12771276
line_error = params.LineFitErrorThreshold;
@@ -1322,16 +1321,14 @@ void EdgeDrawingImpl::detectLines(OutputArray _lines)
13221321
for (int i = 1; i <= size - linesNo; i++)
13231322
lines.pop_back();
13241323

1325-
std::vector<Vec4f> linePoints;
13261324
for (int i = 0; i < linesNo; i++)
13271325
{
13281326
Vec4f line((float)lines[i].sx, (float)lines[i].sy, (float)lines[i].ex, (float)lines[i].ey);
13291327
linePoints.push_back(line);
13301328
}
1331-
1329+
Mat(linePoints).copyTo(_lines);
13321330
delete[] x;
13331331
delete[] y;
1334-
Mat(linePoints).copyTo(_lines);
13351332
}
13361333

13371334
// Computes the minimum line length using the NFA formula given width & height values
@@ -1345,7 +1342,7 @@ int EdgeDrawingImpl::ComputeMinLineLength()
13451342

13461343
double logNT = 2.0 * (log10((double)width) + log10((double)height));
13471344
return (int)round((-logNT / log10(0.125)) * 0.5);
1348-
} //end-ComputeMinLineLength
1345+
}
13491346

13501347
//-----------------------------------------------------------------
13511348
// Given a full segment of pixels, splits the chain to lines
@@ -1434,10 +1431,14 @@ void EdgeDrawingImpl::SplitSegment2Lines(double* x, double* y, int noPixels, int
14341431
index--;
14351432
ComputeClosestPoint(x[index], y[index], lastA, lastB, lastInvert, ex, ey);
14361433

1434+
if ((sx == ex) & (sy == ey))
1435+
break;
1436+
14371437
// Add the line segment to lines
14381438
lines.push_back(EDLineSegment(lastA, lastB, lastInvert, sx, sy, ex, ey, segmentNo, firstPixelIndex + noSkippedPixels, index - noSkippedPixels + 1));
14391439
linesNo++;
14401440
len = index + 1;
1441+
14411442
break;
14421443
}
14431444
}
@@ -1586,9 +1587,7 @@ void EdgeDrawingImpl::ValidateLineSegments()
15861587
}
15871588

15881589
// Check validation by NFA computation (fast due to LUT)
1589-
valid = nfa->checkValidationByNFA(count, aligned);
1590-
if (valid == false)
1591-
valid = ValidateLineSegmentRect(x, y, ls);
1590+
valid = nfa->checkValidationByNFA(count, aligned) || ValidateLineSegmentRect(x, y, ls);
15921591
}
15931592

15941593
if (valid)
@@ -1597,10 +1596,6 @@ void EdgeDrawingImpl::ValidateLineSegments()
15971596
lines[noValidLines] = lines[i];
15981597
noValidLines++;
15991598
}
1600-
else
1601-
{
1602-
invalidLines.push_back(lines[i]);
1603-
}
16041599
}
16051600

16061601
linesNo = noValidLines;
@@ -2295,102 +2290,6 @@ void EdgeDrawingImpl::EnumerateRectPoints(double sx, double sy, double ex, doubl
22952290
*pNoPoints = noPoints;
22962291
}
22972292

2298-
void EdgeDrawingImpl::SplitSegment2Lines(double* x, double* y, int noPixels, int segmentNo, vector<EDLineSegment>& lines, int min_line_len, double line_error)
2299-
{
2300-
// First pixel of the line segment within the segment of points
2301-
int firstPixelIndex = 0;
2302-
2303-
while (noPixels >= min_line_len)
2304-
{
2305-
// Start by fitting a line to MIN_LINE_LEN pixels
2306-
bool valid = false;
2307-
double lastA(0), lastB(0), error;
2308-
int lastInvert(0);
2309-
2310-
while (noPixels >= min_line_len)
2311-
{
2312-
LineFit(x, y, min_line_len, lastA, lastB, error, lastInvert);
2313-
if (error <= 0.5)
2314-
{
2315-
valid = true;
2316-
break;
2317-
}
2318-
2319-
noPixels -= 1; // Go slowly
2320-
x += 1;
2321-
y += 1;
2322-
firstPixelIndex += 1;
2323-
}
2324-
2325-
if (valid == false)
2326-
return;
2327-
2328-
// Now try to extend this line
2329-
int index = min_line_len;
2330-
int len = min_line_len;
2331-
2332-
while (index < noPixels)
2333-
{
2334-
int startIndex = index;
2335-
int lastGoodIndex = index - 1;
2336-
int goodPixelCount = 0;
2337-
int badPixelCount = 0;
2338-
while (index < noPixels)
2339-
{
2340-
double d = ComputeMinDistance(x[index], y[index], lastA, lastB, lastInvert);
2341-
2342-
if (d <= line_error)
2343-
{
2344-
lastGoodIndex = index;
2345-
goodPixelCount++;
2346-
badPixelCount = 0;
2347-
}
2348-
else
2349-
{
2350-
badPixelCount++;
2351-
if (badPixelCount >= 5)
2352-
break;
2353-
}
2354-
index++;
2355-
}
2356-
2357-
if (goodPixelCount >= 2)
2358-
{
2359-
len += lastGoodIndex - startIndex + 1;
2360-
LineFit(x, y, len, lastA, lastB, lastInvert);
2361-
index = lastGoodIndex + 1;
2362-
}
2363-
2364-
if (goodPixelCount < 2 || index >= noPixels)
2365-
{
2366-
// End of a line segment. Compute the end points
2367-
double sx, sy, ex, ey;
2368-
2369-
index = 0;
2370-
while (ComputeMinDistance(x[index], y[index], lastA, lastB, lastInvert) > line_error)
2371-
index++;
2372-
ComputeClosestPoint(x[index], y[index], lastA, lastB, lastInvert, sx, sy);
2373-
int noSkippedPixels = index;
2374-
2375-
index = lastGoodIndex;
2376-
while (ComputeMinDistance(x[index], y[index], lastA, lastB, lastInvert) > line_error)
2377-
index--;
2378-
ComputeClosestPoint(x[index], y[index], lastA, lastB, lastInvert, ex, ey);
2379-
2380-
// Add the line segment to lines
2381-
lines.push_back(EDLineSegment(lastA, lastB, lastInvert, sx, sy, ex, ey, segmentNo, firstPixelIndex + noSkippedPixels, index - noSkippedPixels + 1));
2382-
len = index + 1;
2383-
break;
2384-
}
2385-
}
2386-
2387-
noPixels -= len;
2388-
x += len;
2389-
y += len;
2390-
firstPixelIndex += len;
2391-
}
2392-
}
2393-
23942293
/*--------------------------------------EDPF----------------------------------------*/
23952294

23962295
//----------------------------------------------------------------------------------
@@ -2511,19 +2410,23 @@ double EdgeDrawingImpl::NFA(double prob, int len)
25112410

25122411
void EdgeDrawingImpl::detectEllipses(OutputArray ellipses)
25132412
{
2413+
vector<Vec6d> _ellipses;
25142414
if (segmentPoints.size() < 1)
2415+
{
2416+
Mat(_ellipses).copyTo(ellipses);
25152417
return;
2418+
}
25162419

2517-
vector<Vec6d> _ellipses;
2518-
Circles.clear();
2519-
Ellipses.clear();
2420+
min_line_len = 6;
2421+
Circles.clear();
2422+
Ellipses.clear();
2423+
lines.clear();
25202424
// Arcs & circles to be detected
25212425
// If the end-points of the segment is very close to each other,
25222426
// then directly fit a circle/ellipse instread of line fitting
25232427
noCircles1 = 0;
25242428
circles1 = new Circle[(width + height) * 8];
25252429

2526-
// ----------------------------------- DETECT LINES ---------------------------------
25272430
int bufferSize = 0;
25282431
for (int i = 0; i < (int)segmentPoints.size(); i++)
25292432
bufferSize += (int)segmentPoints[i].size();
@@ -2611,9 +2514,10 @@ void EdgeDrawingImpl::detectEllipses(OutputArray ellipses)
26112514
}
26122515
}
26132516
// Otherwise, split to lines
2614-
SplitSegment2Lines(x, y, noPixels, i, lines);
2517+
SplitSegment2Lines(x, y, noPixels, i);
26152518
}
26162519

2520+
min_line_len = params.MinLineLength;
26172521
segmentStartLines[segmentNos] = (int)lines.size();
26182522

26192523
// ------------------------------- DETECT ARCS ---------------------------------
@@ -3157,7 +3061,6 @@ void EdgeDrawingImpl::DetectArcs()
31573061
if ((coverage >= FULL_CIRCLE_RATIO && circleFitError <= LONG_ARC_ERROR))
31583062
{
31593063
addCircle(circles1, noCircles1, XC, YC, R, Error, x, y, noPixels);
3160-
31613064
}
31623065
else
31633066
{
@@ -3173,7 +3076,6 @@ void EdgeDrawingImpl::DetectArcs()
31733076
y += noPixels;
31743077

31753078
firstLine = curLine;
3176-
info[curLine].taken = false; // may reuse the last line?
31773079
}
31783080
firstLine = lastLine;
31793081
}
@@ -3187,15 +3089,10 @@ void EdgeDrawingImpl::DetectArcs()
31873089
void EdgeDrawingImpl::ValidateCircles(bool validate)
31883090
{
31893091
precision = CV_PI / 16; // Alignment precision
3190-
double max = width;
3191-
if (height > max)
3192-
max = height;
3193-
double min = width;
3194-
if (height < min)
3195-
min = height;
31963092

3197-
double* px = new double[8 * (width + height)];
3198-
double* py = new double[8 * (width + height)];
3093+
int points_buffer_size = 8 * (width + height);
3094+
double *px = new double[points_buffer_size];
3095+
double *py = new double[points_buffer_size];
31993096

32003097
if (nfa->LUTSize == 1 && params.NFAValidation)
32013098
{
@@ -3223,14 +3120,16 @@ void EdgeDrawingImpl::ValidateCircles(bool validate)
32233120

32243121
validateAgain = false;
32253122

3226-
int noPoints = 0;
3123+
int noPoints = (int)(computeEllipsePerimeter(&circle->eq));
32273124

3228-
if (circle->isEllipse)
3125+
if (noPoints > points_buffer_size)
32293126
{
3230-
noPoints = std::min(static_cast<int>(computeEllipsePerimeter(&circle->eq)), 8 * (width + height));
3127+
i++;
3128+
continue;
3129+
}
32313130

3232-
if (noPoints % 2)
3233-
noPoints--;
3131+
if (circle->isEllipse)
3132+
{
32343133
ComputeEllipsePoints(circle->eq.coeff, px, py, noPoints);
32353134
}
32363135
else
@@ -3451,7 +3350,7 @@ void EdgeDrawingImpl::ValidateCircles(bool validate)
34513350
void EdgeDrawingImpl::JoinCircles()
34523351
{
34533352
// Sort the circles wrt their radius
3454-
sortCircle(circles2, noCircles2);
3353+
sortCircles(circles2, noCircles2);
34553354

34563355
noCircles = noCircles2;
34573356
Circle* circles = circles2;
@@ -4449,7 +4348,7 @@ void EdgeDrawingImpl::JoinArcs3()
44494348
delete[] candidateArcs;
44504349
}
44514350

4452-
Circle* EdgeDrawingImpl::addCircle(Circle* circles, int& noCircles, double xc, double yc, double r, double circleFitError, double* x, double* y, int noPixels)
4351+
void EdgeDrawingImpl::addCircle(Circle* circles, int& noCircles, double xc, double yc, double r, double circleFitError, double* x, double* y, int noPixels)
44534352
{
44544353
circles[noCircles].xc = xc;
44554354
circles[noCircles].yc = yc;
@@ -4464,11 +4363,9 @@ Circle* EdgeDrawingImpl::addCircle(Circle* circles, int& noCircles, double xc, d
44644363
circles[noCircles].isEllipse = false;
44654364

44664365
noCircles++;
4467-
4468-
return &circles[noCircles - 1];
44694366
}
44704367

4471-
Circle* EdgeDrawingImpl::addCircle(Circle* circles, int& noCircles, double xc, double yc, double r, double circleFitError, EllipseEquation* pEq, double ellipseFitError, double* x, double* y, int noPixels)
4368+
void EdgeDrawingImpl::addCircle(Circle* circles, int& noCircles, double xc, double yc, double r, double circleFitError, EllipseEquation* pEq, double ellipseFitError, double* x, double* y, int noPixels)
44724369
{
44734370
circles[noCircles].xc = xc;
44744371
circles[noCircles].yc = yc;
@@ -4485,8 +4382,6 @@ Circle* EdgeDrawingImpl::addCircle(Circle* circles, int& noCircles, double xc, d
44854382
circles[noCircles].isEllipse = true;
44864383

44874384
noCircles++;
4488-
4489-
return &circles[noCircles - 1];
44904385
}
44914386

44924387
void EdgeDrawingImpl::sortCircles(Circle* circles, int noCircles)
@@ -4862,12 +4757,9 @@ double EdgeDrawingImpl::ComputeEllipseCenterAndAxisLengths(EllipseEquation* eq,
48624757
// ---------------------------------------------------------------------------
48634758
// Given an ellipse equation, computes "noPoints" many consecutive points
48644759
// on the ellipse periferi. These points can be used to draw the ellipse
4865-
// noPoints must be an even number.
48664760
//
48674761
void EdgeDrawingImpl::ComputeEllipsePoints(double* pvec, double* px, double* py, int noPoints)
48684762
{
4869-
if (noPoints % 2)
4870-
noPoints--;
48714763
int npts = noPoints / 2;
48724764

48734765
double** u = AllocateMatrix(3, npts + 1);
@@ -5423,26 +5315,6 @@ void EdgeDrawingImpl::ComputeCirclePoints(double xc, double yc, double r, double
54235315
*noPoints = count;
54245316
}
54255317

5426-
void EdgeDrawingImpl::sortCircle(Circle* circles, int noCircles)
5427-
{
5428-
for (int i = 0; i < noCircles - 1; i++)
5429-
{
5430-
int max = i;
5431-
for (int j = i + 1; j < noCircles; j++)
5432-
{
5433-
if (circles[j].r > circles[max].r)
5434-
max = j;
5435-
}
5436-
5437-
if (max != i)
5438-
{
5439-
Circle t = circles[i];
5440-
circles[i] = circles[max];
5441-
circles[max] = t;
5442-
}
5443-
}
5444-
}
5445-
54465318
bool EdgeDrawingImpl::EllipseFit(double* x, double* y, int noPoints, EllipseEquation* pResult, int mode)
54475319
{
54485320
double** D = AllocateMatrix(noPoints + 1, 7);

0 commit comments

Comments
 (0)