@@ -154,10 +154,7 @@ class EdgeDrawingImpl : public EdgeDrawing
154
154
int gradThresh; // gradient threshold
155
155
int anchorThresh; // anchor point threshold
156
156
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 );
159
157
std::vector<EDLineSegment> lines;
160
- std::vector<EDLineSegment> invalidLines;
161
158
int linesNo;
162
159
int min_line_len;
163
160
double line_error;
@@ -216,12 +213,11 @@ class EdgeDrawingImpl : public EdgeDrawing
216
213
void JoinArcs3 ();
217
214
218
215
// 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);
221
218
static void sortCircles (Circle* circles, int noCircles);
222
219
static bool CircleFit (double * x, double * y, int N, double * pxc, double * pyc, double * pr, double * pe);
223
220
static void ComputeCirclePoints (double xc, double yc, double r, double * px, double * py, int * noPoints);
224
- static void sortCircle (Circle* circles, int noCircles);
225
221
226
222
// ellipse utility functions
227
223
static bool EllipseFit (double * x, double * y, int noPoints, EllipseEquation* pResult, int mode = FPF);
@@ -365,7 +361,6 @@ void EdgeDrawingImpl::detectEdges(InputArray src)
365
361
anchorNos = 0 ;
366
362
anchorPoints.clear ();
367
363
lines.clear ();
368
- invalidLines.clear ();
369
364
segmentPoints.clear ();
370
365
segmentPoints.push_back (vector<Point >()); // create empty vector of points for segments
371
366
srcImage = src.getMat ();
@@ -1270,8 +1265,12 @@ int EdgeDrawingImpl::RetrieveChainNos(Chain* chains, int root, int chainNos[])
1270
1265
1271
1266
void EdgeDrawingImpl::detectLines (OutputArray _lines)
1272
1267
{
1268
+ std::vector<Vec4f> linePoints;
1273
1269
if (segmentPoints.size () < 1 )
1270
+ {
1271
+ Mat (linePoints).copyTo (_lines);
1274
1272
return ;
1273
+ }
1275
1274
1276
1275
min_line_len = params.MinLineLength ;
1277
1276
line_error = params.LineFitErrorThreshold ;
@@ -1322,16 +1321,14 @@ void EdgeDrawingImpl::detectLines(OutputArray _lines)
1322
1321
for (int i = 1 ; i <= size - linesNo; i++)
1323
1322
lines.pop_back ();
1324
1323
1325
- std::vector<Vec4f> linePoints;
1326
1324
for (int i = 0 ; i < linesNo; i++)
1327
1325
{
1328
1326
Vec4f line ((float )lines[i].sx , (float )lines[i].sy , (float )lines[i].ex , (float )lines[i].ey );
1329
1327
linePoints.push_back (line);
1330
1328
}
1331
-
1329
+ Mat (linePoints). copyTo (_lines);
1332
1330
delete[] x;
1333
1331
delete[] y;
1334
- Mat (linePoints).copyTo (_lines);
1335
1332
}
1336
1333
1337
1334
// Computes the minimum line length using the NFA formula given width & height values
@@ -1345,7 +1342,7 @@ int EdgeDrawingImpl::ComputeMinLineLength()
1345
1342
1346
1343
double logNT = 2.0 * (log10 ((double )width) + log10 ((double )height));
1347
1344
return (int )round ((-logNT / log10 (0.125 )) * 0.5 );
1348
- } // end-ComputeMinLineLength
1345
+ }
1349
1346
1350
1347
// -----------------------------------------------------------------
1351
1348
// 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
1434
1431
index --;
1435
1432
ComputeClosestPoint (x[index ], y[index ], lastA, lastB, lastInvert, ex, ey);
1436
1433
1434
+ if ((sx == ex) & (sy == ey))
1435
+ break ;
1436
+
1437
1437
// Add the line segment to lines
1438
1438
lines.push_back (EDLineSegment (lastA, lastB, lastInvert, sx, sy, ex, ey, segmentNo, firstPixelIndex + noSkippedPixels, index - noSkippedPixels + 1 ));
1439
1439
linesNo++;
1440
1440
len = index + 1 ;
1441
+
1441
1442
break ;
1442
1443
}
1443
1444
}
@@ -1586,9 +1587,7 @@ void EdgeDrawingImpl::ValidateLineSegments()
1586
1587
}
1587
1588
1588
1589
// 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);
1592
1591
}
1593
1592
1594
1593
if (valid)
@@ -1597,10 +1596,6 @@ void EdgeDrawingImpl::ValidateLineSegments()
1597
1596
lines[noValidLines] = lines[i];
1598
1597
noValidLines++;
1599
1598
}
1600
- else
1601
- {
1602
- invalidLines.push_back (lines[i]);
1603
- }
1604
1599
}
1605
1600
1606
1601
linesNo = noValidLines;
@@ -2295,102 +2290,6 @@ void EdgeDrawingImpl::EnumerateRectPoints(double sx, double sy, double ex, doubl
2295
2290
*pNoPoints = noPoints;
2296
2291
}
2297
2292
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
-
2394
2293
/* --------------------------------------EDPF----------------------------------------*/
2395
2294
2396
2295
// ----------------------------------------------------------------------------------
@@ -2511,19 +2410,23 @@ double EdgeDrawingImpl::NFA(double prob, int len)
2511
2410
2512
2411
void EdgeDrawingImpl::detectEllipses (OutputArray ellipses)
2513
2412
{
2413
+ vector<Vec6d> _ellipses;
2514
2414
if (segmentPoints.size () < 1 )
2415
+ {
2416
+ Mat (_ellipses).copyTo (ellipses);
2515
2417
return ;
2418
+ }
2516
2419
2517
- vector<Vec6d> _ellipses;
2518
- Circles.clear ();
2519
- Ellipses.clear ();
2420
+ min_line_len = 6 ;
2421
+ Circles.clear ();
2422
+ Ellipses.clear ();
2423
+ lines.clear ();
2520
2424
// Arcs & circles to be detected
2521
2425
// If the end-points of the segment is very close to each other,
2522
2426
// then directly fit a circle/ellipse instread of line fitting
2523
2427
noCircles1 = 0 ;
2524
2428
circles1 = new Circle[(width + height) * 8 ];
2525
2429
2526
- // ----------------------------------- DETECT LINES ---------------------------------
2527
2430
int bufferSize = 0 ;
2528
2431
for (int i = 0 ; i < (int )segmentPoints.size (); i++)
2529
2432
bufferSize += (int )segmentPoints[i].size ();
@@ -2611,9 +2514,10 @@ void EdgeDrawingImpl::detectEllipses(OutputArray ellipses)
2611
2514
}
2612
2515
}
2613
2516
// Otherwise, split to lines
2614
- SplitSegment2Lines (x, y, noPixels, i, lines );
2517
+ SplitSegment2Lines (x, y, noPixels, i);
2615
2518
}
2616
2519
2520
+ min_line_len = params.MinLineLength ;
2617
2521
segmentStartLines[segmentNos] = (int )lines.size ();
2618
2522
2619
2523
// ------------------------------- DETECT ARCS ---------------------------------
@@ -3157,7 +3061,6 @@ void EdgeDrawingImpl::DetectArcs()
3157
3061
if ((coverage >= FULL_CIRCLE_RATIO && circleFitError <= LONG_ARC_ERROR))
3158
3062
{
3159
3063
addCircle (circles1, noCircles1, XC, YC, R, Error, x, y, noPixels);
3160
-
3161
3064
}
3162
3065
else
3163
3066
{
@@ -3173,7 +3076,6 @@ void EdgeDrawingImpl::DetectArcs()
3173
3076
y += noPixels;
3174
3077
3175
3078
firstLine = curLine;
3176
- info[curLine].taken = false ; // may reuse the last line?
3177
3079
}
3178
3080
firstLine = lastLine;
3179
3081
}
@@ -3187,15 +3089,10 @@ void EdgeDrawingImpl::DetectArcs()
3187
3089
void EdgeDrawingImpl::ValidateCircles (bool validate)
3188
3090
{
3189
3091
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;
3196
3092
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];
3199
3096
3200
3097
if (nfa->LUTSize == 1 && params.NFAValidation )
3201
3098
{
@@ -3223,14 +3120,16 @@ void EdgeDrawingImpl::ValidateCircles(bool validate)
3223
3120
3224
3121
validateAgain = false ;
3225
3122
3226
- int noPoints = 0 ;
3123
+ int noPoints = ( int )( computeEllipsePerimeter (&circle-> eq )) ;
3227
3124
3228
- if (circle-> isEllipse )
3125
+ if (noPoints > points_buffer_size )
3229
3126
{
3230
- noPoints = std::min (static_cast <int >(computeEllipsePerimeter (&circle->eq )), 8 * (width + height));
3127
+ i++;
3128
+ continue ;
3129
+ }
3231
3130
3232
- if (noPoints % 2 )
3233
- noPoints--;
3131
+ if (circle-> isEllipse )
3132
+ {
3234
3133
ComputeEllipsePoints (circle->eq .coeff , px, py, noPoints);
3235
3134
}
3236
3135
else
@@ -3451,7 +3350,7 @@ void EdgeDrawingImpl::ValidateCircles(bool validate)
3451
3350
void EdgeDrawingImpl::JoinCircles ()
3452
3351
{
3453
3352
// Sort the circles wrt their radius
3454
- sortCircle (circles2, noCircles2);
3353
+ sortCircles (circles2, noCircles2);
3455
3354
3456
3355
noCircles = noCircles2;
3457
3356
Circle* circles = circles2;
@@ -4449,7 +4348,7 @@ void EdgeDrawingImpl::JoinArcs3()
4449
4348
delete[] candidateArcs;
4450
4349
}
4451
4350
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)
4453
4352
{
4454
4353
circles[noCircles].xc = xc;
4455
4354
circles[noCircles].yc = yc;
@@ -4464,11 +4363,9 @@ Circle* EdgeDrawingImpl::addCircle(Circle* circles, int& noCircles, double xc, d
4464
4363
circles[noCircles].isEllipse = false ;
4465
4364
4466
4365
noCircles++;
4467
-
4468
- return &circles[noCircles - 1 ];
4469
4366
}
4470
4367
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)
4472
4369
{
4473
4370
circles[noCircles].xc = xc;
4474
4371
circles[noCircles].yc = yc;
@@ -4485,8 +4382,6 @@ Circle* EdgeDrawingImpl::addCircle(Circle* circles, int& noCircles, double xc, d
4485
4382
circles[noCircles].isEllipse = true ;
4486
4383
4487
4384
noCircles++;
4488
-
4489
- return &circles[noCircles - 1 ];
4490
4385
}
4491
4386
4492
4387
void EdgeDrawingImpl::sortCircles (Circle* circles, int noCircles)
@@ -4862,12 +4757,9 @@ double EdgeDrawingImpl::ComputeEllipseCenterAndAxisLengths(EllipseEquation* eq,
4862
4757
// ---------------------------------------------------------------------------
4863
4758
// Given an ellipse equation, computes "noPoints" many consecutive points
4864
4759
// on the ellipse periferi. These points can be used to draw the ellipse
4865
- // noPoints must be an even number.
4866
4760
//
4867
4761
void EdgeDrawingImpl::ComputeEllipsePoints (double * pvec, double * px, double * py, int noPoints)
4868
4762
{
4869
- if (noPoints % 2 )
4870
- noPoints--;
4871
4763
int npts = noPoints / 2 ;
4872
4764
4873
4765
double ** u = AllocateMatrix (3 , npts + 1 );
@@ -5423,26 +5315,6 @@ void EdgeDrawingImpl::ComputeCirclePoints(double xc, double yc, double r, double
5423
5315
*noPoints = count;
5424
5316
}
5425
5317
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
-
5446
5318
bool EdgeDrawingImpl::EllipseFit (double * x, double * y, int noPoints, EllipseEquation* pResult, int mode)
5447
5319
{
5448
5320
double ** D = AllocateMatrix (noPoints + 1 , 7 );
0 commit comments